diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a1673fd5e..d70d02d79 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,6 +43,26 @@ jobs: cmake --install . tar -zcvf build.tar.gz -Cinstall . + - name: Upload generated docs + uses: actions/upload-artifact@v7 + with: + name: generated-docs + path: | + doc/Commands.md + doc/Variables.md + doc/CommandLine.md + doc/Messages.md + if-no-files-found: error + retention-days: 1 + + - name: Check command help + run: | + test -s doc/Commands.md + test -s doc/Variables.md + test -s doc/CommandLine.md + test -s doc/Messages.md + ./build/sta -no_splash -no_init -exit etc/CheckCmdHelp.tcl + - name: Test run: | cd test @@ -106,3 +126,34 @@ jobs: name: result-macos path: | test/results/* + + docs: + needs: linux-ubuntu + if: ${{ !cancelled() && needs.linux-ubuntu.result != 'skipped' }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v7 + + - name: Download generated docs + uses: actions/download-artifact@v8 + with: + name: generated-docs + path: doc + + - name: Check generated docs + run: | + test -s doc/Commands.md + test -s doc/Variables.md + test -s doc/CommandLine.md + + - name: Set up Python + uses: actions/setup-python@v7 + with: + python-version: "3.12" + + - name: Install MkDocs + run: pip install -r doc/requirements.txt + + - name: Build docs + run: mkdocs build --strict diff --git a/.gitignore b/.gitignore index 1c3c92aab..e8f422336 100644 --- a/.gitignore +++ b/.gitignore @@ -19,14 +19,21 @@ pvt # iverilog turd examples/gcd_tb -doc/._Sta.docx +# Generated by building sta (etc/WriteCmdDocs.tcl, etc/FindMessages.tcl). +doc/Commands.md +doc/Variables.md +doc/CommandLine.md +doc/Messages.md test/results */test/results + # ngspice turd test/b3v3_1check.log -doc/messages.txt +# MkDocs +site/ +.venv/ # clangd turds .cache/ diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 000000000..621f14fe0 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,30 @@ +version: 2 + +build: + os: ubuntu-24.04 + tools: + python: "3.12" + apt_packages: + - bison + - build-essential + - cmake + - flex + - libeigen3-dev + - libfl-dev + - ninja-build + - pkg-config + - swig + - tcl-dev + - wget + - zlib1g-dev + jobs: + # Commands.md / Variables.md / CommandLine.md come from a live sta binary. + pre_build: + - bash etc/build_sta.sh + +mkdocs: + configuration: mkdocs.yml + +python: + install: + - requirements: doc/requirements.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index f8ddda840..c753a7268 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -685,7 +685,14 @@ add_custom_target(sta_tags add_custom_command( TARGET OpenSTA POST_BUILD - COMMAND ${STA_HOME}/etc/FindMessages.tcl > ${STA_HOME}/doc/messages.txt || true + COMMAND ${STA_HOME}/etc/FindMessages.tcl ${STA_HOME}/doc/Messages.md + WORKING_DIRECTORY ${STA_HOME} +) + +add_custom_command( + TARGET sta + POST_BUILD + COMMAND $ -no_splash -no_init -exit ${STA_HOME}/etc/WriteCmdDocs.tcl WORKING_DIRECTORY ${STA_HOME} ) diff --git a/README.md b/README.md index b1eb59bc4..63e5afb85 100644 --- a/README.md +++ b/README.md @@ -50,9 +50,15 @@ 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 command documentation. -See doc/ChangeLog.txt for changes to commands. -See doc/StaApi.txt for timing engine API documentation. +Documentation is published at +https://opensta.readthedocs.io/en/latest/ + +See the [command reference](https://opensta.readthedocs.io/en/latest/Commands/) +for command documentation. That page is generated from the live `sta` +help registry when the binary is built (CMake and Read the Docs run +`etc/WriteCmdDocs.tcl`). +See [doc/ChangeLog.md](doc/ChangeLog.md) for changes to commands. +See [doc/StaApi.md](doc/StaApi.md) for timing engine API documentation. OpenSTA is dual licensed. It is released under GPL v3 as OpenSTA and is also licensed for commerical applications by Parallax Software without @@ -273,10 +279,13 @@ tarfile. ## Contributions -Contributors must sign the Contributor License Agreement (doc/CLA.txt) +Contributors must sign the Contributor License Agreement +([doc/CLA.txt](doc/CLA.txt)) when submitting pull requests. -All contributors should read doc/CodingGuidelines.txt for notes on +All contributors should read +[doc/CodingGuidelines.md](doc/CodingGuidelines.md) +for notes on making code that adheres to the existing naming and formatting style. Contributions that claim 4% performance improvements in OpenROAD flow diff --git a/app/Main.cc b/app/Main.cc index 90405a1a2..564ce6293 100644 --- a/app/Main.cc +++ b/app/Main.cc @@ -202,7 +202,9 @@ static void showUsage(std::string_view prog, std::string_view init_filename) { - sta::print(stdout, "Usage: {} [-help] [-version] [-no_init] [-exit] cmd_file\n", + sta::print(stdout, + "Usage: {} [-help] [-version] [-no_init] [-no_splash] " + "[-threads count|max] [-exit] cmd_file\n", prog); sta::print(stdout, " -help show help and exit\n"); sta::print(stdout, " -version show version and exit\n"); diff --git a/dcalc/DelayCalc.tcl b/dcalc/DelayCalc.tcl index 3658c2198..850773814 100644 --- a/dcalc/DelayCalc.tcl +++ b/dcalc/DelayCalc.tcl @@ -25,7 +25,13 @@ namespace eval sta { define_cmd_args "report_dcalc" \ - {[-from from_pin] [-to to_pin] [-scene scene] [-min] [-max] [-digits digits]} + {[-from from_pin] [-to to_pin] [-scene scene] [-min] [-max] [-digits digits]} \ + -help {The `report_dcalc` command shows how the delays between instance pins are calculated. It is useful for debugging problems with delay calculation.} \ + -arg_help { + -from {Report delay calculations for timing arcs from instance input pin from_pin.} + -to {Report delay calculations for timing arcs to instance output pin to_pin.} + -scene {Report delay calculations for this scene. Required if more than one scene is defined.} + } proc_redirect report_dcalc { report_dcalc_cmd "report_dcalc" $args "-digits" @@ -139,7 +145,16 @@ proc set_delay_calculator { alg } { define_cmd_args "set_assigned_delay" \ {-cell|-net [-rise] [-fall] [-scene scene] [-min] [-max]\ - [-from from_pins] [-to to_pins] delay} + [-from from_pins] [-to to_pins] delay} \ + -help {The `set_assigned_delay` command is used to annotate the delays between two pins on an instance or net. The annotated delay overrides the calculated delay. This command is an interactive way to back-annotate delays like an SDF file.} \ + -arg_help { + -cell {Annotate the delays between two pins on an instance.} + -net {Annotate the delays between two pins on a net.} + -scene {The name of a scene. The `-scene` keyword is required if more than one scene is defined.} + -from {A list of pins.} + -to {A list of pins.} + delay {The delay between from_pins and to_pins.} + } # Change the delay for timing arcs between from_pins and to_pins matching # on cell (instance) or net. @@ -239,7 +254,18 @@ define_cmd_args "set_assigned_check" \ {-setup|-hold|-recovery|-removal [-rise] [-fall]\ [-scene scene] [-min] [-max]\ [-from from_pins] [-to to_pins] [-clock rise|fall]\ - [-cond sdf_cond] check_value} + [-cond sdf_cond] check_value} \ + -help {The `set_assigned_check` command is used to annotate the timing checks between two pins on an instance. The annotated delay overrides the calculated delay. This command is an interactive way to back-annotate delays like an SDF file.} \ + -arg_help { + -recovery {Annotate recovery timing checks.} + -removal {Annotate removal timing checks.} + -scene {The name of a scene. The `-scene` keyword is required if more than one scene is defined.} + -from {A list of pins for the clock.} + -to {A list of pins for the data.} + -clock {`rise|fall`: The timing check clock pin transition.} + -cond {SDF condition string for the annotated check.} + margin {The timing check margin.} + } proc set_assigned_check { args } { parse_key_args "set_assigned_check" args \ @@ -348,7 +374,13 @@ proc set_assigned_check2 { from_vertex from_rf to_vertex to_rf \ ################################################################a define_cmd_args "set_assigned_transition" \ - {[-rise] [-fall] [-scene scene] [-min] [-max] slew pins} + {[-rise] [-fall] [-scene scene] [-min] [-max] slew pins} \ + -help {The `set_assigned_transition` command is used to annotate the transition time (slew) of a pin. The annotated transition time overrides the calculated transition time.} \ + -arg_help { + -scene {Annotate delays for scene.} + slew {The pin transition time.} + pin_list {A list of pins.} + } # Change the slew on a list of ports. proc set_assigned_transition { args } { @@ -381,7 +413,13 @@ proc set_assigned_transition { args } { ################################################################ define_cmd_args "report_slews" {[-scenes scenes] [-digits digits]\ - [-report_variance] pin} + [-report_variance] pin} \ + -help {Report the slews at a pin.} \ + -arg_help { + -scenes {Report slews for these scenes. The default is all scenes.} + -report_variance {Report SSTA distribution parameters.} + pin {A pin or port.} + } proc report_slews { args } { global sta_report_default_digits diff --git a/doc/ApiChanges.md b/doc/ApiChanges.md new file mode 100644 index 000000000..0c2468584 --- /dev/null +++ b/doc/ApiChanges.md @@ -0,0 +1,234 @@ +# STA API changes + +This file summarizes STA API changes for each release. + +## 2026/06/22 + +`Liberty::hasSequentials` has been renamed `isSequential`. + +## Release 3.1.0 2026/03/25 + +OpenSTA now uses `std::string` and `std::string_view` instead of +`const char *`. Lookup functions such as `Network::findPin` use +`std::string_view` that accept a `const char *`, `std::string`, or +`std::string_view` caller argument. + +## 2026/03/19 + +`LibertyCell::footprint()` returns `const std::string&` instead of +`const char *`. +`LibertyCell::userFunctionClass` returns `const std::string&` instead of +`const char *`. + +The `Sdc`, `Liberty`, `ConcreteLibrary`, `ConcreteNetwork` classes have +been updated to use `std::string` and `std::string_view` instead of +`const char *`. `std::string_view` is used when the lifetime of the +string argument is only while the function is called. `std::string` is +used when the string value outlives the function call because it is +stored in data structures. + +The `LibertyPort` functions `relatedGroundPin` and `relatedPowerPin` +are renamed to `relatedGroundPort` and `relatedPowerPort` and return +`LibertyPort`s instead of strings. + +## 2026/03/12 + +The `Report` class used for reporting and error messages now uses +`std::format` instead of `printf`. + +`sta::format` is a wrapper for `std::format` that will compile on gcc8, +which centos7 uses and does not support `std::format`. + +`stdstrPrint`, `stringPrint`, `stringAppend` have been removed. Use +`sta::format`. + +`reportLineString` is now `reportLine`. + +## Release 3.0.0 2026/01/03 + +OpenSTA now requires C++ 20. + +`Corner` replaced by `Scene`: + +- `mode()` +- `parasitics(min_max)` + +`DcalcAnalysisPt` replaced by `scene`/`min_max`. +`PathAnalysisPt` replaced by `scene`/`min_max`. + +`StaState::sdc_` moved to `Mode`. +`StaState::sim_` moved to `Mode`. +`StaState::clk_network_` moved to `Mode`. +`StaState::parasitics_` moved to `Scene`. + +`Sta::findPathEnds` `group_paths` arg has been changed from +`PathGroupNameSet*` to `StringSeq&`. + +`Sta::isClock` has been removed. Use `mode->clkNetwork()->isClock` +instead. + +| Old | New | +| --- | --- | +| `Sta::vertexSlew` | `slew` | +| `Sta::vertexSlack` | `slack` | +| `Sta::vertexSlacks` | `slacks` | +| `Sta::vertexArrival` | `arrival` | +| `Sta::vertexRequired` | `required` | +| `Sta::pinSlack` | `slack` | +| `Sta::pinArrival` | `arrival` | + +`FuncExpr::Operator::op_*` renamed to `FuncExpr::Op::*`. +`FuncExprPortIterator` has been removed. Use `FuncExpr::ports()`. + +`Sdc::clocks()` now returns `ClockSeq&`. +`Sdc::clks()` has been removed. + +The `Vector`/`Map`/`Set`/`UnorderedSet` classes have been removed and +replaced by the std containers. The member functions are now templated +functions found in `ContainerHelpers.hh`. + +The `Graph` `slew_rf_count` option is no longer supported. + +## Release 2.6.2 2025/03/30 + +The following functions have been renamed to `to_string` and return +`std::string` instead of `const char *`: + +``` +Vertex::name +FuncExpr::asString +TimingRole::name +MinMax::asString +MinMaxAll::asString +RiseFall::asString +RiseFallBoth::asString +Transition::asString +Tag::asString +timingSenseString +``` + +The following classes now return const objects: `MinMax`, `MinMaxAll`, +`RiseFall`, `RiseFallBoth`, `Transition`, `TimingRole`. + +Liberty `PgPort`s are now `LibertyPort`s with additional member +functions for Liberty `pg_pin`s. + +The `write_verilog` command always sorts the Verilog file instances. +The `-sort` argument is ignored. + +## Release 2.6.1 2025/03/?? + +The following classes have been replaced by the class `Path`: + +- `PathEnumed` +- `PathPrev` +- `PathRef` +- `PathVertex` +- `PathVertexPtr` +- `PathVertexRep` + +The `PathExpanded::prevArc` function has been removed. Use +`Path::prevArc` instead. + +## Release 2.4.0 2023/01/19 + +The Network API and associated containers now `const` the network class +objects. The Network API now requires network objects to have an `id` +function that returns an `ObjectId` (`unsigned int`) that is unique to +the object among objects of the same type. + +```cpp +virtual ObjectId id(const Instance *instance) const = 0; +``` + +Object IDs are used for comparing and hashing network objects. If +network IDs are not available in the host application database, object +pointers can be cast to `intptr_t`. Using pointers as object IDs can +result in memory layout dependent results that are inconsistent from +run to run or across host systems. + +Many `Network` and `Sta` class functions now return collections rather +than pointers to temporary collections that the caller would have to +delete. + +## Release 2.3.1 2022/06/12 + +`LibertyCellTimingArcSetIterator` has been removed. Use range iteration +as shown below: + +```cpp +for (TimingArcSet *arc_set : cell->timingArcSets()) +for (TimingArcSet *arc_set : cell->timingArcSets(from, to)) +``` + +`TimingArcSetArcIterator` has been removed. Use range iteration as +shown below: + +```cpp +for (TimingArc *arc : arc_set->arcs()) +``` + +`LibertyCellSequentialIterator` has been removed. + +```cpp +for (Sequential *seq : cell->sequentials()) +``` + +## Release 2.1.1 2020/12/13 + +`Report::error` and `Report::warn` functions now take a unique message +ID as a first argument. `InternalError` has been renamed +`Report::critical`. + +## Release 2.1.0 2020/04/05 + +All public header files have been moved to `include/sta`. + +The following iterators have been removed. Use range iteration on the +returned collection shown next to them instead. + +``` +LibertyCellInternalPowerIterator cell->internalPowers() +LibertyCellLeakagePowerIterator cell->leakagePowers() +``` + +## Release 2.0.18 2020/02/15 + +The following iterator functions are deprecated: + +- `TimingArcSet::timingArcIterator()` +- `Sdc::clockIterator()` + +Use the iterator class constructor instead. This avoids `new`/`delete`s +of the iterators by stack allocating them. For example, instead of: + +```cpp +TimingArcSetArcIterator *arc_iter = arc_set->timingArcIterator(); +while (arc_iter->hasNext()) { + TimingArc *arc = arc_iter->next(); +} +delete arc_iter; +``` + +use the following: + +```cpp +TimingArcSetArcIterator arc_iter(arc_set); +while (arc_iter.hasNext()) { + TimingArc *arc = arc_iter.next(); +} +``` + +`StaException` renamed to `Exception`. + +## Release 2.0.17 2019/11/11 + +`Network::setVertexIndex` renamed to `setVertexId`. +`Network::vertexIndex` renamed to `vertexId`. + +`TransRiseFall` renamed to `RiseFall`. +`TransRiseFallBoth` renamed to `RiseFallBoth`. + +## Release 2.0.0 2018/06/11 + +Initial release. diff --git a/doc/ApiChanges.txt b/doc/ApiChanges.txt deleted file mode 100644 index 0aa3e9f64..000000000 --- a/doc/ApiChanges.txt +++ /dev/null @@ -1,246 +0,0 @@ -# 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 . -# -# 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. - -This file summarizes STA API changes for each release. - -2026/06/22 ----------- - -Liberty::hasSequentials has been renamed isSequential. - -Release 3.1.0 2026/03/25 ------------------------- - -OpenSTA now uses std::string and std::string_view instead of const char *. -Lookup funtions such as Network::findPin use std::string_view that accept -a const char *, std::string, or std::string_view caller argument. - -2026/03/19 ----------- - -LibertyCell::footprint() returns const std::string& instead of const char*. -LibertyCell::userFunctionClass returns const std::string& instead of const char*. - -The Sdc, Liberty, ConcreteLibrary, ConcreteNetwork classes have been updated to -use std::string and std::string_view instead of const char *. std::string_view -is used when the lifetime of the string argument is only while the function is -called. std::string is used when the string value outlives the function call -because it is stored in data structures. - -The LibertyPort functions - relatedGroundPin - relatedPowerPin -are renamed to - relatedGroundPort - relatedPowerPort -and return LibertyPort's instead of strings. - -2026/03/12 ----------- - -The Report class used for reporting and error messages now uses std::format -instead of printf. - -sta::format is a wrapper for std::format that will compile on gcc8, which -centos7 uses and does not support std::format. - -stdstrPrint, strintPrint, stringAppend have been removed. Use sta::format. - -reportLineString is now reportLine - -Release 3.0.0 2026/01/03 ------------------------- - -OpenSTA now requires c++ 20. - -Corner replaced by Scene - mode() - parasitics(min_max) -DcalcAnalysisPt replaced by scene/min_min -PathAnalysisPt replaced by scene/min_min -StaState::sdc_ moved to Mode -StaState::sim_ moved to Mode -StaState::clk_network__ moved to Mode -StaState::parasitics_ moved to Scene - -Sta::findPathEnds group_paths arg has been changed from PathGroupNameSet* -to StringSeq&. - -Sta::isClock has been removed. Use mode->clkNetwork()->isClock instead. - -Sta::vertexSlew renamed to slew -Sta::vertexSlack renamed to slack -Sta::vertexSlacks renamed to slacks -Sta::vertexArrival renamed to arrival -Sta::vertexRequired renamed to required -Sta::pinSlack renamed to slack -Sta::pinArrival renamed to arrival - -FuncExpr::Operator::op_* renamed to FuncExpr::Op::* -FuncExprPortIterator has been removed. Use FuncExpr::ports(). - -Sdc::clocks() now returns ClockSeq&. -Sdc::clks() has been removed. - -The Vector/Map/Set/UnorderedSet classes have been removed and replaced by -the std containers. The member functions are now templated functions found -in ContainerHelpers.hh. - -The Graph slew_rf_count option is no longer supported. - -Release 2.6.2 2025/03/30 ------------------------- - -The following functions have been renamed to to_string and return std::string -instead of "const char*" - - Vertex::name - FuncExpr::asString - TimingRole::name - MinMax::asString - MinMaxAll::asString - RiseFall::asString - RiseFallBoth::asString - Transition::asString - Tag::asString - timingSenseString - -The following classes now return const objects. - - MinMax - MinMaxAll - RiseFall - RiseFallBoth - Transition - TimingRole - -Liberty PgPorts are now LibertyPorts with additional member functions for -liberty pg_pins. - -The write_verilog command always sorts the verilog file instances. -The -sort argument is ignored. - -Release 2.6.1 2025/03/?? -------------------------- - -The following classes have been replaced by the class Path. - PathEnumed - PathPrev - PathRef - PathVertex - PathVertexPtr - PathVertexRep - -The PathExpanded::prevArc function has been removed. Use Path::prevArc instead. - -Release 2.4.0 2023/01/19 -------------------------- - -The Network API and associated containers now 'const' the network class objects. -The Network API now requires network objects to have and "id" function that -returns an ObjectId (unsigned int) that is unique to the object among objects -of the same type. - - virtual ObjectId id(const Instance *instance) const = 0; - -Object IDs are used for comparing and hashing network objects. -If network Ids are not available in the host application database object pointers -can be cast to intptr_t. Using pointers as object Ids can result in memory layout -dependent results that are inconsistent from run to run or across host systems. - -Many Network and Sta class functions now return collections rather than pointers -to temporary collections that the caller would have to delete. - -Release 2.3.1 2022/06/12 -------------------------- -LibertyCellTimingArcSetIterator has been removed. -Use range iteration as shown below: - for (TimingArcSet *arc_set : cell->timingArcSets()) - for (TimingArcSet *arc_set : cell->timingArcSets(from, to)) - -TimingArcSetArcIterator has been removed. -Use range iteration as shown below: - for (TimingArc *arc : arc_set->arcs()) - -LibertyCellSequentialIterator has been removed. - for (Sequential *seq : cell->sequentials()) - -Release 2.1.1 2020/12/13 -------------------------- -Report::error, Report::warn functions now take a unique message ID as a first argument. -InternalError has been renamed Report::cricical. - -Release 2.1.0 2020/04/05 -------------------------- -All public headers files have been moved to include/sta. - -The following iterators have been removed. -Use range iteration on the returned collection shown next to them instead. - LibertyCellInternalPowerIterator cell->internalPowers() - LibertyCellLeakagePowerIterator cell->leakagePowers() - -Release 2.0.18 2020/02/15 -------------------------- - -The following iterator functions are deprecated: - - TimingArcSet::timingArcIterator() - Sdc::clockIterator() - -Use the iterator class constructor instead. This avoids new/deletes of -the iterators by stack allocating them. For example, -Instead of - - TimingArcSetArcIterator *arc_iter = arc_set->timingArcIterator(); - while (arc_iter->hasNext()) { - TimingArc *arc = arc_iter->next(); - } - delete arc_iter; - -use the following: - - TimingArcSetArcIterator arc_iter(arc_set); - while (arc_iter.hasNext()) { - TimingArc *arc = arc_iter.next(); - } - -StaException renamed to Exception - -Release 2.0.17 2019/11/11 -------------------------- - -Network::setVertexIndex renamed to setVertexId -Network::vertexIndex renamed to vertexId - -TransRiseFall renamed to RiseFall -TransRiseFallBoth renamed to RiseFallBoth - -Release 2.0.0 2018/06/11 -------------------------- - -Initial release. - -# Local Variables: -# mode:text -# End: diff --git a/doc/ChangeLog.md b/doc/ChangeLog.md new file mode 100644 index 000000000..cca9979e0 --- /dev/null +++ b/doc/ChangeLog.md @@ -0,0 +1,592 @@ +# OpenSTA Timing Analyzer Release Notes + +This file summarizes user visible changes for each release. +See [API changes](ApiChanges.md) for changes to the STA API. + +## 2026/08/02 + +The `set_path_margin` command applies a signed slack adjustment to the +capture-clock side of matching timing paths. A positive margin +tightens the path and a negative margin loosens it. + +```tcl +set_path_margin [-setup] [-hold] [-rise] [-fall] + [-from from_list|-rise_from from_list|-fall_from from_list] + [-through through_list|-rise_through through_list|-fall_through through_list] + [-to to_list|-rise_to to_list|-fall_to to_list] + [-comment comment] + margin +``` + +## 2026/07/20 + +The `read_vcd` command supports `-begin_time` / `-end_time` to limit +activity annotation to a VCD time window. + +```tcl +read_vcd [-scope scope] [-mode mode_name] + [-begin_time begin_time] [-end_time end_time] filename +``` + +## 2026/05/01 + +The `write_sdc` command supports a `-mode` argument. + +```tcl +write_sdc [-mode mode] +``` + +## 2026/03/23 + +The `write_path_spice` command `-spice_directory` has been changed to +`-spice_file`, which is a prefix for the spice filenames. Successive +paths are written in files named `_.sp`. + +## Release 3.0.1 2026/03/12 + +Statistical timing (SSTA) with Liberty LVF (Liberty Variation Format) +models is now supported. Statistical timing uses a probability +distribution to represent a delay or slew rather than a single +number. + +Normal and skew normal probability distributions are supported. + +SSTA is enabled with the `sta_pocv_mode` variable. + +```tcl +set sta_pocv_mode scalar|normal|skew_normal +``` + +- `scalar` mode is for non-SSTA analysis +- `normal` mode uses gaussian normal distributions +- `skew_normal` mode is for skew normal LVF moment based distributions + +The target quantile of a delay probability distribution (confidence level) is +set with the `sta_pocv_quantile` variable. + +```tcl +sta_pocv_quantile +``` + +The default value is 3 standard deviations, or sigma. + +Use the `variation` field with `report_checks` or `report_check_types` to see +distribution parameters in timing reports. See [Examples](Examples.md) +for a command file, sample report, and the Liberty timing groups used +for normal and skew-normal LVF. + +The following commands now support a `-report_variance` argument. + +```tcl +report_arrival [-report_variance] +report_required [-report_variance] +report_slack [-report_variance] +report_slews [-report_variance] +report_edges [-report_variance] +``` + +The following commands now support a `-digits` option. + +```tcl +report_edges [-digits digits] +report_slews [-digits digits] +``` + +## 2026/02/24 + +The `define_scene` `-library` argument now takes the library name or a +library filename. If a filename is used, it must be the same as the +filename used to read the library with `read_liberty`. + +## Release 3.0.0 2025/11/26 + +This release adds multi-corner multi-mode (mcmm) support. The SDC +constraints in each mode describe a different operating mode, such as +mission mode or scan mode. + +A "scene" is the combination of a mode and corner. Each scene can have +separate min/max liberty and spef files. + +The basic structure of a multi-corner/multi-mode command file is: + +```tcl +read_liberty +read_verilog +link_design +read_sdc -mode... or set_mode followed by sdc commands +read_spef -name... +define_scene... +report_checks [-scenes] +``` + +This is an example script with 2 corners, 2 modes and 3 scenes. + +```tcl +read_liberty bc.lib +read_liberty wc.lib + +read_verilog design.v +link_design top + +read_sdc -mode run design.sdc +read_sdc -mode scan design_scan.sdc + +read_spef -name bc bc.spef +read_spef -name wc wc.spef + +define_scene bc \ + -mode run \ + -liberty bc \ + -spef bc +define_scene wc \ + -mode run \ + -liberty wc \ + -spef wc +define_scene scan \ + -mode scan \ + -liberty wc \ + -spef wc + +report_checks +report_checks -scenes bc +report_checks -scenes wc +report_checks -scenes scan +``` + +Alternatively, the `set_mode` command can be used to define commands +for each mode at the command level instead of using SDC files. + +```tcl +set_mode run +create_clock -period 10 clock +set_input_delay 0 -clock clock [all_inputs -no_clocks] +set_output_delay 0 -clock clock [all_outputs] + +set_mode scan +create_clock -period 100 scan_clock +set_input_delay 0 -clock scan_clock scan_in +set_output_delay 0 -clock scan_clock scan_out +``` + +The `define_corners` command is supported for compatibility but should +not be used with mcmm flows. Similarly, the `-min`/`-max` arguments to +`read_liberty` and `read_spef` are supported for compatibility but should +not be used with mcmm flows. + +An initial mode and scene named `default` are defined for single mode, +single corner analysis. SDC commands defined interactively and read +with `read_sdc` without a `-mode` argument are defined in the `default` +mode. + +Use the `set_mode` command to define a mode or set the command +interpreter to add following commands to mode `mode_name`. + +```tcl +set_mode mode_name +``` + +If `mode_name` does not exist it is created. When modes are created the +default mode is deleted. + +The `read_sdc` command has a `-mode` argument to assign the commands in the file +to a mode. + +```tcl +read_sdc [-mode mode_name] +``` + +If the mode does not exist it is created. Multiple SDC files can +append commands to a mode by using the `-mode` argument for each +one. If no `-mode` argument is used the commands are added to the +current mode. + +The `define_scene` command defines a scene for a mode (SDC), liberty files +and spef parasitics. + +```tcl +define_scene -mode mode_name + -liberty liberty_files | -liberty_min liberty_min_files -liberty_max liberty_max_files + [-spef spef_file | -spef_min spef_min_file -spef_max spef_max_file] +``` + +Use `get_scenes` to find defined scenes. + +```tcl +get_scenes [-modes mode_names] scene_name +``` + +Use the `read_spef` `-name` argument to append multiple parasitics files +to annotate hierarchical blocks. Scene definitions use the spef name +to specify which parasitics to use for each scene. + +```tcl +read_spef -name spef_name +report_parasitic_annotation [-name spef_name] +``` + +If `-name` is omitted the base name of the file name is used. + +The `read_spef` `-corner`/`-min`/`-max` arguments are supported for compatibility +but will be removed in a future release. + +The `read_spef` `-reduce` options don't work because sdc, liberty ap isn't known. + +The `report_checks` and `report_check_types` commands support a `-scenes` +argument to report timing checks/paths from multiple scenes. + +```tcl +report_checks -scenes +report_check_types -scenes +report_slews -scenes +report_clock_latency -scenes +``` + +To annotate delays with SDF when there are multiple scenes, use +the `-scene` argument. + +```tcl +read_sdf -scene +report_annotated_delay -scene +report_annotated_check -scene +``` + +SDF annotation for mcmm analysis must follow the scene definitions. + +VCD annotation with `read_vcd` now supports a `-mode` argument. + +```tcl +read_vcd [-mode mode_name] +``` + +The `-corner` args has been removed from the following commands because they are no +longer necessary. + +```tcl +set_load -corner +set_port_fanout_number -corner +``` + +The `report_pulse_width_checks` command is no longer supported. Use +`report_check_types -min_pulse_width`. + +Delay calculation slew values now propagate through `set_case_analysis` +and `set_logic_zero`, `set_logic_one`, `set_logic_dc` constraints. + +Power analysis now ignores `set_case_analysis` and `set_logic_zero`, +`set_logic_one`, `set_logic_dc`. + +## 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 `report_checks` command now supports a `-unique_edges_to_endpoint` option +to remove paths through identical pins and rise/fall edges. + +```tcl +report_checks [-unique_edges_to_endpoint] +``` + +Instances now have pins for verilog netlist power/ground connections. + +`Sta::findPathEnds` `group_paths` arg has been changed from `PathGroupNameSet*` +to `StringSeq&`. + +## Release 2.6.1 2025/03/30 + +The `-list_annotated` and `-list_not_annotated` arguments to the +`report_annotated_delay` and `report_annotated_check` commands have been renamed to +`-report_annotated` and `-report_unannotated`. + +The Tcl `source` command is no longer redefined to support `-echo` and +`-verbose` arguments and redirection. Use the `include` command instead. + +```tcl +include [-echo] [-verbose] filename [> filename] [>> filename] +``` + +- `-echo` echos commands as they are read +- `-verbose` prints command results as they are evaluated + +Unlike the Tcl `source` command, `include` expands filenames with tilde `~` +and respects `sta_continue_on_error`. + +## Release 2.6.0 2024/07/22 + +The version of C++ used by OpenSTA is now 17. +The Cudd BDD package is now required. + +The `USE_TCL_READLINE` option defaults to ON. + +The variable `link_make_black_boxes` has been removed. +Use the `-no_black_boxes` option to the `link_design` command. + +```tcl +link_design [-no_black_blocks] [top_cell_name] +``` + +The `all_inputs` command now supports `-no_clocks` to remove clocks +inputs from the returned list. + +```tcl +all_inputs [-no_clocks] +``` + +The `read_power_activities` command has been deprecated. Use `read_vcd` instead. + +```tcl +read_vcd [-scope scope] filename +``` + +The Switching Activity Interchange Format (SAIF) for reading power activities +is now supported by the `read_saif` command. + +```tcl +read_saif [-scope scope] filename +``` + +The `report_checks` `-group_count` option has been renamed to `-group_path_count`. +The `report_checks` `-endpoint_count` option has been renamed to `-endpoint_path_count`. + +The `report_checks` `-field hierarchical_pins` field reports hierarchical pins between +a driver and a load in the path report. + +The `suppress_msg` and `unsuppress_msg` commands allow suppression/unsuppression of +warnings/errors by ID. Message IDs can be found in doc/Messages.md. + +## Release 2.5.0 2024/01/17 + +The `report_net` `-connections`, `-verbose` and `-hier_pins` flags are deprecated. +The `report_instance` `-connections` and `-verbose` flags are deprecated. +The options are now enabled in all cases. + +The `read_spef` parasitic reduction arguments have changed. The +`-reduce_to` and `-delete_after_reduce` arguments are deprecated and +replaced with the `-reduce` flag. With the `-reduce` flag, the current +delay calculator reduces the parasitic network to the appropriate type +and deletes the parasitic network. + +The `report_clock_skew` and `report_clock_latency` commands now support +the `-include_internal_latency` flag to control inclusion of macro +internal clock delays from the cell liberty `min_clock_tree_path` / +`max_clock_tree_path` timing groups. + +```tcl +report_clock_skew -include_internal_latency +report_clock_latency -include_internal_latency +``` + +The `report_clock_skew` requires a `-scene` argument if multiple scenes are defined. + +The `all_inputs` command now supports the `-no_clocks` argument to exclude +clocks from the list. + +```tcl +all_inputs [-no_clocks] +``` + +The `report_activity_annotation` command reports power activity annotation +from vcd, saif or the `set_input_activity` command. + +```tcl +report_activity_annotation [-report_unannotated] [-report_annotated] +``` + +## Release 2.4.0 2023/01/19 + +The `report_parasitics_annotation` command reports SPEF annotation completeness. + +```tcl +report_parasitics_annotation [-report_unannotated] +``` + +The `read_power_activities` command reads a verilog vcd file and extracts +pin activities for power analysis. + +```tcl +read_power_activities -vcd filename +``` + +The `report_cell` command has been removed; use `report_instance`. + +The `read_liberty` command latch inference (see the command documentation) is now disabled by default. +The `-no_latch_infer` flag is deprecated. +To enable latch inference, use the `-infer_latches` flag. + +The report fanout and capacitance fields are now shown on output pin lines rather +than net lines. + +## Release 2.3.3 2022/09/24 + +Tcl readline support added. See the repository `README.md` for build instructions. + +## Release 2.3.2 2022/07/03 + +The liberty `default_wire_load` is now ignored. You must explicitly set the wire load +model with the `set_wire_load_model` command to apply wire load model based parasitics. + +## Release 2.3.1 2020/11/08 + +The `read_sdf` command no longer supports the `-analysis_type`, `-type`, `-min_type`, +and `-max_type` arguments. Use the `set_operating_conditions -analysis_type` +command to set the analysis type before `read_sdf`. + +## Release 2.2.0 2020/07/18 + +The `report_units` command reports the current units used by commands. + +```tcl +report_units +``` + +The `report_check_types` command now supports `-min_fanout`, `-max_fanout`, +`-max_capacitance`, and `-min_capacitance`. + +```tcl +report_check_types [-min_fanout] [-max_fanout] [-max_capacitance] [-min_capacitance] +``` + +The `insert_buffer` command is no longer supported. + +## Release 2.0.0 2018/09/28 + +The command line options have changed to the following: + +``` +-help show help and exit +-version show version and exit +-no_init do not read .sta init file +-threads count|max use count threads +-no_splash do not show the license splash at startup +-exit exit after reading cmd_file +cmd_file source cmd_file +``` + +Builds using Autotools/configure are no longer supported. +Use CMake as documented in `README.md`. + +The `check_timing` command `-no_output_delay` checks output ports for +`set_output_delay`. + +The `report_power` command reports the power consumption of the design +or a specific instance. + +```tcl +report_power [-instances inst] [-digits digits] [> filename] [>> filename] +``` + +The internal, switching, leakage and total power are reported. Design +power is reported separately for combinational, sequential, macro and +pad groups. + +Use `-instances` to report power for a specific instance. + +Use the `set_power_activity` command to specify activity/duty +globally using `-global`, the input port default using `-input`, +or for input ports using `-input_ports`, or pins using `-pins`. + +```tcl +set_power_activity [-global] + [-input] + [-input_ports ports] + [-pins pins] + [-activity activity] + [-duty duty] +``` + +The `write_path_spice` command writes a spice netlist for a timing path. + +```tcl +write_path_spice -path_args path_args + -spice_directory spice_directory + -subckt_file subckt_file + -lib_subckt_file lib_subckts_file + -model_file model_file + -power power + -ground ground +``` + +Use `path_args` to specify `-from`/`-through`/`-to` as arguments to the +`find_timing_paths` command. For each path, a spice netlist and the +subckts referenced by the path are written in `spice_directory`. The +spice netlist is written in `path_.sp` and the subckt file is +`path_.subckt`. + +Spice netlists for liberty library cells are read from +`lib_subckts_file`. The spice netlists used by the path are written to +`subckt_file`, which `spice_file` includes. The device models used by the +spice subckt netlists in `model_file` are included in `spice_file`. Power +and ground names are specified with the `-power` and `-ground` arguments. +The spice netlist includes a piecewise linear voltage source at the +input and `.measure` statement for each gate delay and pin slew. + +The `report_checks` and `report_check_types` commands now support an +`-unconstrained` flag. + +```tcl +report_checks -unconstrained +report_check_types -unconstrained +``` + +The `sta_report_unconstrained_paths` variable will be supported for +compatibility in the current release. + +The `transition_time` path reporting field has been renamed to `slew`. + +```tcl +report_checks -fields {slew} +report_check_types -fields {slew} +``` + +The `read_parasitics` command has been renamed `read_spef` and no longer +supports the SPF format. + +The `make_instance` command now takes a single instance name argument +and returns the instance. + +```tcl +make_instance instance_name +``` + +The `make_net` command now takes a single net name argument and returns +the net. + +```tcl +make_net net_name +``` + +The `delete_instance` command deletes a single instance instead of a list +of instances. + +```tcl +delete_instance instance +``` + +The `delete_net` command deletes a single net instead of a list +of nets. + +```tcl +delete_net net +``` + +The `disconnect_pins` command is renamed `disconnect_pin` and disconnects a +single pin. + +```tcl +disconnect_pin net pin +``` + +The `report_tns` and `report_wns` commands print the value returned by +`total_negative_slack` and `worst_negative_slack` respectively. + +```tcl +report_tns +report_wns +report_worst_slack +``` + +The `set_clock_sense` command was deprecated by SDC 2.1. +Use `set_sense -type clock` instead. diff --git a/doc/ChangeLog.txt b/doc/ChangeLog.txt deleted file mode 100644 index 4b803497d..000000000 --- a/doc/ChangeLog.txt +++ /dev/null @@ -1,647 +0,0 @@ -OpenSTA Timing Analyzer Release Notes -------------------------------------- - -This file summarizes user visible changes for each release. -See ApiChangeLog.txt for changes to the STA api. - -2026/08/02 ----------- - -The set_path_margin command applies a signed slack adjustment to the -capture-clock side of matching timing paths. A positive margin -tightens the path and a negative margin loosens it. - - set_path_margin [-setup] [-hold] [-rise] [-fall] - [-from from_list|-rise_from from_list|-fall_from from_list] - [-through through_list|-rise_through through_list|-fall_through through_list] - [-to to_list|-rise_to to_list|-fall_to to_list] - [-comment comment] - margin - -2026/07/20 ----------- - -The read_vcd command supports -begin_time / -end_time to limit -activity annotation to a VCD time window. - - read_vcd [-scope scope] [-mode mode_name] - [-begin_time begin_time] [-end_time end_time] filename - -2026/05/01 ----------- - -The write_sdc command supports a -mode argument. - - write_sdc [-mode mode] - -2026/03/23 ----------- - -The write_path_spice command -spice_directory has been changed to --spice_file, which is a prefix for the spice filenames. Successive -paths are written in files name _.sp. - -Release 3.0.1 2026/03/12 ------------------------- - -Statistical timing (SSTA) with Liberty LVF (Liberty Variation Format) -models is now supported. Statistical timing uses a probability -distribution to represent a delay or slew rather than a single -number. - -Normal and skew normal probability distributions are supported. - -SSTA is enabled with the sta_pocv_mode variable. - - set sta_pocv_mode scalar|normal|skew_normal - -scalar mode is for non-SSTA analysis -normal mode uses gaussian normal distributions -skew_normal'mode is for skew normal LVF moment based distributions - -The target quantile of a delay probability distribution (confidence level) is -set with the sta_pocv_quantile variable. - - sta_pocv_quantile - -The default value is 3 standard deviations, or sigma. - -Use the variation field with report_checks or report_check_types to see -distribution parameters in timing reports. - -A command file for analyzing a design with statistical timing with an -LVF library is shown below. - -read_liberty lvf_library.lib.gz -read_verilog design.v -link_design top -create_clock -period 50 clk -set_input_delay -clock clk 1 {in1 in2} -set sta_pocv_mode skew_normal -report_checks -fields {slew variation input_pin} -digits 3 - -Startpoint: r2 (rising edge-triggered flip-flop clocked by clk) -Endpoint: r3 (rising edge-triggered flip-flop clocked by clk) -Path Group: clk -Path Type: max - - Slew Delay Variation Time Description ---------------------------------------------------------------------------- - 0.000 0.000 0.000 clock clk (rise edge) - 0.000 0.000 clock network delay (ideal) - 0.000 0.000 0.000 ^ r2/CK (FDPQ1) - 12.026 mean - 0.017 mean_shift - 0.366 std_dev - 0.000 skewness - 4.648 12.409 12.409 v r2/Q (FFQ1) - 4.648 0.000 12.409 v u1/A (BUF1) - 6.084 mean - 0.007 mean_shift - 0.188 std_dev - 0.000 skewness - 2.513 6.137 18.546 v u1/X (BUF1) - 2.513 0.000 18.546 v u2/A2 (AN21) - 6.447 mean - 0.008 mean_shift - 0.191 std_dev - 0.000 skewness - 2.565 6.497 25.043 v u2/X (AN21) - 2.565 0.000 25.043 v r3/D (FFQ1) - 25.043 data arrival time - - 0.000 50.000 50.000 clock clk (rise edge) - 0.000 50.000 clock network delay (ideal) - 0.000 50.000 clock reconvergence pessimism - 50.000 ^ r3/CK (FFQ1) - -9.376 40.624 library setup time - 40.624 data required time ---------------------------------------------------------------------------- - 40.624 data required time - -25.043 data arrival time ---------------------------------------------------------------------------- - 15.581 slack (MET) - - -The following commands now support a -report_variance arggument. - - report_arrival [-report_variance] - report_required [-report_variance] - report_slack [-report_variance] - report_slews [-report_variance] - report_edges [-report_variance] - -The following commands now support a -digits option. - - report_edges [-digits digits] - report_slews [-digits digits] - -The standard deviation for normal distributions is specified with the -following liberty timing groups. - - ocv_sigma_cell_rise - ocv_sigma_cell_fall - ocv_sigma_rise_transition - ocv_sigma_fall_transition - ocv_sigma_rise_constraint - ocv_sigma_fall_constraint - -LVF skew normal distributions are specified with liberty groups below. - - ocv_std_dev_cell_rise - ocv_std_dev_cell_fall - ocv_mean_shift_cell_rise - ocv_mean_shift_cell_fall - ocv_skewness_cell_rise - ocv_skewness_cell_fall - - ocv_std_dev_rise_transition - ocv_std_dev_fall_transition - ocv_skewness_rise_transition - ocv_skewness_fall_transition - ocv_mean_shift_rise_transition - ocv_mean_shift_fall_transition - - ocv_std_dev_rise_constraint - ocv_std_dev_fall_constraint - ocv_skewness_rise_constraint - ocv_skewness_fall_constraint - ocv_mean_shift_rise_constraint - ocv_mean_shift_fall_constraint - -2026/02/24 ----------- - -The define_scene -library argument now takes a the library name or a -library filename. If a filename is used, it must be the same as the -filename used to read the library with read_liberty. - -Release 3.0.0 2025/11/26 ------------------------- - -This release adds multi-corner multi-mode (mcmm) support. The SDC -constraints in each mode describe a different operating mode, such as -mission mode or scan mode. - -A "scene" is the combination of a mode and corner. Each scene can have -separate min/max liberty and spef files. - -THe basic structure of a multi-corner/multi-mode command file is - read_liberty - read_verilog - link_design - read_sdc -mode... or set_mode followed by sdc commands - read_spef -name... - define_scene... - report_checks [-scenes] - -This is an example script with 2 corners, 2 modes and 3 scenes. - -read_liberty bc.lib -read_liberty wc.lib - -read_verilog design.v -link_design top - -read_sdc -mode run design.sdc -read_sdc -mode scan design_scan.sdc - -read_spef -name bc bc.spef -read_spef -name wc wc.spef - -define_scene bc \ - -mode run \ - -liberty bc \ - -spef bc -define_scene wc \ - -mode run \ - -liberty wc \ - -spef wc -define_scene scan \ - -mode scan \ - -liberty wc \ - -spef wc - -report_checks -report_checks -scenes bc -report_checks -scenes wc -report_checks -scenes scan - -................ - -Alternatively, the set_mode command can be used to define commands -for each mode at the command level instead of using SDC files. - -set_mode run -create_clock -period 10 clock -set_input_delay 0 -clock clock [all_inputs -no_clocks] -set_output_delay 0 -clock clock [all_outputs] - -set_mode scan -create_clock -period 100 scan_clock -set_input_delay 0 -clock scan_clock scan_in -set_output_delay 0 -clock scan_clock scan_out - -................ - -The define_corners command is supported for compatiblity but should -not be used with mcmm flows. Similarly, the -min/-max arguemnts to -read_liberty and read_spaf are supported for compabibility but should -not be used with mcmm flows. - -................ - -An initial mode and scene named "default" are defined for single mode, -single corner analysis. SDC commands defined interactively and read -with read_sdc without a -mode argument are defined in the "default" -mode. - -Use the set_mode command to define a mode or set the command -interpreter to add following commands to mode mode_name. - - set_mode mode_name - -If mode_name does not exist it is created. When modes are created the -default mode is deleted. - -The read_sdc command has a -mode argument to assign the commands in the file -to a mode. - - read_sdc [-mode mode_name] - -If the mode does not exist it is created. Multiple SDC files can -append commands to a mode by using the -mode_name argument for each -one. If no -mode arguement is is used the commands are added to the -current mode. - -................ - -The define_scene command defines a scene for a mode (SDC), liberty files -and spef parasitics. - - define_scene -mode mode_name - -liberty liberty_files | -liberty_min liberty_min_files -liberty_max liberty_max_files - [-spef spef_file | -spef_min spef_min_file -spef_max spef_max_file] - -Use get_scenes to find defined scenes. - - get_scenes [-modes mode_names] scene_name - -................ - -Use the read_spef -name argument to append multiple parasitics files -to annotate hierarchical blocks. Scene definitions use the spef_name -to specify which parasitices to use for each scene. - - read_spef -name spef_name - report_parasitic_annotation [-name spef_name] - -If -name is omitted the base name of the file name is used. - -The read_spef -corner/-min/-max arguments are supported for comppatibility -but will be removed in a future release. - -The read_spef -reduce options don't work because sdc, liberty ap isn't known - -................ - -The report_checks and report_check_typescommands support a -scenes -argument to report timing checks/paths from multiple scenes. - - report_checks -scenes - report_check_types -scenes - report_slews -scenes - report_clock_latency -scenes - -................ - -To annotate delays with SDF when there are multiple scenes, use -the -scene argument. - - read_sdf -scene - report_annotated_delay -scene - report_annotated_check -scene - -SDF annotation for mcmm analysis must follow the scene definitions. - -................ - -VCD annotation with read_vcd now supports a -mode arguement. - - read_vcd [-mode mode_name] - -................ - -The -corner args has been removed from the following commands because they are no -longer necessary. - set_load -corner - set_port_fanout_number -corner - -................ - -The report_pulse_width_checks command is no longer supported. Use -report_check_types -min_pulse_width. - -................ - -Delay calculation slew values now propagate through set_case_analysis -and set_logic_zero, set_logic_one, set_logic_dc constraints. - -Power analysis now ignores set_case_analysis and set_logic_zero, -set_logic_one, set_logic_dc. - -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 report_checks command now supports a -unique_edges_to_endpoint option -to remove paths through identical pins and rise/fall edges. - - report_checks [-unique_edges_to_endpoint] - -Instances now have pins for verilog netlist power/ground connections, - -Sta::findPathEnds group_paths arg has been changed from PathGroupNameSet* -to StringSeq&. - -Release 2.6.1 2025/03/30 -------------------------- - -The -list_annotated and -list_not_annotated arguments to the -report_annotated_delay and report_annotated_check commands have been renamed to --report_annotated and -report_unannotated. - -The Tcl "source" command is no longer redefined to support "-echo" and -"-verbose" arguments and redirecton. Use the "include" command instead. - - include [-echo] [-verbose] filename [> filename] [>> filename] - -echo echos commands as they are read - -verbose prints command results as they are evaluated - -Unlike the Tcl source command, "include" expands filenames with tilda '~' -and respects sta_continue_on_error. - -Release 2.6.0 2024/07/22 -------------------------- - -The version of c++ used by OpenSTA is now 17. -The Cudd BBD packager is now required. - -The USE_TCL_READLINE option defaults to ON. - -The variable link_make_black_boxes has been removed. -Use the -no_black_boxes option to the link_design command. - - link_design [-no_black_blocks] [top_cell_name] - -The all_inputs command now supports -no_clocks to remove clocks -inputs from the returned list. - - all_inputs [-no_clocks] - -The read_power_activities command has been deprecated. Use read_vcd instead. - - read_vcd [-scope scope] filename - -The Switching Activity Interchange Format (SAIF) for reading power activities -is now supported by the the read_saif command. - - read_saif [-scope scope] filename - -The report_checks -group_count option has been renamed to -group_path_count. -The report_checks -endpoint_count option has been renamed to -endpoint_path_count. - -The report_checks -field hierarchical_pins field reports hierarchical pins between -a driver and a load in the path report. - -The suppress_msg and unsuppress_msg commands allow suppression/unsuppression of -warnings/errors by ID. Message IDs can be found in doc/messages.txt. - -Release 2.5.0 2024/01/17 -------------------------- - -The report_net -connections, -verbose and -hier_pins flags are deprecated. -The report_instance -connections and -verbose flags are deprecated. -The options are now enabled in all cases. - -The read_spef parasitic reduction arguments have changed. The --reduce_to and -delete_after_reduce arguments are deprecated and -replaced with the -reduce flag. With the -reduce flag, the current -delay calculator reduces the parastic network to the appropriate type -and deletes the parasitic network. - -The report_clock_skew and report_clock_latency commands now supports -the -include_internal_latency flag to control inclusion of macro -internal clock delays from the cell liberty min/max_clock_tree_path -timing groups. - - report_clock_skew -include_internal_latency - report_clock_latency -include_internal_latency - -The report_clock_skew requires a -scene argument if multiple scenes are defined. - -The all_inputs command now supports the -no_clocks argument to exclude -clocks from the list. - - all_inputs [-no_clocks] - -The report_activity_annotation command reports power activity annotaton -from vcd, saif or the set_input_activity command. - - report_activity_annotation [-report_unannotated] [-report_annotated] - -Release 2.4.0 2023/01/19 -------------------------- - -The report_parasitics_annotation command reports SPEF annotation completeness. - - report_parasitics_annotation [-report_unannotated] - -The read_power_activities command reads a verilog vcd file and extracts -pin activities for power analysis. - - read_power_activities -vcd filename - -The report_cell command has been removed; use report_instance. - -The read_liberty command latch inference (see OpenSTA.pdf) is now disabled by default. -The -no_latch_infer flag is deprecated. -To enable latch inference, use the -infer_latches flag. - -The report fanout and capacitance fields are now shown on output pin lines rather -than net lines. - -Release 2.3.3 2022/09/24 -------------------------- - -TCL readline support added. See README.md for build instructions. - -Release 2.3.2 2022/07/03 -------------------------- - -The liberty default_wire_load is now ignored. You must explicitly set the wire load -model with the set_wire_load_model command to apply wire load model based parasitics. - -Release 2.3.1 2020/11/08 -------------------------- - -The read_sdf command no longer supports the -analysis_type, -type, -min_type, -and -max_type arguments. Use the set_operating_conditions -analysis_type -command to set the analysis type before read_sdf. - -Release 2.2.0 2020/07/18 -------------------------- - -The report_units reports the current units used by commands. - - report_units - -The report_check_types -min_fanout -max_fanout -max_capacitance -min_capacitance - - report_check_types [-min_fanout] [-max_fanout] [-max_capacitance] [-min_capacitance] - - -The insert_buffer command is no longer supported. - -Release 2.0.0 2018/09/28 -------------------------- - -The command line options have changed to the following: - - -help show help and exit - -version show version and exit - -no_init do not read .sta init file - -threads count|max use count threads - -no_splash do not show the license splash at startup - -exit exit after reading cmd_file - cmd_file source cmd_file - - -.... - -Builds using Autotools/configure are no longer supported. -Use CMake as documented in README.md. - -.... - -The check_timing command -no_output_delay checks output ports for -set_output_delay. - -.... - -The report_power command reports the power consumption of the design -or a specific instance. - - report_power [-instances inst] [-digits digits] [> filename] [>> filename] - -The internal, switching, leakage and total power are reported. Design -power is reported separately for combinational, sequential, macro and -pad groups. - -Use -instances to report power for a specific instance. - -Use the set_power_activity command to specify activity/duty -globally using -global, the input port default using -input, -or for input ports using -input_ports, or pins using -pins. - - set_power_activity [-global] - [-input] - [-input_ports ports] - [-pins pins] - [-activiity activity] - [-duty duty] - -.... - -The write_path_spice command writes a spice netlist for a timing path. - - write_path_spice -path_args path_args - -spice_directory spice_directory - -subckt_file subckt_file - -lib_subckt_file lib_subckts_file\ - -model_file model_file - -power power - -ground ground - -Use path_args to specify -from/-through/-to as arguments to the -find_timing_paths command. For each path, a spice netlist and the -subckts referenced by the path are written in spice_directory. The -spice netlist is written in path_.sp and subckt file is -path_.subckt. - -Spice netlists for liberty library cells are read from -lib_subckts_file. The spice netlists used by the path are written to -subckt_file, which spice_file .includes. The device models used by the -spice subckt netlists in model_file are .included in spice_file. Power -and ground names are specified with the -power and -ground arguments. -The spice netlist includes a piecewise linear voltage source at the -input and .measure statement for each gate delay and pin slew. - -.... - -The report_checks and report_check_types commands now support an --unconstrained flag. - - report_checks -unconstrained - report_check_types -unconstrained - -The sta_report_unconstrained_paths variable will be supported for -for compatibility in the current release. - -.... - -The transition_time path reporting field has been renamed to slew. - - report_checks -fields {slew} - report_check_types -fields {slew} - -... - -The read_parasitics command has been renamed read_spef and no longer -supports the SPF format. - -.... - -The make_instance command now takes a single instance name argument -and returns the instance. - - make_instance instance_name - -The make_net command now takes a single net name argument and returns -the net. - - make_net net_name - -The delete_instance command deletes a single instance instead of a list -of instances. - - delete_instance instance - -The delete_net command deletes a single net instead of a list -of nets. - - delete_net net - -The disconnect_pins command is renamed disconnect_pin and disconnects a -single pin. - - disconnect_pin net pin - -The report_tns and report_wns commands print the value returned by -total_negative_slack and worst_negative_slack respectively. - - report_tns - report_wns - report_worst_slack - -The set_clock_sense command was deprecated by SDC 2.1. -Use set_sense -type clock instead. - -# Local Variables: -# mode:text -# End: diff --git a/doc/CodingGuidelines.md b/doc/CodingGuidelines.md new file mode 100644 index 000000000..e88352809 --- /dev/null +++ b/doc/CodingGuidelines.md @@ -0,0 +1,180 @@ +# Coding guidelines + +## Naming conventions + +| Kind | Convention | Example | +| --- | --- | --- | +| directory | lowercase | `directory` | +| filename | corresponding class name without prefix | `Filename.cc` | +| class | upper camel case | `ClassName` | +| member function | lower camel case | `memberFunction` | +| member variable | snake case with trailing underscore | `member_variable_` | +| function | lower camel case | `functionName` | +| variable | snake case | `variable` | +| comments | capitalized sentences that end with periods | | + +The trailing underscore on member variables prevents a conflict with +the accessor member function name. + +C++ source files should use a `.cc` file extension. +C++ header files should use a `.hh` file extension. + +Use pragmas to protect headers from being read more than once instead of +`#ifdef` / `#define`. + +```cpp +#pragma once +``` + +In general it is better for class variables to use pointers to +objects of other classes rather than embedding the instance directly. +This only requires that the class be declared rather than defined, +many times breaking a dependency on another header file. + +Header files that define the classes of a sub-directory allow other +headers to have pointers to the objects without pulling in the details +of the class definitions. These headers are named `DirectoryClass.hh` +where `Directory` is the capitalized name of the sub-directory. + +Place comments describing public functions and classes in header files +rather than code files because a consumer is more likely to have +access to the header and that is the first place they will look. + +The return type of a function should be on the line before the +function name. Arguments should be on separate lines to make it easier +to remove or add them without having to reformat the lines as they +change length. + +```cpp +return_type +function(type1 arg1, + type2 arg2) +{ +} +``` + +Functions should be less than one screen long. Break long functions +up into smaller ones. Lines should be less than 90 characters long. + +Avoid assignments inside `if` conditions. For example, don't write +this: + +```cpp +if ((foo = (char *) malloc (sizeof *foo)) == 0) + fatal ("virtual memory exhausted"); +``` + +instead, write this: + +```cpp +foo = (char *) malloc (sizeof *foo); +if (foo == nullptr) + fatal ("virtual memory exhausted"); +``` + +Do not use braces around `if`/`for` that are one line. + +```cpp +if (pred) + bar = 1; +else + bar = 3; +``` + +Use braces around `if`/`for` bodies that are more than one line. + +```cpp +if (pred) { + for (int i = 0; i < len; i++) { + ... + } +} +``` + +Add a default clause to all switches calling `switchCaseNotHandled`: + +```cpp +switch (type) { +case edge_interconnect: + ... +default: + switchCaseNotHandled(); +} +``` + +Put return types for functions on the line before the function name: + +```cpp +Cell * +Library::findCell(char *name) +{ + ... +} +``` + +Class member functions should be grouped in public, protected and then +private order. + +```cpp +class Frob +{ +public: +protected: +private: + + friend class Frobulator; +}; +``` + +Class member functions should not be defined inside the class unless they +are simple accessors that return a member variable. + +Avoid using `[]` to lookup a map value because it creates a key/null value +pair if the lookup fails. Use `map::find` or `sta::findKey` instead. + +Avoid nested classes/enums because SWIG has trouble with them. + +Avoid all use of global variables as "caches", even if they are thread local. +OpenSTA goes to great lengths to minimize global state variables that prevent +multiple instances of the `Sta` class from coexisting. + +Do not use `thread_local` variables. They are essentially global +variables so they prevent multiple instances of an `Sta` object from +existing concurrently, so they should also be avoided. Use stack state +in each thread instead. + +## Regression tests + +Most regression tests live in the private `pvt/test/` tree. A smaller +public subset ships in `test/` at the OpenSTA repo root. + +Tests are run with the Tcl script `test/regression` (or `pvt/test/regression`): + +``` +Usage: regression [-help] [-threads threads] [-valgrind] [-report_stats] tests... + -threads max|integer - number of threads to use + -valgrind - run valgrind (linux memory checker) + -report_stats - report run time and memory + Wildcarding for test names is supported (enclose in "'s) +``` + +Test log files and results are in `test/results`. The `test/results/.log` +is compared to `test/.ok` to determine if a test passes. + +Test scripts are written in Tcl and live in `pvt/test/` or `test/`. +Compress large Liberty, Verilog, and SPEF files. Use small or +existing Verilog and Liberty files to prevent repository bloat. + +The test script should use a one line comment at the beginning of the +file so `head -1` can show what it is for. Use file names to roughly +group regressions and use numeric suffixes to distinguish them. + +The script `test/save_ok` saves a `test/results/.log` to +`test/.ok`. + +To add a new regression: + +- add `.tcl` to `test/` +- add the `` name to `test/regression_vars.tcl` +- run the test with `test/regression ` +- use `save_ok ` to save the log file to `test/.ok` diff --git a/doc/CodingGuidelines.txt b/doc/CodingGuidelines.txt deleted file mode 100644 index 4e2e096eb..000000000 --- a/doc/CodingGuidelines.txt +++ /dev/null @@ -1,153 +0,0 @@ -Naming conventions ------------------- - -directory - lowercase (directory) -filename - corresponding class name without prefix (Filename) -class - upper camel case (ClassName) -member function - lower camel case (memberFunction) -member variable - snake case with trailing underscore (member_variable_) - Trailing underscore prevents conflict with accessor - member function name. -function - lower camel case (functionName) -variable - snake case -comments - use capitalized sentences that end with periods - -C++ code files should use a .cc file extension -C++ header files should use a .hh file extension - -Use pragmas to protect headers from being read more than once instead of -ifdef/define. - - #pragma once - -In general it is better to for class variables to use pointers to -objects of other classes rather than embedding the instance directly. -This only requires that the class be declared rather than defined, -many times breaking a dependency on another header file. - -Header files that define the classes of a sub-directory allow other -headers to have pointers to the objects without pulling in the details -of the class definitions. These headers are named "DirectoryClass.hh" -where Directory is the capitalized name of the sub-directory. - -Place comments describing public functions and classes in header files -rather than code files because a consumer is more likely to have -access to the header and that is the first place they will look. - -The return type of a function should be on the line before the -function name. Arguments should be on separate lines to make it easier -to remove or add them without having to reformat the lines as they -change length. - -return_type -function(type1 arg1, - type2 arg2) -{ -} - -Functions should be less than one screen long. Break long functions -up into smaller ones. Lines should be less than 90 characters long. - -Avoid assignments inside `if'-conditions. For example, don't write -this: - - if ((foo = (char *) malloc (sizeof *foo)) == 0) - fatal ("virtual memory exhausted"); - -instead, write this: - - foo = (char *) malloc (sizeof *foo); - if (foo == nullptr) - fatal ("virtual memory exhausted"); - - -Do not use braces around if/for that are one line. - - if (pred) - bar = 1; - else - bar = 3; - -Use braces around if/for bodies that are more than one line. - - if (pred) { - for (int i = 0; i < len; i++) { - ... - } - } - -Add a default clause to all switches calling switchCaseNotHandled: - - switch (type) { - case edge_interconnect: - ... - default: - switchCaseNotHandled(); - } - -Put return types for functions on the line before the function name: - - Cell * - Library::findCell(char *name) - { - ... - } - -Class member functions should be grouped in public, protected and then -private order. - - class Frob - { - public: - protected: - private: - - friend class Frobulator; - } - -Class member functions should not be defined inside the class unless they -are simple accessors that return a member variable. - -Avoid using [] to lookup a map value because it creates a key/null value -pair if the lookup fails. Use map::find or sta::Map::findKey instead. - -Avoid nested classes/enums because SWIG has trouble with them. - -Avoid all use of global variables as "caches", even if they are thread local. -OpenSTA goes to great lengths to minimize global state variable that prevent -multiple instances of the Sta class from coexisting. - -Do not use thread_local variables. They are essentially global -variables so they prevent multiple instances of an Sta object from -existing concurrently, so they sbould also be avoided. Use stack state -in each thread instead. - -Regression Tests -................ - -Tests are run with the tcl script test/regression: - -Usage: regression [-help] [-threads threads] [-valgrind] [-report_stats] tests... - -threads max|integer - number of threads to use - -valgrind - run valgrind (linux memory checker) - -report_stats - report run time and memory - Wildcarding for test names is supported (enclose in "'s) - -Tests log files and results are in test/results. The result/test.log -is compared to test.ok to determine if a test passes. - -Test scripts are written in tcl and live in the /test directory. -Compress large liberty, verilog, and spef, files., Use small or -existing verilog and liberty files to prevent repository bloat. - -The test script should use a one line comment at the beginning of the -file so head -1 can show what it is for. Use file names to roughly -group regressions and use numeric suffixes to distinguish them. - -The script test/save_ok saves a test/results/.log to test/.okfile. - -To add a new regression: - add .tcl to /tcl - add name to test/regression_vars.tcl - run with test/regression - use save_ok to save the log file to >test>.log diff --git a/doc/Debugging.md b/doc/Debugging.md new file mode 100644 index 000000000..590e3773e --- /dev/null +++ b/doc/Debugging.md @@ -0,0 +1,116 @@ +# Debugging timing + +Here are some guidelines for debugging your design if static timing +does not report any paths, or does not report the expected paths. + +Debugging timing problems generally involves using the following +commands to follow the propagation of arrival times from a known +arrival downstream to understand why the arrival times are not +propagating: + +```tcl +report_edges +report_arrival +report_net +``` + +`report_edges -from` can be used to walk forward and `report_edges -to` +to walk backward in the netlist/timing graph. `report_arrival` shows +the min/max rise/fall arrival times with respect to each clock that has +a path to the pin. `report_net` shows connections to a net across +hierarchy levels. + +## No paths found + +The `report_checks` command only reports paths that are constrained by +timing checks or SDC commands such as `set_output_delay`. If the design +has only combinational logic (no registers or latches), there are no +timing checks, so no paths are reported. Use the `-unconstrained` +option to `report_checks` to see unconstrained paths. + +```tcl +% report_checks -unconstrained +``` + +If the design is sequential (has registers or latches) and no paths are +reported, it is likely that there is a problem with the clock +propagation. Check the timing at a register in the design with the +`report_arrival` command. + +```tcl +% report_arrival r1/CP + (clk ^) r 0.00:0.00 f INF:-INF + (clk v) r INF:-INF f 5.00:5.00 +``` + +In this example the rising edge of the clock `clk` causes the rising +arrival min:max time at 0.00, and the falling edge arrives at 5.00. +Since the rising edge of the clock causes the rising edge of the +register clock pin, the clock path is positive unate. + +The clock path should be positive or negative unate. Something is +probably wrong with the clock network if it is non-unate. A non-unate +clock path will report arrivals similar to the following: + +```tcl +% report_arrival r1/CP + (clk ^) r 0.00:0.00 f 0.00:0.00 + (clk v) r 5.00:5.00 f 5.00:5.00 +``` + +Notice that each clock edge causes both rise and fall arrivals at the +register clock pin. + +If there are no paths to the register clock pin, nothing is printed. +Use the `report_edges -to` command to find the gate driving the clock +pin. + +```tcl +% report_edges -to r1/CP +i1/ZN -> CP wire + ^ -> ^ 0.00:0.00 + v -> v 0.00:0.00 +``` + +This shows that the gate/pin `i1/ZN` is driving the clock pin. The +`report_edges -to` command can be used to walk backward or forward +through the netlist one gate/net at a time. By checking the arrivals +with the `report_arrival` command you can determine where the path is +broken. + +## No path reported at an endpoint + +In order for a timing check to be reported, there must be an arrival +time at the data pin (the constrained pin) as well as the timing check +clock pin. If `report_checks -to` a register input does not report any +paths, check that the input is constrained by a timing check with +`report_edges -to`. + +```tcl +% report_edges -to r1/D +CP -> D hold + ^ -> ^ -0.04:-0.04 + ^ -> v -0.03:-0.03 +CP -> D setup + ^ -> ^ 0.09:0.09 + ^ -> v 0.08:0.08 +in1 -> D wire + ^ -> ^ 0.00:0.00 + v -> v 0.00:0.00 +``` + +This reports the setup and hold checks for the D pin of `r1`. + +Next, check the arrival times at the D and CP pins of the register with +`report_arrival`. + +```tcl +% report_arrival r1/D + (clk1 ^) r 1.00:1.00 f 1.00:1.00 +% report_arrival r1/CP + (clk1 ^) r 0.00:0.00 f INF:-INF + (clk1 v) r INF:-INF f 5.00:5.00 +``` + +If there are no arrivals on an input port of the design, use the +`set_input_delay` command to specify the arrival times on the port. diff --git a/doc/DocBuild.md b/doc/DocBuild.md new file mode 100644 index 000000000..f4cfad1ee --- /dev/null +++ b/doc/DocBuild.md @@ -0,0 +1,26 @@ +Documention is publish at https://opensta.readthedocs.io/en/latest/ using +.readthedocs.yaml. + +Command documention is declared in the various TCL command file such as search/Search.tcl. +An example is show below. + +define_cmd_args "check_setup" \ + { [-verbose] [-no_input_delay] [-no_output_delay]\ + [-multiple_clock] [-no_clock]\ + [-unconstrained_endpoints] [-loops] [-generated_clocks]\ + [> filename] [>> filename] } \ + -help {The `check_setup` command performs sanity checks on the design. Individual checks can be performed with the keywords. If no check keywords are specified all checks are performed. Checks that fail are reported as warnings. If no checks fail nothing is reported. The command returns 1 if there are no warnings for use in scripts.} \ + -arg_help { + -verbose {Show offending objects rather than just error counts.} + -unconstrained_endpoints {Check path endpoints for timing constraints (timing check or `set_output_delay`).} + -multiple_clock {Check register/latch clock pins for multiple clocks.} + -no_clock {Check register/latch clock pins for a clock.} + -no_input_delay {Check for inputs that do not have a `set_input_delay` command.} + -no_output_delay {Check for outputs that do not have a `set_output_delay` command.} + -no_output_delay {Check for outputs that do not have a `set_output_delay` command.} + -loops {Check for combinational logic loops.} + -generated_clocks {Check that generated clock source pins have been defined as clocks.} + } + +The script etc/WriteCmdDocs.tcl extracts the command documentation +from the sources and writes doc/Commands.mv, doc/Variables.md, and doc/CommandLine.md. diff --git a/doc/Examples.md b/doc/Examples.md new file mode 100644 index 000000000..abeef120d --- /dev/null +++ b/doc/Examples.md @@ -0,0 +1,249 @@ +# Examples + +To read a design into OpenSTA use the `read_liberty` command to read +Liberty library files. Next, read hierarchical structural Verilog files +with the `read_verilog` command. The `link_design` command links the +Verilog to the Liberty timing cells. Any number of Liberty and Verilog +files can be read before linking the design. + +Delays used for timing analysis are calculated using the Liberty timing +models. If no parasitics are read only the pin capacitances of the +timing models are used in delay calculation. Use the `read_spef` +command to read parasitics from an extractor, or `read_sdf` to use +delays calculated by an external delay calculator. + +Timing constraints can be entered as Tcl commands or read using the +`read_sdc` command. + +The units used by OpenSTA for all command arguments and reports are +taken from the first Liberty file that is read. Use the `set_cmd_units` +command to override the default units. Use the `report_units` command +to see the command units. + +## Timing analysis using SDF + +A sample command file that reads a library and a Verilog netlist and +reports timing checks is shown below. + +```tcl +read_liberty example1_slow.lib +read_verilog example1.v +link_design top +read_sdf example1.sdf +create_clock -name clk -period 10 {clk1 clk2 clk3} +set_input_delay -clock clk 0 {in1 in2} +report_checks +``` + +This example can be found in `examples/sdf_delays.tcl`. + +## Timing analysis with multiple scenes + +An example command script using three scenes and +/-10% min/max +derating is shown below. + +```tcl +read_liberty nangate45_slow.lib.gz +read_liberty nangate45_typ.lib.gz +read_liberty nangate45_fast.lib.gz +read_verilog example1.v +link_design top +set_timing_derate -early 0.9 +set_timing_derate -late 1.1 +create_clock -name clk -period 10 {clk1 clk2 clk3} +set_input_delay -clock clk 0 {in1 in2} + +define_scene ss -liberty nangate45_slow +define_scene tt -liberty nangate45_typ +define_scene ff -liberty nangate45_fast + +# report all scenes +report_checks -path_delay min_max +# report typical scene +report_checks -scene tt +``` + +This example can be found in `examples/multi_corner.tcl`. Other examples +can be found in the `examples` directory. + +## Timing analysis with multiple modes and scenes + +OpenSTA supports multi-corner, multi-mode analysis. SDC constraints in +each mode describe an operating mode such as mission or scan. A scene +is a combination of a mode with Liberty libraries and SPEF parasitics. + +A mode named "default" is initially created for SDC commands. It is +deleted when a mode is defined with `set_mode` or `read_sdc -mode`. +Similarly, a scene named "default" is initially created that is deleted +when `define_scene` is used to define a scene. + +An example command script using two scenes and two modes is +shown below. + +```tcl +read_liberty asap7_small_ff.lib.gz +read_liberty asap7_small_ss.lib.gz +read_verilog reg1_asap7.v +link_design top + +read_sdc -mode mode1 mcmm2_mode1.sdc +read_sdc -mode mode2 mcmm2_mode2.sdc + +read_spef -name reg1_ff reg1_asap7.spef +read_spef -name reg1_ss reg1_asap7_ss.spef + +define_scene scene1 -mode mode1 -liberty asap7_small_ff -spef reg1_ff +define_scene scene2 -mode mode2 -liberty asap7_small_ss -spef reg1_ss + +report_checks -scenes scene1 +report_checks -scenes scene2 +report_checks -group_path_count 4 +``` + +This example can be found in `examples/mcmm3.tcl`. + +In the example shown above the SDC for each mode is defined in a +separate file. Alternatively, the SDC can be defined in the command +file using the `set_mode` command between SDC command groups. + +```tcl +set_mode mode1 +create_clock -name m1_clk -period 1000 {clk1 clk2 clk3} +set_input_delay -clock m1_clk 100 {in1 in2} + +set_mode mode2 +create_clock -name m2_clk -period 500 {clk1 clk3} +set_output_delay -clock m2_clk 100 out +``` + +## Statistical timing analysis + +OpenSTA also supports statistical timing analysis with Liberty Variation +Format (LVF) libraries. Statistical timing uses a probability +distribution to represent a delay or slew rather than a single number. + +Normal and skew normal probability distributions are supported. SSTA is +enabled with the `sta_pocv_mode` variable. + +```tcl +set sta_pocv_mode scalar|normal|skew_normal +``` + +- `scalar` mode is for non-SSTA analysis +- `normal` mode uses gaussian normal distributions +- `skew_normal` mode is for skew normal LVF moment based distributions + +The target quantile of a delay probability distribution (confidence +level) is set with the `sta_pocv_quantile` variable. + +```tcl +set sta_pocv_quantile +``` + +The default value is 3 standard deviations, or sigma. + +Use the `variation` field with the `report_checks` and +`report_check_types` commands to see distribution parameters in timing +reports. + +A command file for analyzing a design with statistical timing is shown +below. + +```tcl +read_liberty lvf_library.lib.gz +read_verilog design.v +link_design top +create_clock -period 50 clk +set_input_delay -clock clk 1 {in1 in2} +set sta_pocv_mode skew_normal +report_checks -fields {slew variation input_pin} -digits 3 +``` + +The standard deviation for normal distributions is specified with the +following Liberty timing groups. + +``` +ocv_sigma_cell_rise +ocv_sigma_cell_fall +ocv_sigma_rise_transition +ocv_sigma_fall_transition +ocv_sigma_rise_constraint +ocv_sigma_fall_constraint +``` + +LVF skew normal distributions are specified with the Liberty groups +below. + +``` +ocv_std_dev_cell_rise +ocv_std_dev_cell_fall +ocv_mean_shift_cell_rise +ocv_mean_shift_cell_fall +ocv_skewness_cell_rise +ocv_skewness_cell_fall + +ocv_std_dev_rise_transition +ocv_std_dev_fall_transition +ocv_skewness_rise_transition +ocv_skewness_fall_transition +ocv_mean_shift_rise_transition +ocv_mean_shift_fall_transition + +ocv_std_dev_rise_constraint +ocv_std_dev_fall_constraint +ocv_skewness_rise_constraint +ocv_skewness_fall_constraint +ocv_mean_shift_rise_constraint +ocv_mean_shift_fall_constraint +``` + +## Power analysis + +OpenSTA also supports static power analysis with the `report_power` +command. Probabilistic switching activities are propagated from the +input ports to determine switching activities for internal pins. + +```tcl +read_liberty sky130hd_tt.lib +read_verilog gcd_sky130hd.v +link_design gcd +read_sdc gcd_sky130hd.sdc +read_spef gcd_sky130hd.spef +set_power_activity -input -activity 0.1 +set_power_activity -input_port reset -activity 0 +report_power +``` + +In this example the activity for all inputs is set to `0.1`, and then +the activity for the `reset` signal is set to zero because it does not +switch during steady state operation. + +This example can be found in `examples/power.tcl`. + +Gate level simulation results can be used to get a more accurate power +estimate. For example, the Icarus Verilog simulator can be used to run +the test bench `examples/gcd_tb.v` for the gcd design in the previous +example. + +```tcl +iverilog -o gcd_tb gcd_tb.v +vvp gcd_tb +``` + +The test bench writes the VCD (Value Change Dump) file +`gcd_sky130hd.vcd` which can then be read with the `read_vcd` command. + +```tcl +read_liberty sky130hd_tt.lib +read_verilog gcd_sky130hd.v +link_design gcd +read_sdc gcd_sky130hd.sdc +read_spef gcd_sky130hd.spef +read_vcd -scope gcd_tb/gcd1 gcd_sky130hd.vcd.gz +report_power +``` + +This example can be found in `examples/power_vcd.tcl`. + +Note that in this simple example design, simulation-based activities +do not significantly change the results. diff --git a/doc/Extra.css b/doc/Extra.css new file mode 100644 index 000000000..2b777647b --- /dev/null +++ b/doc/Extra.css @@ -0,0 +1,5 @@ +/* Synopsis flags are links to the option descriptions below. */ +.md-typeset pre a { + color: var(--md-typeset-a-color); + text-decoration: underline; +} diff --git a/doc/FilterExpressions.md b/doc/FilterExpressions.md new file mode 100644 index 000000000..f2001ac03 --- /dev/null +++ b/doc/FilterExpressions.md @@ -0,0 +1,22 @@ +# Filter expressions + +The following commands support filtering returned objects by property +values: `get_cells`, `get_clocks`, `get_lib_cells`, `get_lib_pins`, +`get_libs`, `get_modes`, `get_nets`, `get_pins`, `get_ports`, +`get_scenes`, and `get_timing_edges`. + +Supported filter expressions are shown below. + +| Expression | Description | +| --- | --- | +| `property` | Return objects with `property` value equal to 1. | +| `property==value` | Return objects with `property` value equal to `value`. | +| `property=~pattern` | Return objects with `property` value that matches `pattern`. | +| `property!=value` | Return objects with `property` value not equal to `value`. | +| `property!~pattern` | Return objects with `property` value that does not match `pattern`. | +| `expr1&&expr2` | Return objects that match `expr1` and `expr2`. | +| expr1||expr2 | Return objects that match `expr1` or `expr2`. | + +Where `property` is a property supported by the `get_property` command. +If there are spaces in the expression it must be enclosed in quotes so +that it is a single argument. diff --git a/doc/OpenSTA.fodt b/doc/OpenSTA.fodt deleted file mode 100644 index 4ea0eeba6..000000000 --- a/doc/OpenSTA.fodt +++ /dev/null @@ -1,14741 +0,0 @@ - - - - Parallax STA documentationJames Cherry5302025-03-17T12:59:52.4638705382010-07-31T21:07:002026-07-14T15:27:24.184633000P123DT2H21M56SLibreOffice/26.2.4.2$MacOSX_AARCH64 LibreOffice_project/0229ac93fcf0d7cbc6376066c6f35021cef002dcPDF files: James CherryJames Cherry12.00000falsefalsefalsefalse - - - 1227342 - 0 - 30134 - 16491 - true - false - - - view2 - 6812 - 1238504 - 0 - 1227342 - 30133 - 1243831 - 0 - 1 - false - 90 - false - false - 236,209,1382,863;1;,,,; - true - true - false - false - false - - - - - 0 - true - false - false - false - true - false - true - false - - false - true - false - false - false - false - false - false - false - false - false - false - false - true - 0 - false - false - false - false - false - false - false - false - false - false - false - false - false - true - false - 933294 - true - true - true - false - false - false - false - false - false - false - true - false - true - false - true - false - 27679432 - 0 - - false - false - false - false - false - false - false - false - false - false - false - false - false - true - false - false - - true - false - true - false - true - false - false - false - false - false - false - 0 - true - false - true - false - false - false - false - 1 - false - true - false - true - high-resolution - - - en - US - - - - - - - false - true - true - - - false - true - true - false - false - true - false - false - false - false - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OpenSTA - - - Table of Contents - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Table of Contents - - Command Line Arguments1 - Example Command Scripts1 - Timing Analysis using SDF2 - Timing Analysis with Multiple Process Corners2 - Timing Analysis with Multiple Corners and Modes3 - Power Analysis3 - TCL Interpreter5 - Debugging Timing6 - No paths found6 - No path reported an endpoint7 - Commands7 - Filter Expressions84 - Variables85 - - - Command Line Arguments - The command line arguments for sta are shown below. - sta -help show help and exit -version show version and exit -no_init do not read ~/.sta -no_splash do not print the splash message -threads count|max use count threads -exit exit after reading cmd_file cmd_file source cmd_file - When OpenSTA starts up, commands are first read from the user initialization file ~/.sta if it exists. If a TCL command file cmd_file is specified on the command line, commands are read from the file and executed before entering an interactive TCL command interpreter. If -exit is specified the application exits after reading cmd_file. Use the TCL exit command to exit the application. The –threads option specifies how many parallel threads to use. Use –threads max to use one thread per processor. - Example Command Scripts - To read a design into OpenSTA use the read_liberty command to read Liberty library files. Next, read hierarchical structural Verilog files with the read_verilog command. The link_design command links the Verilog to the Liberty timing cells. Any number of Liberty and Verilog files can be read before linking the design. - Delays used for timing analysis are calculated using the Liberty timing models. If no parasitics are read only the pin capacitances of the timing models are used in delay calculation. Use the read_spef command to read parasitics from an extractor, or read_sdf to use delays calculated by an external delay calculator. - Timing constraints can be entered as TCL commands or read using the read_sdc command. - The units used by OpenSTA for all command arguments and reports are taken from the first Liberty file that is read. Use the set_cmd_units command to override the default units. Use the report_units command to see the ccmmand units. - Timing Analysis using SDF - A sample command file that reads a library and a Verilog netlist and reports timing checks is shown below. - read_liberty example1_slow.libread_verilog example1.vlink_design topread_sdf example1.sdfcreate_clock -name clk -period 10 {clk1 clk2 clk3}set_input_delay -clock clk 0 {in1 in2}report_checks - This example can be found in examples/sdf_delays.tcl. - Timing Analysis with Multiple Process Corners - An example command script using three process corners and +/-10% min/max derating is shown below. - read_liberty nangate45_slow.lib.gzread_liberty nangate45_typ.lib.gzread_liberty nangate45_fast.lib.gzread_verilog example1.link_design topset_timing_derate -early 0.9set_timing_derate -late 1.1create_clock -name clk -period 10 {clk1 clk2 clk3}set_input_delay -clock clk 0 {in1 in2}define_scene ss -liberty nangate45_slowdefine_scene tt -liberty nangate45_typdefine_scene ff -liberty nangate45_fast# report all scenesreport_checks -path_delay min_max# report typical scenereport_checks -scene tt - This example can be found in examples/multi_corner.tcl. Other examples can be found in the examples directory. - Timing Analysis with Multiple Corners and Modes - OpenSTA supports multi-corner, multi-mode analysis. Each corner/mode combination is called a “scene”. The SDC constraints in each mode describe a different operating mode, such as mission mode or scan mode. Each corner has min/max Liberty libraries and SPEF parasitics. - A mode named “default” is initially created for SDC commands. It is deleted when a mode is defined with set_mode or read_sdc -mode. Similartly, a named “default” is initially created that is deleted when define_scene is used to define a scene. - An example command script using two process corners two modes is shown below. - read_liberty asap7_small_ff.lib.gzread_liberty asap7_small_ss.lib.gzread_verilog reg1_asap7.vlink_design topread_sdc -mode mode1 mcmm2_mode1.sdcread_sdc -mode mode2 mcmm2_mode2.sdcread_spef -name reg1_ff reg1_asap7.spefread_spef -name reg1_ss reg1_asap7_ss.spefdefine_scene scene1 -mode mode1 -liberty asap7_small_ff -spef reg1_ffdefine_scene scene2 -mode mode2 -liberty asap7_small_ss -spef reg1_ssreport_checks -scenes scene1report_checks -scenes scene2report_checks -group_path_count 4 - This example can be found in examples/mcmm3.tcl.In the example show above the SDC for each mode is in defined in a separate file. Alternatively, the SDC can be defined in the command file using the set_mode command between SDC command groups. - set_mode mode1create_clock -name m1_clk -period 1000 {clk1 clk2 clk3}set_input_delay -clock m1_clk 100 {in1 in2}set_mode mode2create_clock -name m2_clk -period 500 {clk1 clk3}set_output_delay -clock m2_clk 100 out - Statistical Timing Analysis - OpenSTA also supports statistical timing analysis with Liberty Variation Format (LVF) libraries. Statistical timing uses a probability distribution to represent a delay or slew rather than a single number. - Normal and skew normal probability distributions are supported. SSTA is enabled with the sta_pocv_mode variable. - set sta_pocv_mode scalar|normal|skew_normalscalar mode is for non-SSTA analysisnormal mode uses gaussian normal distributionsskew_normal mode is for skew normal LVF moment based distributions - The target quantile of a delay probability distribution (confidence level) is set with the sta_pocv_quantile variable. - set sta_pocv_quantile <float> - The default value is 3 standard deviations, or sigma. - Use the variation field with the report_checks and report_check_types commands to see distribution parameters in timing reports. - A command file for analyzing a design with statistical timing is shown below. - read_liberty lvf_library.lib.gzread_verilog design.vlink_design topcreate_clock -period 50 clkset_input_delay -clock clk 1 {in1 in2}set sta_pocv_mode skew_normalreport_checks -fields {slew variation input_pin} -digits 3 - Startpoint: r2 (rising edge-triggered flip-flop clocked by clk)Endpoint: r3 (rising edge-triggered flip-flop clocked by clk)Path Group: clkPath Type: max Slew Delay Variation Time Description--------------------------------------------------------------------------- 0.000 0.000 0.000 clock clk (rise edge) 0.000 0.000 clock network delay (ideal) 0.000 0.000 0.000 ^ r2/CK (FDPQ1) 12.026 mean 0.017 mean_shift 0.366 std_dev 0.000 skewness 4.648 12.409 12.409 v r2/Q (FFQ1) 4.648 0.000 12.409 v u1/A (BUF1) 6.084 mean 0.007 mean_shift 0.188 std_dev 0.000 skewness 2.513 6.137 18.546 v u1/X (BUF1) 2.513 0.000 18.546 v u2/A2 (AN21) 6.447 mean 0.008 mean_shift 0.191 std_dev 0.000 skewness 2.565 6.497 25.043 v u2/X (AN21) 2.565 0.000 25.043 v r3/D (FFQ1) 25.043 data arrival time 0.000 50.000 50.000 clock clk (rise edge) 0.000 50.000 clock network delay (ideal) 0.000 50.000 clock reconvergence pessimism 50.000 ^ r3/CK (FFQ1) -9.376 40.624 library setup time 40.624 data required time--------------------------------------------------------------------------- 40.624 data required time -25.043 data arrival time--------------------------------------------------------------------------- 15.581 slack (MET) - The standard deviation for normal distributions is specified with the following liberty timing groups. - ocv_sigma_cell_riseocv_sigma_cell_fallocv_sigma_rise_transitionocv_sigma_fall_transitionocv_sigma_rise_constraintocv_sigma_fall_constraint - LVF skew normal distributions are specified with liberty groups below. - ocv_std_dev_cell_riseocv_std_dev_cell_fallocv_mean_shift_cell_riseocv_mean_shift_cell_fallocv_skewness_cell_riseocv_skewness_cell_fallocv_std_dev_rise_transitionocv_std_dev_fall_transitionocv_skewness_rise_transitionocv_skewness_fall_transitionocv_mean_shift_rise_transitionocv_mean_shift_fall_transitionocv_std_dev_rise_constraintocv_std_dev_fall_constraintocv_skewness_rise_constraintocv_skewness_fall_constraintocv_mean_shift_rise_constraintocv_mean_shift_fall_constraint - - Power Analysis - OpenSTA also supports static power analysis with the report_power command. Probabalistic switching activities are propagated from the input ports to determine switching activities for internal pins. - read_liberty sky130hd_tt.libread_verilog gcd_sky130hd.vlink_design gcdread_sdc gcd_sky130hd.sdcread_spef gcd_sky130hd.spefset_power_activity -input -activity 0.1set_power_activity -input_port reset -activity 0report_power - In this example the activity for all inputs is set to 0.1, and then the activity for the reset signal is set to zero because it does not switch during steady state operation. - Group Internal Switching Leakage Total Power Power Power Power (Watts)----------------------------------------------------------------Sequential 3.27e-04 7.87e-05 2.96e-10 4.06e-04 36.4%Combinational 2.34e-04 3.10e-04 6.95e-10 5.43e-04 48.7%Clock 4.68e-05 1.20e-04 2.30e-11 1.67e-04 15.0%Macro 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.0%Pad 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.0%----------------------------------------------------------------Total 6.07e-04 5.09e-04 1.01e-09 1.12e-03 100.0% 54.4% 45.6% 0.0% - This example can be found in examples/power.tcl. - Gate level simulation results can be used to get a more accurate power estimate. For example, the Icarus verilog simulator can be used to run the the test bench examples/gcd_tb.v for the gcd design in the previous example. - iverilog -o gcd_tb gcd_tb.vvvp gcd_tb - The test bench writes the VCD (Value Change Data) file gcd_sky130hd.vcd which can then be read with the read_vcd command. - read_liberty sky130hd_tt.libread_verilog gcd_sky130hd.vlink_design gcdread_sdc gcd_sky130hd.sdcread_spef gcd_sky130hd.spefread_vcd -scope gcd_tb/gcd1 gcd_sky130hd.vcd.gzreport_power - This example can be found in examples/power_vcd.tcl. - Note that in this simple example design simulation based activities does not significantly change the results. - TCL Interpreter - Keyword arguments to commands may be abbreviated. For example, - report_checks -unique - is equivalent to the following command. - report_checks -unique_paths_to_endpoint - The help command lists matching commands and their arguments. - > help report*report_annotated_check [-setup] [-hold] [-recovery] [-removal] [-nochange] [-width] [-period] [-max_skew] [-max_lines liness] [-list_annotated]group_path_count [-list_not_annotated] [-constant_arcs]report_annotated_delay [-cell] [-net] [-from_in_ports] [-to_out_ports] [-max_lines liness] [-list_annotated] [-list_not_annotated] [-constant_arcs]report_arrival pinreport_check_types [-violators] [-verbose] [-scene scene] [-format slack_only|end] [-max_delay] [-min_delay] [-recovery] [-removal] [-clock_gating_setup] [-clock_gating_hold] [-max_slew] [-min_slew] [-max_fanout] [-min_fanout] [-max_capacitance] [-min_capacitance [-min_pulse_width] [-min_period] [-max_skew] [-net net] [-digits digits [-no_line_splits] [> filename] [>> filename]report_checks [-from from_list|-rise_from from_list|-fall_from from_list] [-through through_list|-rise_through through_list|-fall_through through_list] [-to to_list|-rise_to to_list|-fall_to to_list] [-unconstrained] [-path_delay min|min_rise|min_fall|max|max_rise|max_fall|min_max] [-scene scene] [-group_path_count path_count] [-endpoint_path_count path_count] [-unique_paths_to_endpoint] [-slack_max slack_max] [-slack_min slack_min] [-sort_by_slack] [-path_group group_name] [-format full|full_clock|full_clock_expanded|short|end|summary]... - Many reporting commands support redirection of the output to a file much like a Unix shell. - report_checks -to out1 > path.logreport_checks -to out2 >> path.log - Debugging Timing - Here are some guidelines for debugging your design if static timing does not report any paths, or does not report the expected paths. - Debugging timing problems generally involves using the following commands to follow the propagation of arrival times from a known arrival downstream to understand why the arrival times are not propagating: - report_edgesreport_arrivalsreport_net - report_edges -from can be used to walk forward and report_edges -to to walk backward in the netlist/timing graph. report_arrivals shows the min/max rise/fall arrival times with respect to each clock that has a path to the pin. report_net shows connections to a net across hierarchy levels. - No paths found - The report_checks command only reports paths that are constrained by timing checks or SDC commands such as set_output_delay. If the design has only combinational logic (no registers or latches), there are no timing checks, so no paths are reported. Use the -unconstrained option to report_checks to see unconstrained paths. - % report_checks -unconstrained - If the design is sequential (has registers or latches) and no paths are reported, it is likely that there is a problem with the clock propagation. Check the timing at an register in the design with the report_arrivals command. - % report_arrivals r1/CP (clk ^) r 0.00:0.00 f INF:-INF (clk v) r INF:-INF f 5.00:5.00 - In this example the rising edge of the clock "clk" causes the rising arrival min:max time at 0.00, and the falling edge arrives at 5.00. Since the rising edge of the clock causes the rising edge of the register clock pin, the clock path is positive unate. - The clock path should be positive or negative unate. Something is probably wrong with the clock network if it is non-unate. A non-unate clock path will report arrivals similar to the foillowing: - % report_arrivals r1/CP (clk ^) r 0.00:0.00 f 0.00:0.00 (clk v) r 5.00:5.00 f 5.00:5.00 - Notice that each clock edge causes both rise and fall arrivals at the register clock pin. - If there are no paths to the register clock pin, nothing is printed. Use the report_edges -to command to find the gate driving the clock pin. - % report_edges -to r1/CPi1/ZN -> CP wire ^ -> ^ 0.00:0.00 v -> v 0.00:0.00 - This shows that the gate/pin i1/ZN is driving the clock pin. The report_edges -to commond can be used to walk backward or forward through the netlist one gate/net at a time. By checking the arrivals with the report_arrival command you can determine where the path is broken. - No path reported an endpoint - In order for a timing check to be reported, there must be an arrival time at the data pin (the constrained pin) as well as the timing check clock pin. If report_checks -to a register input does not report any paths, check that the input is constrained by a timing check with report_edges -to. - % report_edges -to r1/DCP -> D hold ^ -> ^ -0.04:-0.04 ^ -> v -0.03:-0.03CP -> D setup ^ -> ^ 0.09:0.0 ^ -> v 0.08:0.08in1 -> D wire ^ -> ^ 0.00:0.00 v -> v 0.00:0.00 - This reports the setup and hold checks for the D pin of r1. - Next, check the arrival times at the D and CP pins of the register with report_arrivals. - % report_arrivals r1/D (clk1 ^) r 1.00:1.00 f 1.00:1.00% report_arrivals r1/CP (clk1 ^) r 0.00:0.00 f INF:-INF (clk1 v) r INF:-INF f 5.00:5.00 - If there are no arrivals on an input port of the design, use the set_input_delay command to specify the arrival times on the port. - Commands - - - - - - all_clocks - - - - - - - The all_clocks command returns a list of all clocks that have been defined. - - - - - - all_inputs - - - [-no_clocks] - - - - - -no_clocks - - - Exclude inputs defined as clock sources. - - - - The all_inputs command returns a list of all input and bidirect ports of the current design. - - - - - - all_outputs - - - - - - - The all_outputs command returns a list of all output and bidirect ports of the design. - - - - - - - all_registers - - - [-clock clock_names][-cells | -data_pins | -clock_pins | -async_pins | ‑output_pins][-level_sensitive][-edge_triggered] - - - - - -clock clock_names - - - A list of clock names. Only registers clocked by these clocks are returned. - - - - - -cells - - - Return a list of register instances. - - - - - -data_pins - - - Return the register data pins. - - - - - -clock_pins - - - Return the register clock pins. - - - - - -async_pins - - - Return the register set/clear pins. - - - - - -output_pins - - - Return the register output pins. - - - - - -level_sensitive - - - Return level-sensitive latches. - - - - - -edge_triggered - - - Return edge-triggered registers. - - - - The all_registers command returns a list of register instances or register pins in the design. Options allow the list of registers to be restricted in various ways. The -clock keyword restrcts the registers to those that are clocked by a set of clocks. The -cells option returns the list of registers or latches (the default). The -‑data_pins, -clock_pins, -async_pins and -output_pins options cause all_registers to return a list of register pins rather than instances. - - - - - - check_setup - - - [-verbose][-unconstrained_endpoints][-multiple_clock][-no_clock][-no_input_delay][-loops][-generated_clocks][> filename][>> filename] - - - - - -verbose - - - Show offending objects rather than just error counts. - - - - - -unconstrained_endpoints - - - Check path endpoints for timing constraints (timing check or set_output_delay). - - - - - -multiple_clock - - - Check register/latch clock pins for multiple clocks. - - - - - - -no_clock - - - Check register/latch clock pins for a clock. - - - - - -no_input_delay - - - Check for inputs that do not have a set_input_delay command. - - - - - -loops - - - Check for combinational logic loops. - - - - - -generated_clocks - - - Check that generated clock source pins have been defined as clocks. - - - - The check_setup command performs sanity checks on the design. Individual checks can be performed with the keywords. If no check keywords are specified all checks are performed. Checks that fail are reported as warnings. If no checks fail nothing is reported. The command returns 1 if there are no warnings for use in scripts. - - - - - - connect_pin - - - netport|pin - - - - - net - - - A net to add connections to. - - - - - port - - - A port to connect to net. - - - - - Pin - - - A pin to connect to net. - - - - The connect_pin command connects a port or instance pin to a net. - - - - - - create_clock - - - -period period[-name clock_name][-waveform edge_list][-add][pin_list] - - - - - -period period - - - The clock period. - - - - - -name clock_name - - - The name of the clock. - - - - - -waveform edge_list - - - A list of edge rise and fall time. - - - - - -add - - - Add this clock to the clocks on pin_list. - - - - - pin_list - - - A list of pins driven by the clock. - - - - The create_clock command defines the waveform of a clock used by the design. - If no pin_list is specified the clock is virtual. A virtual clock can be refered to by name in input arrival and departure time commands but is not attached to any pins in the design. - If no clock name is specified the name of the first pin is used as the clock name. - If a wavform is not specified the clock rises at zero and falls at half the clock period. The waveform is a list with time the clock rises as the first element and the time it falls as the second element. - If a clock is already defined on a pin the clock is redefined using the new clock parameters. If multiple clocks drive the same pin, use the -add option to prevent the existing definition from being overwritten. - The following command creates a clock with a period of 10 time units that rises at time 0 and falls at 5 time units on the pin named clk1. - create_clock -period 10 clk1 - The following command creates a clock with a period of 10 time units that is high at time zero, falls at time 2 and rises at time 8. The clock drives three pins named clk1, clk2, and clk3. - create_clock -period 10 -waveform {8 2} -name clk {clk1 clk2 clk3} - - - - - - create_generated_clock - - - [-name clock_name]-source master_pin[-master_clock master_clock][-divide_by divisor][-multiply_by multiplier][-duty_cycle duty_cycle][-invert][-edges edge_list][-edge_shift shift_list][-add]pin_list - - - - - -name clock_name - - - The name of the generated clock. - - - - - -source master_pin - - - A pin or port in the fanout of the master clock that is the source of the generated clock. - - - - - -master_clock master_clock - - - Use -master_clock to specify which source clock to use when multiple clocks are present on master_pin. - - - - - -divide_by divisor - - - Divide the master clock period by divisor. - - - - - -multiply_by multiplier - - - Multiply the master clock period by multiplier. - - - - - -duty_cycle duty_cycle - - - The percent of the period that the generated clock is high (between 0 and 100). - - - - - -invert - - - Invert the master clock. - - - - - - -edges edge_list - - - List of master clock edges to use in the generated clock. Edges are numbered from 1. edge_list must be 3 edges long. - - - - - -edge_shift shift_list - - - Not supported. - - - - - -add - - - Add this clock to the existing clocks on pin_list. - - - - - pin_list - - - A list of pins driven by the generated clock. - - - - The create_generated_clock command is used to generate a clock from an existing clock definition. It is used to model clock generation circuits such as clock dividers and phase locked loops. - The -divide_by, -multiply_by and -edges arguments are mutually exclusive. - The -multiply_by option is used to generate a higher frequency clock from the source clock. The period of the generated clock is divided by multiplier. The clock multiplier must be a positive integer. If a duty cycle is specified the generated clock rises at zero and falls at period * duty_cycle / 100. If no duty cycle is specified the source clock edge times are divided by multiplier. - The -divide_by option is used to generate a lower frequency clock from the source clock. The clock divisor must be a positive integer. If the clock divisor is a power of two the source clock period is multiplied by divisor, the clock rise time is the same as the source clock, and the clock fall edge is one half period later. If the clock divisor is not a power of two the source clock waveform edge times are multiplied by divisor. - The -edges option forms the generated clock waveform by selecting edges from the source clock waveform. - If the -invert option is specified the waveform derived above is inverted. - If a clock is already defined on a pin the clock is redefined using the new clock parameters. If multiple clocks drive the same pin, use the -add option to prevent the existing definition from being overwritten. - In the example show below generates a clock named gclk1 on register output pin r1/Q by dividing it by four. - create_clock -period 10 -waveform {1 8} clk1create_generated_clock -name gclk1 -source clk1 -divide_by 4 r1/Q - The generated clock has a period of 40, rises at time 1 and falls at time 21. - In the example shown below the duty cycle is used to define the derived clock waveform. - create_generated_clock -name gclk1 -source clk1 -duty_cycle 50 \ -multiply_by 2 r1/Q - The generated clock has a period of 5, rises at time .5 and falls at time 3. - In the example shown below the first, third and fifth source clock edges are used to define the derived clock waveform. - create_generated_clock -name gclk1 -source clk1 -edges {1 3 5} r1/Q - The generated clock has a period of 20, rises at time 1 and falls at time 11. - - - - - - create_voltage_area - - - [-name name][-coordinate coordinates][-guard_band_x guard_x][-guard_band_y guard_y]cells - - - - This command is parsed and ignored by timing analysis. - - - - - - current_design - - - [design] - - - - - - - - - - current_instance - - - [instance] - - - - - instance - - - Not supported. - - - - - - - - - - define_scene - - - -mode mode_name -liberty liberty_files|-liberty_min liberty_min_files -liberty_max liberty_max_files-spef spef_file| -spef_min spef_min_file -spef_max spef_max_file - - - - - mode_name - - - The SDC mode to use. - - - - - liberty_files - - - List of Liberty files to use. - - - - - spef_file - - - The SPEF parasitics file to use. - - - - The define_scene command defines a scene for a mode (SDC), liberty files and spef parasitics. Define scenes after reading Liberty libraries and SPEF parasitics.Liberty files are specifiec with the name of the liberty library or the filename of the liberty file. If a filename is used, it must be the same as the filename used to read the library with read_liberty.. - Use get_scenes to find defined scenes. - - - - - - - delete_clock - - - [-all] clocks - - - - - clocks - - - A list of clocks to remove. - - - - - - - - - - delete_from_list - - - list objects - - - - - list - - - A list of objects. - - - - - objects - - - A list of objects to delete from list. - - - - - - - - - - delete_generated_clock - - - [-all] clocks - - - - - clocks - - - A list of generated clocks to remove. - - - - - - - - - - delete_instance - - - instance - - - - - instance - - - Instance to delete. - - - - The network editing command delete_instance removes an instance from the design. - - - - - - delete_net - - - net - - - - - net - - - Net to delete. - - - - The network editing command delete_net removes a net from the design. - - - - - - disconnect_pin - - - netport | pin | -all - - - - - net - - - The net to disconnect pins from. - - - - - port - - - A port to connect to net. - - - - - pin - - - A pin to connect to net. - - - - - - -all - - - Disconnect all pins from the net. - - - - Disconnects a port or pin from a net. Parasitics connected to the pin are deleted. - - - - - - elapsed_run_time - - - - - - - Returns the total clock run time in seconds as a float. - - - - - - find_timing_paths - - - [-from from_list |-rise_from from_list |-fall_from from_list][-through through_list |-rise_through through_list |-fall_through through_list][-to to_list |-rise_to to_list |-fall_to to_list][-unconstrained][-path_delay min|min_rise|min_fall |max|max_rise|max_fall |min_max][-group_path_count path_count][-endpoint_path_count endpoint_path_count][-unique_paths_to_endpoint][-scene scene][-slack_max max_slack][-slack_min min_slack][-sort_by_slack][-path_group groups] - - - - - -from from_list - - - Return paths from a list of clocks, instances, ports, register clock pins, or latch data pins. - - - - - -rise_from from_list - - - Return paths from the rising edge of clocks, instances, ports, register clock pins, or latch data pins. - - - - - -fall_from from_list - - - Return paths from the falling edge of clocks, instances, ports, register clock pins, or latch data pins. - - - - - -through through_list - - - Return paths through a list of instances, pins or nets. - - - - - -rise_through through_list - - - Return rising paths through a list of instances, pins or nets. - - - - - - -fall_through through_list - - - Return falling paths through a list of instances, pins or nets. - - - - - -to to_list - - - Return paths to a list of clocks, instances, ports or pins. - - - - - -rise_to to_list - - - Return rising paths to a list of clocks, instances, ports or pins. - - - - - -fall_to to_list - - - Return falling paths to a list of clocks, instances, ports or pins. - - - - - -unconstrained - - - Report unconstrained paths also. - - - - - -path_delay min - - - Return min path (hold) checks. - - - - - -path_delay min_rise - - - Return min path (hold) checks for rising endpoints. - - - - - -path_delay min_fall - - - Return min path (hold) checks for falling endpoints. - - - - - -path_delay max - - - Return max path (setup) checks. - - - - - -path_delay max_rise - - - Return max path (setup) checks for rising endpoints. - - - - - -path_delay max_fall - - - Return max path (setup) checks for falling endpoints. - - - - - -path_delay min_max - - - Return max and max path (setup and hold) checks. - - - - - -group_path_count path_count - - - The number of paths to return in each path group. - - - - - -endpoint_path_count endpoint_path_count - - - The number of paths to return for each endpoint. - - - - - ‑unique_paths_to_endpoint - - - Return multiple paths to an endpoint that traverse different pins without showing multiple paths with different rise/fall transitions. - - - - - -scene scene - - - Return paths for one process corner. - - - - - -slack_max max_slack - - - Return paths with slack less than max_slack. - - - - - -slack_min min_slack - - - Return paths with slack greater than min_slack. - - - - - -sort_by_slack - - - Sort paths by slack rather than slack within path groups. - - - - - -path_group groups - - - Return paths in path groups. Paths in all groups are returned if this option is not specified. - - - - The find_timing_paths command returns a list of path objects for scripting. Use the get_property function to access properties of the paths. - - - - - - get_cells - - - [-hierarchical][-hsc separator][-filter expr][-regexp][-nocase][-quiet][-of_objects objects][patterns] - - - - - -hierarchical - - - Searches hierarchy levels below the current instance for matches. - - - - - -hsc separator - - - Character to use to separate hierarchical instance names in patterns. - - - - - -filter expr - - - A filter expression of the form property==value”where property is a property supported by the get_property command. See the section “Filter Expressions” for additional forms. - - - - - -regexp - - - Use regular expression matching instead of glob pattern matching. - - - - - -nocase - - - Ignore case when matching. Only valid with –regexp. - - - - - -quiet - - - Do not warn if no matches are found. - - - - - -of_objects objects - - - The name of a pin or net, a list of pins returned by get_pins, or a list of nets returned by get_nets. The –hierarchical option cannot be used with ‑of_objects. - - - - - patterns - - - A list of instance name patterns. - - - - The get_cells command returns a list of all cell instances that match patterns. - - - - - - get_clocks - - - [-regexp][-nocase][-filter expr][-quiet]patterns - - - - - -regexp - - - Use regular expression matching instead of glob pattern matching. - - - - - -nocase - - - Ignore case when matching. Only valid with –regexp. - - - - - - -filter expr - - - A filter expression of the form property==value”where property is a property supported by the get_property command. See the section “Filter Expressions” for additional forms. - - - - - -quiet - - - Do not warn if no matches are found. - - - - - patterns - - - A list of clock name patterns. - - - - The get_clocks command returns a list of all clocks that have been defined. - - - - - - get_fanin - - - -to sink_list[-flat][-only_cells][-startpoints_only][-levels level_count][-pin_levels pin_count][-trace_arcs timing|enabled|all] - - - - - -to sink_list - - - List of pins, ports, or nets to find the fanin of. For nets, the fanin of driver pins on the nets are returned. - - - - - -flat - - - With –flat pins in the fanin at any hierarchy level are returned. Without ‑flat only pins at the same hierarchy level as the sinks are returned. - - - - - -only_cells - - - Return the instances connected to the pins in the fanin. - - - - - -startpoints_only - - - Only return pins that are startpoints. - - - - - -level level_count - - - Only return pins within level_count instance traversals. - - - - - -pin_levels pin_count - - - Only return pins within pin_count pin traversals. - - - - - -trace_arcs timing - - - Only trace through timing arcs that are not disabled. - - - - - -trace_arcs enabled - - - Only trace through timing arcs that are not disabled. - - - - - -trace_arcs all - - - Trace through all arcs, including disabled ones. - - - - The get_fanin command returns traverses the design from sink_list pins, ports or nets backwards and return the fanin pins or instances. - - - - - - - get_fanout - - - -from source_list[-flat][-only_cells][-endpoints_only][-levels level_count][-pin_levels pin_count][-trace_arcs timing|enabled|all] - - - - - -from source_list - - - List of pins, ports, or nets to find the fanout of. For nets, the fanout of load pins on the nets are returned. - - - - - -flat - - - With –flat pins in the fanin at any hierarchy level are returned. Without ‑flat only pins at the same hierarchy level as the sinks are returned. - - - - - -only_cells - - - Return the instances connected to the pins in the fanout. - - - - - -endpoints_only - - - Only return pins that are endpoints. - - - - - -level level_count - - - Only return pins within level_count instance traversals. - - - - - -pin_levels pin_count - - - Only return pins within pin_count pin traversals. - - - - - -trace_arcs timing - - - Only trace through timing arcs that are not disabled. - - - - - -trace_arcs enabled - - - Only trace through timing arcs that are not disabled. - - - - - -trace_arcs all - - - Trace through all arcs, including disabled ones. - - - - The get_fanout command returns traverses the design from source_list pins, ports or nets backwards and return the fanout pins or instances. - - - - - - get_full_name - - - object - - - - - object - - - A library, cell, port, instance, pin or timing arc object. - - - - Return the name of object. Equivalent to [get_property object full_name]. - - - - - - - get_lib_cells - - - [-of_objects objects][-hsc separator][-filter expr][-regexp][-nocase][-quiet]patterns - - - - - -of_objects objects - - - A list of instance objects. - - - - - -hsc separator - - - Character that separates the library name and cell name in patterns. Defaults to ‘/’. - - - - - -filter expr - - - A filter expression of the form property==value”where property is a property supported by the get_property command. See the section “Filter Expressions” for additional forms. - - - - - -regexp - - - Use regular expression matching instead of glob pattern matching. - - - - - -nocase - - - Ignore case when matching. Only valid with –regexp. - - - - - -quiet - - - Do not warn if no matches are found. - - - - - patterns - - - A list of library cell name patterns of the form library_name/cell_name. - - - - The get_lib_cells command returns a list of library cells that match pattern. The library name can be prepended to the cell name pattern with the separator character, which defaults to hierarchy_separator. - - - - - - get_lib_pins - - - [-of_objects objects][-hsc separator][-filter expr][-regexp][-nocase][-quiet]patterns - - - - - -of_objects objects - - - A list of library cell objects. - - - - - -hsc separator - - - Character that separates the library name, cell name and port name in pattern. Defaults to ‘/’. - - - - - - -filter expr - - - A filter expression of the form property==value”where property is a property supported by the get_property command. See the section “Filter Expressions” for additional forms. - - - - - -regexp - - - Use regular expression matching instead of glob pattern matching. - - - - - -nocase - - - Ignore case when matching. Only valid with –regexp. - - - - - -quiet - - - Do not warn if no matches are found. - - - - - patterns - - - A list of library port name patterns of the form library_name/cell_name/port_name. - - - - The get_lib_pins command returns a list of library ports that match pattern. Use separator to separate the library and cell name patterns from the port name in pattern. - - - - - - get_libs - - - [-filter expr][-regexp][-nocase][-quiet]patterns - - - - - -filter expr - - - A filter expression of the form property==value”where property is a property supported by the get_property command. See the section “Filter Expressions” for additional forms. - - - - - -regexp - - - Use regular expression matching instead of glob pattern matching. - - - - - -nocase - - - Ignore case when matching. Only valid with –regexp. - - - - - -quiet - - - Do not warn if no matches are found. - - - - - patterns - - - A list of library name patterns. - - - - The get_libs command returns a list of clocks that match patterns. - - - - - - - get_nets - - - [-hierarchical][-hsc separator][-filter expr][-regexp][-nocase][-quiet][-of_objects objects][patterns] - - - - - -hierarchical - - - Searches hierarchy levels below the current instance for matches. - - - - - -hsc separator - - - Character that separates the library name, cell name and port name in pattern. Defaults to ‘/’. - - - - - -filter expr - - - A filter expression of the form property==value”where property is a property supported by the get_property command. See the section “Filter Expressions” for additional forms. - - - - - -regexp - - - Use regular expression matching instead of glob pattern matching. - - - - - -nocase - - - Ignore case when matching. Only valid with –regexp. - - - - - -quiet - - - Do not warn if no matches are found. - - - - - -of_objects objects - - - The name of a pin or instance, a list of pins returned by get_pins, or a list of instances returned by get_cells. The –hierarchical option cannot be used with –of_objects. - - - - - patterns - - - A list of net name patterns. - - - - The get_nets command returns a list of all nets that match patterns. - - - - - - get_name - - - object - - - - - object - - - A library, cell, port, instance, pin or timing arc object. - - - - Return the name of object. Equivalent to [get_property object name]. - - - - - - - get_pins - - - [-hierarchical][-hsc separator][-filter expr][-regexp][-nocase][-quiet][-of_objects objects][patterns] - - - - - -hierarchical - - - Searches hierarchy levels below the current instance for matches. - - - - - -hsc separator - - - Character that separates the library name, cell name and port name in pattern. Defaults to ‘/’. - - - - - -filter expr - - - A filter expression of the form property==value”where property is a property supported by the get_property command. See the section “Filter Expressions” for additional forms. - - - - - -nocase - - - Ignore case when matching. Only valid with –regexp. - - - - - -quiet - - - Do not warn if no matches are found. - - - - - -of_objects objects - - - The name of a net or instance, a list of nets returned by get_nets, or a list of instances returned by get_cells. The –hierarchical option cannot be used with –of_objects. - - - - - patterns - - - A list of pin name patterns. - - - - The get_pins command returns a list of all instance pins that match patterns. - A useful idiom to find the driver pin for a net is the following. - get_pins -of_objects [get_net net_name] -filter “direction==output” - - - - - - get_ports - - - [-filter expr][-regexp][-nocase][-quiet][-of_objects objects][patterns] - - - - - - -filter expr - - - A filter expression of the form property==value”where property is a property supported by the get_property command. See the section “Filter Expressions” for additional forms. - - - - - -regexp - - - Use regular expression matching instead of glob pattern matching. - - - - - -nocase - - - Ignore case when matching. Only valid with –regexp. - - - - - -quiet - - - Do not warn if no matches are found. - - - - - -of_objects objects - - - The name of net or a list of nets returned by get_nets. - - - - - patterns - - - A list of port name patterns. - - - - The get_ports command returns a list of all top level ports that match patterns. - - - - - - get_property - - - [-object_type object_type]objectproperty - - - - - -object_type object_type - - - The type of object when it is specified as a name.cell|pin|net|port|clock|library|library_cell|library_pin|timing_arc - - - - - object - - - An object returned by get_cells, get_pins, get_nets, get_ports, get_clocks, get_libs, get_lib_cells, get_lib_pins, or get_timing_arcs, or object name. ‑object_type is required if object is a name. - - - - - property - - - A property name. - - - - The properties for different objects types are shown below. - cell (SDC lib_cell) - base_namefilenamefull_namelibraryname - clock - full_nameis_generatedis_propagatedis_virtualnameperiodsources - edge - delay_max_falldelay_min_falldelay_max_risedelay_min_risefull_namefrom_pinsenseto_pin - instance (SDC cell) - cellfull_nameis_bufferis_clock_gateis_hierarchicalis_inverteris_macrois_memoryliberty_cellnameref_name - liberty_cell (SDC lib_cell) - areabase_namedont_usefilenamefull_nameis_bufferis_inverteris_memorylibraryname - liberty_port (SDC lib_pin) - capacitancedirectiondrive_resistancedrive_resistance_max_falldrive_resistance_max_risedrive_resistance_min_falldrive_resistance_min_risefull_nameintrinsic_delayintrinsic_delay_max_fallintrinsic_delay_max_riseintrinsic_delay_min_fallintrinsic_delay_min_riseis_register_clocklib_cellname - library - filename (Liberty library only)namefull_name - net - full_namename - path (PathEnd) - endpointendpoint_clockendpoint_clock_pinslackstartpointstartpoint_clockpoints - pin - activity (activity in transitions per second, duty cycle, origin)origin is one ofglobalset_power_activity -globalinputset_power_activity -inputuserset_power_activity -input_ports -pinsvcdread_vcdsaifread_saifpropagatedpropagated from upstream activitiesclockSDC create_clock or create_generated_clockconstantconstant pins propagated from verilog tie high/low, set_case_analysis, set_logic_one/zero/dc - slew_max_fallslew_max_riseslew_min_fallslew_min_riseclocksclock_domainsdirectionfull_nameis_hierarchicalis_portis_register_clocklib_pin_namenameslack_maxslack_max_fallslack_max_riseslack_minslack_min_fallslack_min_rise - port - activityslew_max_fallslew_max_riseslew_min_fallslew_min_risedirectionfull_nameliberty_portnameslack_maxslack_max_fallslack_max_riseslack_minslack_min_fallslack_min_rise - point (PathRef) - arrivalpinrequiredslack - - - - - - get_scenes - - - [-mode mode_name]scene_name - - - - - mode_name - - - Get the scenes for mode_name. - - - - - scene_name - - - A scene name pattern. - - - - The get_scenes command is used to find the scenes matching a pattern or that use an SDC mode. - - - - - - get_timing_edges - - - [-from from_pins][-to to_pins][-of_objects objects][-filter expr][patterns] - - - - - -from from_pin - - - A list of pins. - - - - - -to to_pin - - - A list of pins. - - - - - -of_objects objects - - - A list of instances or library cells. The –from and -to options cannot be used with –of_objects. - - - - - -filter expr - - - A filter expression of the form property==value”where property is a property supported by the get_property command. See the section “Filter Expressions” for additional forms. - - - - The get_timing_edges command returns a list of timing edges (arcs) to, from or between pins. The result can be passed to get_property or set_disable_timing. - - - - - - - group_path - - - -name group_name[-weight weight][-critical_range range][-from from_list |-rise_from from_list |-fall_from from_list][-through through_list][-rise_through through_list][-fall_through through_list][-to to_list |-rise_to to_list |-fall_to to_list][-default] - - - - - -name group_name - - - The name of the path group. - - - - - -weight weight - - - Not supported. - - - - - -critical_range range - - - Not supported. - - - - - -from from_list - - - Group paths from a list of clocks, instances, ports, register clock pins, or latch data pins. - - - - - -rise_from from_list - - - Group paths from the rising edge of clocks, instances, ports, register clock pins, or latch data pins. - - - - - -fall_from from_list - - - Group paths from the falling edge of clocks, instances, ports, register clock pins, or latch data pins. - - - - - -through through_list - - - Group paths through a list of instances, pins or nets. - - - - - -rise_through through_list - - - Group rising paths through a list of instances, pins or nets. - - - - - -fall_through through_list - - - Group falling paths through a list of instances, pins or nets. - - - - - -to to_list - - - Group paths to a list of clocks, instances, ports or pins. - - - - - -rise_to to_list - - - Group rising paths to a list of clocks, instances, ports or pins. - - - - - -fall_to to_list - - - Group falling paths to a list of clocks, instances, port-s or pins. - - - - - -default - - - Restore the paths in the path group -from/-to/-through/-to to their default path group. - - - - The group_path command is used to group paths reported by the report_checks command. See set_false_path for a description of allowed from_list, through_list and to_list objects. - - - - - - include - - - [-echo|-e][-verbose|-v]filename[> log_filename][>> log_filename] - - - - - -echo|-e - - - Print each command before evaluating it. - - - - - -verbose|-v - - - Print each command before evaluating it as well as the result it returns. - - - - - filename - - - The name of the file containing commands to read. - - - - - > log_filename - - - Redirect command output to log_filename. - - - - - >> log_filename - - - Redirect command output and append log_filename. - - - - Read STA/SDC/Tcl commands from filename. - The include command stops and reports any errors encountered while reading a file unless sta_continue_on_error is 1. - - - - - - link_design - - - [-no_black_boxes][cell_name] - - - - - -no_black_boxes - - - Do not make empty “black box” cells for instances that reference undefined cells. - - - - - cell_name - - - The top level module/cell name of the design hierarchy to link. - - - - Link (elaborate, flatten) the the top level cell cell_name. The design must be linked after reading netlist and library files. The default value of cell_name is the current design. - The linker creates empty "block box" cells for instances the reference undefined cells when the variable link_create_black_boxes is true. When link_create_black_boxes is false an error is reported and the link fails. - The link_design command returns 1 if the link succeeds and 0 if it fails. - - - - - - make_instance - - - inst_pathlib_cell - - - - - inst_path - - - A hierarchical instance name. - - - - - - lib_cell - - - The library cell of the new instance. - - - - The make_instance command makes an instance of library cell lib_cell. - - - - - - make_net - - - net_name_list - - - - - net_name_list - - - A list of net names. - - - - Creates a net for each hierarchical net name. - - - - - - read_liberty - - - [-corner corner][-min][-max][-infer_latches]filename - - - - - -corner corner - - - Use the library for process corner corner delay calculation. - - - - - -min - - - Use library for min delay calculation. - - - - - -max - - - Use library for max delay calculation. - - - - - filename - - - The liberty file name to read. - - - - The read_liberty command reads a Liberty format library file. The first library that is read sets the units used by SDC/TCL commands and reporting. The include_file attribute is supported. - Some Liberty libraries do not include latch groups for cells that are describe transparent latches. In that situation the -infer_latches command flag can be used to infer the latches. The timing arcs required for a latch to be inferred should look like the following: - cell (infered_latch) { pin(D) { direction : input ; timing () { related_pin : "E" ; timing_type : setup_falling ; } timing () { related_pin : "E" ; timing_type : hold_falling ; } } pin(E) { direction : input; } pin(Q) { direction : output ; timing () { related_pin : "D" ; } timing () { related_pin : "E" ; timing_type : rising_edge ; } }} - In this example a positive level-sensitive latch is inferred. - Files compressed with gzip are automatically uncompressed. - - - - - - read_saif - - - [-scope scope]filename - - - - - scope - - - The SAIF scope of the current design to extract simulation data. Typically the test bench name and design under test instance name. Scope levels are separated with ‘/’. - - - - - filename - - - The name of the SAIF file to read. - - - - The read_saif command reads a SAIF (Switching Activity Interchange Format) file from a Verilog simulation and extracts pin activities and duty cycles for use in power estimation. Files compressed with gzip are supported. Annotated activities are propagated to the fanout of the annotated pins. - - - - - - - read_sdc - - - [-mode mode_name][-echo]filename - - - - - mode_name - - - Mode for the SDC commands in the file. - - - - - -echo - - - Print each command before evaluating it. - - - - - filename - - - SDC command file. - - - - Read SDC commands from filename. - If the mode does not exist it is created. Multiple SDC files can append commands to a mode by using the -mode_name argument for each one. If no -mode arguement is is used the commands are added to the current mode. - The read_sdc command stops and reports any errors encountered while reading a file unless sta_continue_on_error is 1. - Files compressed with gzip are automatically uncompressed. - - - - - - read_sdf - - - [-scene scene][-unescaped_dividers]filename - - - - - scene - - - Scene delays to annotate. - - - - - -unescaped_dividers - - - With this option path names in the SDF do not have to escape hierarchy dividers when the path name is escaped. For example, the escaped Verilog name "\inst1/inst2 " can be referenced as "inst1/inst2". The correct SDF name is "inst1\/inst2", since the divider does not represent a change in hierarchy in this case. - - - - - filename - - - The name of the SDF file to read. - - - - Read SDF delays from a file. The min and max values in the SDF tuples are used to annotate the delays for corner. The typical values in the SDF tuples are ignored. If multiple scenes are defined -scene must be specified. SDC annotation for mcmm analysis must follow the scene definitions. - Files compressed with gzip are automatically uncompressed. - INCREMENT is supported as an alias for INCREMENTAL. - The following SDF statements are not supported. - PORTINSTANCE wildcards - - - - - - read_spef - - - [-name name][-keep_capacitive_coupling][-coupling_reduction_factor factor][-reduce][-path path]filename - - - - - name - - - The name of the SPEF parasitics to use for defining scenes. The default is the base name of filename. - - - - - path - - - Hierarchical block instance path to annotate with parasitics. - - - - - ‑keep_capacitive_coupling - - - Keep coupling capacitors in parasitic networks rather than converting them to grounded capacitors. - - - - - ‑coupling_reduction_factorfactor - - - Factor to multiply coupling capacitance by when reducing parasitic networks. The default value is 1.0. - - - - - filename - - - The name of the parasitics file to read. - - - - The read_spef command reads a file of net parasitics in SPEF format. Use the report_parasitic_annotation command to check for nets that are not annotated. - Files compressed with gzip are automatically uncompressed. - Separate min/max parasitics can be annotated for each scene mode/corner. - read_spef -name min spef1read_spef -name max spef2define_scene -mode mode1 -spef_min min -spef_max max - Coupling capacitors are multiplied by the –coupling_reduction_factor when a parasitic network is reduced. - The following SPEF constructs are ignored. - *DESIGN_FLOW (all values are ignored)*S slews*D driving cell*I pin capacitances (library cell capacitances are used instead)*Q r_net load poles*K r_net load residues - If the SPEF file contains triplet values the first value is used. - Parasitic networks (DSPEF) can be annotated on hierarchical blocks using the -path argument to specify the instance path to the block. Parasitic networks in the higher level netlist are stitched together at the hierarchical pins of the blocks. - - - - - - read_vcd - - - [-scope scope][-mode mode_name]filename - - - - - scope - - - The VCD scope of the current design to extract simulation data. Typically the test bench name and design under test instance name. Scope levels are separated with ‘/’. - - - - - mode_name - - - Mode to annotate activities. - - - - - filename - - - The name of the VCD file to read. - - - - The read_vcd command reads a VCD (Value Change Dump) file from a Verilog simulation and extracts pin activities and duty cycles for use in power estimation. Files compressed with gzip are supported. Annotated activities are propagated to the fanout of the annotated pins. - - - - - - read_verilog - - - filename - - - - - filename - - - The name of the verilog file to read. - - - - The read_verilog command reads a gate level verilog netlist. After all verilog netlist and Liberty libraries are read the design must be linked with the link_design command. - Verilog 2001 module port declaratations are supported. An example is shown below. - module top (input in1, in2, clk1, clk2, clk3, output out); - Files compressed with gzip are automatically uncompressed. - - - - - - replace_cell - - - instance_listreplacement_cell - - - - - - instance_list - - - A list of instances to swap the cell. - - - - - replacement_cell - - - The replacement lib cell. - - - - The replace_cell command changes the cell of an instance. The replacement cell must have the same port list (number, name, and order) as the instance's existing cell for the replacement to be successful. - - - - - - replace_activity_annotation - - - [-report_unannotated][-report_annotated] - - - - - -report_unannotated - - - Report unannotated pins. - - - - - -report_unannotated - - - Report annotated pins. - - - - Report a summary of pins that are annotated by read_vcd, read_saif or set_power_activity. Sequential internal pins and hierarchical pins are ignored. - - - - - - report_annotated_check - - - [-setup][-hold][-recovery][-removal][-nochange][-width][-period][-max_skew][-max_line lines][-report_annotated][-report_unannotated][-constant_arcs] - - - - - -setup - - - Report annotated setup checks. - - - - - -hold - - - Report annotated hold checks. - - - - - -recovery - - - Report annotated recovery checks. - - - - - -removal - - - Report annotated removal checks. - - - - - -nochange - - - Report annotated nochange checks. - - - - - -width - - - Report annotated width checks. - - - - - -period - - - Report annotated period checks. - - - - - -max_skew - - - Report annotated max skew checks. - - - - - - -max_line lines - - - Maximum number of lines listed by the report_annotated and ‑report_unannotated options. - - - - - -report_annotated - - - Report annotated timing arcs. - - - - - -report_unannotated - - - Report unannotated timing arcs. - - - - - -constant_arcs - - - Report separate annotation counts for arcs disabled by logic constants (set_logic_one, set_logic_zero). - - - - The report_annotated_check command reports a summary of SDF timing check annotation. The -report_annotated and report_annotated options can be used to list arcs that are annotated or not annotated. - - - - - - report_annotated_delay - - - [-cell][-net][-from_in_ports][-to_out_ports][-max_lines lines][-report_annotated][-report_unannotated][-constant_arcs] - - - - - -cell - - - Report annotated cell delays. - - - - - -net - - - Report annotated internal net delays. - - - - - -from_in_ports - - - Report annotated delays from input ports. - - - - - -to_out_ports - - - Report annotated delays to output ports. - - - - - -max_lines lines - - - Maximum number of lines listed by the report_annotated and ‑report_unannotated options. - - - - - -report_annotated - - - Report annotated timing arcs. - - - - - -report_unannotated - - - Report unannotated timing arcs. - - - - - -constant_arcs - - - Report separate annotation counts for arcs disabled by logic constants (set_logic_one, set_logic_zero). - - - - The report_annotated_delay command reports a summary of SDF delay annotation. Without the ‑from_in_ports and –to_out_ports options arcs to and from top level ports are not reported. The ‑report_annotated and report_unannotated options can be used to list arcs that are annotated or not annotated. - - - - - - - report_checks - - - [-from from_list |-rise_from from_list |-fall_from from_list][-through through_list |-rise_through through_list |-fall_through through_list][-to to_list |-rise_to to_list |-fall_to to_list][-unconstrained][-path_delay min|min_rise|min_fall |max|max_rise|max_fall |min_max][-group_path_count path_count][-endpoint_path_count endpoint_path_count][-unique_paths_to_endpoint][-unique_edges_to_endpoint][-scenes scenes][-slack_max max_slack][-slack_min min_slack][-sort_by_slack][-path_group groups][-format end|full|short|summary |full_clock|full_clock_expanded |json][-fields fields][-digits digits][-no_line_split][> filename][>> filename] - - - - - -from from_list - - - Report paths from a list of clocks, instances, ports, register clock pins, or latch data pins. - - - - - -rise_from from_list - - - Report paths from the rising edge of clocks, instances, ports, register clock pins, or latch data pins. - - - - - -fall_from from_list - - - Report paths from the falling edge of clocks, instances, ports, register clock pins, or latch data pins. - - - - - -through through_list - - - Report paths through a list of instances, pins or nets. - - - - - -rise_through through_list - - - Report rising paths through a list of instances, pins or nets. - - - - - - -fall_through through_list - - - Report falling paths through a list of instances, pins or nets. - - - - - -to to_list - - - Report paths to a list of clocks, instances, ports or pins. - - - - - -rise_to to_list - - - Report rising paths to a list of clocks, instances, ports or pins. - - - - - -fall_to to_list - - - Report falling paths to a list of clocks, instances, ports or pins. - - - - - -unconstrained - - - Report unconstrained paths also. The unconstrained path group is not reported without this option. - - - - - -path_delay min - - - Report min path (hold) checks. - - - - - -path_delay min_rise - - - Report min path (hold) checks for rising endpoints. - - - - - -path_delay min_fall - - - Report min path (hold) checks for falling endpoints. - - - - - -path_delay max - - - Report max path (setup) checks. - - - - - -path_delay max_rise - - - Report max path (setup) checks for rising endpoints. - - - - - -path_delay max_fall - - - Report max path (setup) checks for falling endpoints. - - - - - -path_delay min_max - - - Report max and max path (setup and hold) checks. - - - - - -group_path_count path_count - - - The number of paths to report in each path group. The default is 1. - - - - - -endpoint_path_count endpoint_path_count - - - The number of paths to report for each endpoint. The default is 1. - - - - - ‑unique_paths_to_endpoint - - - When multiple paths to an endpoint are specified with ‑endpoint_path_count, many of the paths may differ only in the rise/fall edges of the pins in the paths. With this option only the worst path through the set of pins is reported. - - - - - ‑unique_edges_to_endpoint - - - When multiple paths to an endpoint are specified with ‑endpoint_path_count, conditional timing arcs result in paths that through the same pins and rise/fall edges. With this option only the worst path through the set of pins and rise/fall edges is reported. - - - - - scenes - - - Report paths for one process corner. The default is to report paths for all process corners. - - - - - - max_slack - - - Only report paths with less slack than max_slack. - - - - - min_slack - - - Only report paths with more slack than min_slack. - - - - - -sort_by_slack - - - Sort paths by slack rather than slack grouped by path group. - - - - - groups - - - List of path groups to report. The default is to report all path groups. - - - - - -format end - - - Report path ends in one line with delay, required time and slack. - - - - - -format full - - - Report path start and end points and the path. This is the default path type. - - - - - -format full_clock - - - Report path start and end points, the path, and the source and and target clock paths. - - - - - -format full_clock_expanded - - - Report path start and end points, the path, and the source and and target clock paths. If the clock is generated and propagated, the path from the clock source pin is also reported. - - - - - -format short - - - Report only path start and end points. - - - - - -format summary - - - Report only path ends with delay. - - - - - -format json - - - Report in json format. -fields is ignored. - - - - - fields - - - List of capacitance|slew|input_pins|hierarchical_pins|net|fanout|src_attr|variation - - - - - digits - - - The number of digits after the decimal point to report. The default value is the variable sta_report_default_digits. - - - - - -no_line_splits - - - Do not split long lines into multiple lines. - - - - The report_checks command reports paths in the design. Paths are reported in groups by capture clock, unclocked path delays, gated clocks and unconstrained. - See set_false_path for a description of allowed from_list, through_list and to_list objects. - - - - - - - report_check_types - - - [-scenes scenes][-violators][-verbose][-fields fields][-format slack_only|end][-max_delay][-min_delay][-recovery][-removal][-clock_gating_setup][-clock_gating_hold][-max_slew][-min_slew][-min_pulse_width][-min_period][-digits digits][-no_split_lines][> filename][>> filename] - - - - - scenes - - - Report checks for some scenes. The default value is all scenes. - - - - - -violators - - - Report all violated timing and design rule constraints. - - - - - -verbose - - - Use a verbose output format. - - - - - -format slack_only - - - Report the minimum slack for each timing check. - - - - - -format end - - - Report the endpoint for each check. - - - - - fields - - - List of capacitance|slew|input_pins|hierarchical_pins|net|fanout|src_attr|variation - - - - - -max_delay - - - Report setup and max delay path delay constraints. - - - - - -min_delay - - - Report hold and min delay path delay constraints. - - - - - -recovery - - - Report asynchronous recovery checks. - - - - - -removal - - - Report asynchronous removal checks. - - - - - -clock_gating_setup - - - Report gated clock enable setup checks. - - - - - -clock_gating_hold - - - Report gated clock hold setup checks. - - - - - - -max_slew - - - Report max transition design rule checks. - - - - - -max_skew - - - Report max skew design rule checks. - - - - - -min_pulse_width - - - Report min pulse width design rule checks. - - - - - -min_period - - - Report min period design rule checks. - - - - - -min_slew - - - Report min slew design rule checks. - - - - - -digits digits - - - The number of digits after the decimal point to report. The default value is the variable sta_report_default_digits. - - - - - -no_split_lines - - - Do not split long lines into multiple lines. - - - - The report_check_types command reports the slack for each type of timing and design rule constraint. The keyword options allow a subset of the constraint types to be reported. - - - - - - report_clock_latency - - - [-clocks clocks][-scenes scenes][-include_internal_latency][-digits digits] - - - - - clocks - - - The clocks to report. The default value is all c - - - - - scenes - - - Report clocks for scenes. The default value is all clocks in scenes modes. - - - - - -include_internal_latency - - - Include internal clock latency from liberty min/max_clock_tree_path timing groups. - - - - - digits - - - The number of digits to report for delays. - - - - Report the clock network latency. - - - - - - report_clock_min_period - - - [-clocks clocks][-scenes scenes][-include_port_paths] - - - - - clocks - - - The clocks to report. - - - - - -include_port_paths - - - Include paths from input port and to output ports. - - - - Report the minimum period and maximum frequency for clocks. If the -clocks argument is not specified all clocks are reported. The minimum period is determined by examining the smallest slack paths between registers the rising edges of the clock or between falling edges of the clock. Paths between different clocks, different clock edges of the same clock, level sensitive latches, or paths constrained by set_multicycle_path, set_max_path are not considered. - - - - - - report_clock_properties - - - [clock_names] - - - - - clock_names - - - List of clock names to report. - - - - The report_clock_properties command reports the period and rise/fall edge times for each clock that has been defined. - - - - - - report_clock_skew - - - [-setup|-hold][-clocks clocks][-scenes scenes][-include_internal_latency][-digits digits] - - - - - -setup - - - Report skew for setup checks. - - - - - -hold - - - Report skew for hold checks. - - - - - clocks - - - The clocks to report. The default value is all clocks in scenes modes. - - - - - scenes - - - Report clocks for scenes. The default value is all scenes. - - - - - -include_internal_latency - - - Include internal clock latency from liberty min/max_clock_tree_path timing groups. - - - - - -digits digits - - - The number of digits to report for delays. - - - - Report the maximum difference in clock arrival between every source and target register that has a path between the source and target registers. - - - - - - report_dcalc - - - [-from from_pin][-to to_pin][-scene scene][-min][-max][-digits digits][> filename][>> filename] - - - - - from_pin - - - Report delay calculations for timing arcs from instance input pin from_pin. - - - - - to_pin - - - Report delay calculations for timing arcs to instance output pin to_pin. - - - - - - scene - - - Report paths for process scene. The -scene keyword is required if more than one process corner is defined. - - - - - -min - - - Report delay calculation for min delays. - - - - - -max - - - Report delay calculation for max delays. - - - - - -digits digits - - - The number of digits after the decimal point to report. The default is sta_report_default_digits. - - - - The report_dcalc command shows how the delays between instance pins are calculated. It is useful for debugging problems with delay calculation. - - - - - - report_disabled_edges - - - - - - - The report_disabled_edges command reports disabled timing arcs along with the reason they are disabled. Each disabled timing arc is reported as the instance name along with the from and to ports of the arc. The disable reason is shown next. Arcs that are disabled with set_disable_timing are reported with constraint as the reason. Arcs that are disabled by constants are reported with constant as the reason along with the constant instance pin and value. Arcs that are disabled to break combinational feedback loops are reported with loop as the reason. - > report_disabled_edgesu1 A B constant B=0 - - - - - - report_edges - - - [-from from_pin][-to to_pin][-report_variation][-digits digits] - - - - - from_pin - - - Report edges/timing arcs from pin from_pin. - - - - - to_pin - - - Report edges/timing arcs to pin to_pin. - - - - - -report_variation - - - - - - - - digits - - - The number of digits after the decimal point to report. The default value is the variable sta_report_default_digits. - - - - Report the edges/timing arcs and their delays in the timing graph from/to/between pins. - - - - - - - report_instance - - - instance_path[> filename][>> filename] - - - - - instance_path - - - Hierarchical path to an instance. - - - - - - - - - - report_lib_cell - - - cell_name[> filename][>> filename] - - - - - cell_name - - - The name of a library cell. - - - - Describe the liberty library cell cell_name. - - - - - - report_net - - - [-digits digits]net_path[> filename][>> filename] - - - - - digits - - - The number of digits after the decimal point to report. The default value is the variable sta_report_default_digits. - - - - - net_path - - - Hierarchical path to a net. - - - - Report the connections and capacitance of a net. - - - - - - report_parasitic_annotation - - - [-report_unannotated][> filename][>> filename] - - - - - -report_unannotated - - - Report unannotated and partially annotated nets. - - - - Report SPEF parasitic annotation completeness. - - - - - - report_power - - - [-instances instances][-highest_power_instances count][-digits digits][> filename][>> filename] - - - - - - -instances instances - - - Report the power for each instance of instances. If the instance is hierarchical the total power for the instances inside the hierarchical instance is reported. - - - - - -highest_power_instances count - - - Report the power for the count highest power instances. - - - - - -digits digits - - - The number of digits after the decimal point to report. The default value is the variable sta_report_default_digits. - - - - The report_power command uses static power analysis based on propagated or annotated pin activities in the circuit using Liberty power models. The internal, switching, leakage and total power are reported. Design power is reported separately for combinational, sequential, macro and pad groups. Power values are reported in watts. - The read_vcd or read_saif commands can be used to read activities from a file based on simulation. If no simulation activities are available, the set_power_activity command should be used to set the activity of input ports or pins in the design. The default input activity and duty for inputs are 0.1 and 0.5 respectively. The activities are propagated from annotated input ports or pins through gates and used in the power calculations. - Group Internal Switching Leakage Total Power Power Power Power----------------------------------------------------------------Sequential 3.29e-06 3.41e-08 2.37e-07 3.56e-06 92.4%Combinational 1.86e-07 3.31e-08 7.51e-08 2.94e-07 7.6%Macro 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.0%Pad 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.0%---------------------------------------------------------------Total 3.48e-06 6.72e-08 3.12e-07 3.86e-06 100.0% 90.2% 1.7% 8.1% - - - - - - report_slews - - - [-scenes scenes][-report_variation][-digits digits]pin - - - - - scenes - - - Report slews for process for scenes process corners. - - - - - -report_variation - - - Report SSTA distribution parameters. - - - - - -digits digits - - - The number of digits after the decimal point to report. The default value is the variable sta_report_default_digits. - - - - - pin - - - - - - - Report the slews at pin - - - - - - - report_tns - - - [-min][-max][-digits digits] - - - - - -max - - - Report the total max/setup slack. - - - - - -min - - - Report the total min/hold slack. - - - - - -digits digits - - - The number of digits after the decimal point to report. The default value is the variable sta_report_default_digits. - - - - Report the total negative slack. - - - - - - report_units - - - - - - - Report the units used for command arguments and reporting. - report_units time 1ns capacitance 1pF resistance 1kohm voltage 1v current 1A power 1pW distance 1um - - - - - - report_wns - - - [-min][-max][-digits digits] - - - - - -max - - - Report the worst max/setup slack. - - - - - -min - - - Report the worst min/hold slack. - - - - - -digits digits - - - The number of digits after the decimal point to report. The default value is the variable sta_report_default_digits. - - - - Report the worst negative slack. If the worst slack is positive, zero is reported. - - - - - - report_worst_slack - - - [-min][-max][-digits digits] - - - - - - -max - - - Report the worst max/setup slack. - - - - - -min - - - Report the worst min/hold slack. - - - - - -digits digits - - - The number of digits after the decimal point to report. The default value is the variable sta_report_default_digits. - - - - - - - - - - set_assigned_check - - - -setup|-hold|-recovery|-removal[-rise][-fall][-scene scene][-min][-max][-from from_pins][-to to_pins][-clock rise|fall][-cond sdf_cond][-worst]margin - - - - - -setup - - - Annotate setup timing checks. - - - - - -hold - - - Annotate hold timing checks. - - - - - -recovery - - - Annotate recovery timing checks. - - - - - -removal - - - Annotate removal timing checks. - - - - - -rise - - - Annotate rising delays. - - - - - -fall - - - Annotate falling delays. - - - - - scene - - - The name of a scene. The -scene keyword is required if more than one scene is defined. - - - - - -min - - - Annotate the minimum value of the process corner. - - - - - -max - - - Annotate the maximum value of the process corner. - - - - - from_pins - - - A list of pins for the clock. - - - - - to_pins - - - A list of pins for the data. - - - - - - -clock rise|fall - - - The timing check clock pin transition. - - - - - margin - - - The timing check margin. - - - - The set_assigned_check command is used to annotate the timing checks between two pins on an instance. The annotated delay overrides the calculated delay. This command is an interactive way to back-annotate delays like an SDF file. - - - - - - set_assigned_delay - - - -cell|-net[-rise][-fall][-scene scene][-min][-max][-from from_pins][-to to_pins]delay - - - - - -cell - - - Annotate the delays between two pins on an instance. - - - - - -net - - - Annotate the delays between two pins on a net. - - - - - -rise - - - Annotate the rising delays. - - - - - -fall - - - Annotate the falling delays. - - - - - scene - - - The name of a scene. The -scene keyword is required if more than one scene is defined. - - - - - -min - - - Annotate the minimum delays. - - - - - -max - - - Annotate the maximum delays. - - - - - from_pins - - - A list of pins. - - - - - to_pins - - - A list of pins. - - - - - delay - - - The delay between from_pins and to_pins. - - - - The set_assigned_delay command is used to annotate the delays between two pins on an instance or net. The annotated delay overrides the calculated delay. This command is an interactive way to back-annotate delays like an SDF file. - - - - - - - set_assigned_transition - - - [-rise][-fall][-scene scene][-min][-max]slewpin_list - - - - - -rise - - - Annotate the rising transition. - - - - - -fall - - - Annotate the falling transition. - - - - - scene - - - Annotate delays for scene. - - - - - -min - - - Annotate the minimum transition time. - - - - - -max - - - Annotate the maximum transition time. - - - - - slew - - - The pin transition time. - - - - - pin_list - - - A list of pins. - - - - The set_assigned_transition command is used to annotate the transition time (slew) of a pin. The annotated transition time overrides the calculated transition time. - - - - - - set_case_analysis - - - 0|1|zero|one|rise|rising|fall|fallingport_or_pin_list - - - - - port_or_pin_list - - - A list of ports or pins. - - - - The set_case_analysis command sets the signal on a port or pin to a constant logic value. No paths are propagated from constant pins. Constant values set with the set_case_analysis command are propagated through downstream gates. - Conditional timing arcs with mode groups are controlled by logic values on the instance pins. - - - - - - set_clock_gating_check - - - [-setup setup_time][-hold hold_time][-rise][-fall][-high][-low][objects] - - - - - - -setup setup_time - - - Clock enable setup margin. - - - - - -hold hold_time - - - Clock enable hold margin. - - - - - -rise - - - The setup/hold margin is for the rising edge of the clock enable. - - - - - -fall - - - The setup/hold margin is for the falling edge of the clock enable. - - - - - -high - - - The gating clock is active high (pin and instance objects only). - - - - - -low - - - The gating clock is active low (pin and instance objects only). - - - - - objects - - - A list of clocks, instances, pins or ports. - - - - The set_clock_gating_check command is used to add setup or hold timing checks for data signals used to gate clocks. - If no objects are specified the setup/hold margin is global and applies to all clock gating circuits in the design. If neither of the -rise and -fall options are used the setup/hold margin applies to the rising and falling edges of the clock gating signal. - Normally the library cell function is used to determine the active state of the clock. The clock is active high for AND/NAND functions and active low for OR/NOR functions. The -high and -low options are used to specify the active state of the clock for other cells, such as a MUX. - If multiple set_clock_gating_check commands apply to a clock gating instance he priority of the commands is shown below (highest to lowest priority). - clock enable pininstanceclock pinclockglobal - - - - - - set_clock_groups - - - [-name name][-logically_exclusive][-physically_exclusive][-asynchronous][-allow_paths]-group clocks - - - - - -name name - - - The clock group name. - - - - - -logically_exclusive - - - The clocks in different groups do not interact logically but can be physically present on the same chip. Paths between clock groups are considered for noise analysis. - - - - - - -physically_exclusive - - - The clocks in different groups cannot be present at the same time on a chip. Paths between clock groups are not considered for noise analysis. - - - - - -asynchronous - - - The clock groups are asynchronous. Paths between clock groups are considered for noise analysis. - - - - - -allow_paths - - - - - - - - clocks - - - A list of clocks in the group. - - - - The set_clock_groups command is used to define groups of clocks that interact with each other. Clocks in different groups do not interact and paths between them are not reported. Use a –group argument for each clock group. - - - - - - set_clock_latency - - - [-source][-clock clock][-rise][-fall][-min][-max]delayobjects - - - - - -source - - - The latency is at the clock source. - - - - - -clock clock - - - If multiple clocks are defined at a pin this use this option to specify the latency for a specific clock. - - - - - -rise - - - The latency is for the rising edge of the clock. - - - - - -fall - - - The latency is for the falling edge of the clock. - - - - - -min - - - delay is the minimum latency. - - - - - -max - - - delay is the maximum latency. - - - - - delay - - - Clock source or insertion delay. - - - - - objects - - - A list of clocks, pins or ports. - - - - The set_clock_latency command describes expected delays of the clock tree when anxsalyzing a design using ideal clocks. Use the -source option to specify latency at the clock source, also known as insertion delay. Source latency is delay in the clock tree that is external to the design or a clock tree internal to an instance that implements a complex logic function.set_clock_latency removes propagated clock properties for the clocks and pins objects. - - - - - - set_clock_transition - - - [-rise][-fall][-min][-max]transitionclocks - - - - - -rise - - - Set the transition time for the rising edge of the clock. - - - - - -fall - - - Set the transition time for the falling edge of the clock. - - - - - -min - - - Set the min transition time. - - - - - -max - - - Set the min transition time. - - - - - transition - - - Clock transition time (slew). - - - - - clocks - - - A list of clocks. - - - - The set_clock_transition command describes expected transition times of the clock tree when analyzing a design using ideal clocks. - - - - - - set_clock_uncertainty - - - [-from|-rise_from|-fall_from from_clock][-to|-rise_to|-fall_to to_clock][-rise][-fall][-setup][-hold]uncertainty[objects] - - - - - -from from_clock - - - Inter-clock uncertainty source clock. - - - - - -to to_clock - - - Inter-clock uncertainty target clock. - - - - - -rise - - - Inter-clock target clock rise edge, alternative to ‑rise_to.Inter-clock target clock rise edge, alternative to ‑rise_to. - - - - - -fall - - - Inter-clock target clock rise edge, alternative to ‑fall_to. - - - - - -setup - - - uncertainty is for setup checks. - - - - - - -hold - - - uncertainty is for hold checks. - - - - - uncertainty - - - Clock uncertainty. - - - - - objects - - - A list of clocks, ports or pins. - - - - The set_clock_uncertainty command specifies the uncertainty or jitter in a clock. The uncertainty for a clock can be specified on its source pin or port, or the clock itself. - set_clock_uncertainty .1 [get_clock clk1] - Inter-clock uncertainty between the source and target clocks of timing checks is specified with the ‑from|‑rise_from|-fall_from andto|‑rise_to|-fall_to arguments . - set_clock_uncertainty -from [get_clock clk1] -to [get_clocks clk2] .1 - The following commands are equivalent. - set_clock_uncertainty -from [get_clock clk1] -rise_to [get_clocks clk2] .1set_clock_uncertainty -from [get_clock clk1] -to [get_clocks clk2] -rise .1 - - - - - - set_cmd_units - - - [-capacitance cap_unit][-resistance res_unit][-time time_unit][-voltage voltage_unit][-current current_unit][-power power_unit][-distance distance_unit] - - - - - -capacitance cap_unit - - - The capacitance scale factor followed by 'f'. - - - - - -resistance res_unit - - - The resistance scale factor followed by 'ohm'. - - - - - -time time_unit - - - The time scale factor followed by 's'. - - - - - -voltage voltage_unit - - - The voltage scale factor followed by 'v'. - - - - - -current current_unit - - - The current scale factor followed by 'A'. - - - - - -power power_unit - - - The power scale factor followed by 'w'. - - - - - -distance distance_unit - - - The distance scale factor followed by 'm'. - - - - The set_cmd_units command is used to change the units used by the STA command interpreter when parsing commands and reporting results. The default units are the units specified in the first Liberty library file that is read. - Units are specified as a scale factor followed by a unit name. The scale factors are as follows. - M 1E+6k 1E+3m 1E-3u 1E-6n 1E-9p 1E-12f 1E-15 - An example of the set_units command is shown below. - set_cmd_units -time ns -capacitance pF -current mA -voltage V -resistance kOhm -distance um - - - - - - set_data_check - - - [-from|-rise_from|-fall_from from_pin][-to|-rise_to|-fall_to to_pin][-setup][-hold][-clock clock]margin - - - - - -from from_pin - - - A pin used as the timing check reference. - - - - - -to to_pin - - - A pin that the setup/hold check is applied to. - - - - - -setup - - - Add a setup timing check. - - - - - -hold - - - Add a hold timing check. - - - - - -clock clock - - - The setup/hold check clock. - - - - - margin - - - The setup or hold time margin. - - - - The set_data_check command is used to add a setup or hold timing check between two pins. - - - - - - set_disable_inferred_clock_gating - - - objects - - - - - objects - - - A list of clock gating instances, clock gating pins, or clock enable pins. - - - - The set_disable_inferred_clock_gating command disables clock gating checks on a clock gating instance, clock gating pin, or clock gating enable pin. - - - - - - set_disable_timing - - - [-from from_port][-to to_port]objects - - - - - -from from_port - - - - - - - - -to to_port - - - - - - - - objects - - - A list of instances, ports, pins, cells, cell/port, or library/cell/port. - - - - The set_disable_timing command is used to disable paths though pins in the design. There are many different forms of the command depending on the objects specified in objects. - All timing paths though an instance are disabled when objects contains an instance. Timing checks in the instance are not disabled. - set_disable_timing u2 - The -from and -to options can be used to restrict the disabled path to those from, to or between specific pins on the instance. - set_disable_timing -from A u2set_disable_timing -to Z u2set_disable_timing -from A -to Z u2 - A list of top level ports or instance pins can also be disabled. - set_disable_timing u2/Zset_disable_timing in1 - Timing paths though all instances of a library cell in the design can be disabled by naming the cell using a hierarchy separator between the library and cell name. Paths from or to a cell port can be disabled with the -from and -to options or a port name after library and cell names. - set_disable_timing liberty1/snl_bufx2set_disable_timing -from A liberty1/snl_bufxset_disable_timing -to Z liberty1/snl_bufxset_disable_timing liberty1/snl_bufx2/A - - - - - - set_drive - - - [-rise][-fall][-max][-min]resistanceports - - - - - -rise - - - Set the drive rise resistance. - - - - - -fall - - - Set the drive fall resistance. - - - - - -max - - - Set the maximum resistance. - - - - - -min - - - Set the minimum resistance. - - - - - resistance - - - The external drive resistance. - - - - - ports - - - A list of ports. - - - - The set_drive command describes the resistance of an input port external driver. - - - - - - set_driving_cell - - - [-lib_cell cell_name][-library library][-rise][-fall][-min][-max][-pin pin][-from_pin from_pin][-input_transition_rise trans_rise][-input_transition_fall trans_fall]ports - - - - - -lib_cell cell_name - - - The driving cell. - - - - - -library library - - - The driving cell library. - - - - - -rise - - - Set the driving cell for a rising edge. - - - - - - -fall - - - Set the driving cell for a falling edge. - - - - - -max - - - Set the driving cell for max delays. - - - - - -min - - - Set the driving cell for min delays. - - - - - -pin pin - - - The output port of the driving cell. - - - - - -from_pin from_pin - - - Use timing arcs from from_pin to the output pin. - - - - - -input_transition_rise trans_rise - - - The transition time for a rising input at from_pin. - - - - - -input_transition_fall trans_fall - - - The transition time for a falling input at from_pin. - - - - - ports - - - A list of ports. - - - - The set_driving_cell command describes an input port external driver. - - - - - - set_false_path - - - [-setup][-hold][-rise][-fall][-from from_list][-rise_from from_list][-fall_from from_list][-through through_list][-rise_through through_list][-fall_through through_list][-to to_list][-rise_to to_list][-fall_to to_list][-reset_path] - - - - - -setup - - - Apply to setup checks. - - - - - -hold - - - Apply to hold checks. - - - - - -rise - - - Apply to rising path edges. - - - - - -fall - - - Apply to falling path edges. - - - - - - -reset_path - - - Remove any matching set_false_path, set_multicycle_path, set_max_delay, set_min_delay exceptions first. - - - - - -from from_list - - - A list of clocks, instances, ports or pins. - - - - - -through through_list - - - A list of instances, pins or nets. - - - - - -to to_list - - - A list of clocks, instances, ports or pins. - - - - The set_false_path command disables timing along a path from, through and to a group of design objects. - Objects in from_list can be clocks, register/latch instances, or register/latch clock pins. The -rise_from and -fall_from keywords restrict the false paths to a specific clock edge. - Objects in through_list can be nets, instances, instance pins, or hierarchical pins,. The -rise_through and -fall_through keywords restrict the false paths to a specific path edge that traverses through the object. - Objects in to_list can be clocks, register/latch instances, or register/latch clock pins. The -rise_to and -fall_to keywords restrict the false paths to a specific transition at the path end. - - - - - - set_fanout_load - - - fanoutport_list - - - - This command is ignored. - - - - - - set_hierarchy_separator - - - separator - - - - - separator - - - Character used to separate hierarchical names. - - - - Set the character used to separate names in a hierarchical instance, net or pin name. This separator is used by the command interpreter to read arguments and print results. The default separator is '/'. - - - - - - set_ideal_latency - - - [-rise] [-fall] [-min] [-max] delay objects - - - - The set_ideal_latency command is parsed but ignored. - - - - - - set_ideal_network - - - [-no_propagation] objects - - - - The set_ideal_network command is parsed but ignored. - - - - - - set_ideal_transition - - - [-rise] [-fall] [-min] [-max] transition_time objects - - - - The set_ideal_transition command is parsed but ignored. - - - - - - set_input_delay - - - [-rise][-fall][-max][-min][-clock clock][-clock_fall][-reference_pin ref_pin][-source_latency_included][-network_latency_included][-add_delay]delayport_pin_list - - - - - -rise - - - Set the arrival time for the rising edge of the input. - - - - - -fall - - - Set the arrival time for the falling edge of the input. - - - - - -max - - - Set the maximum arrival time. - - - - - -min - - - Set the minimum arrival time. - - - - - -clock clock - - - The arrival time is from clock. - - - - - -clock_fall - - - The arrival time is from the falling edge of clock. - - - - - -reference_pin ref_pin - - - The arrival time is with respect to the clock that arrives at ref_pin. - - - - - -source_latency_included - - - D no add the clock source latency (insertion delay) to the delay value. - - - - - -network_latency_included - - - Do not add the clock latency to the delay value when the clock is ideal. - - - - - -add_delay - - - Add this arrival to any existing arrivals. - - - - - delay - - - The arrival time after clock. - - - - - pin_port_list - - - A list of pins or ports. - - - - The set_input_delay command is used to specify the arrival time of an input signal. - The following command sets the min, max, rise and fall times on the in1 input port 1.0 time units after the rising edge of clk1. - set_input_delay -clock clk1 1.0 [get_ports in1] - Use multiple commands with the -add_delay option to specify separate arrival times for min, max, rise and fall times or multiple clocks. For example, the following specifies separate arrival times with respect to clocks clk1 and clk2. - set_input_delay -clock clk1 1.0 [get_ports in1]set_input_delay -add_delay -clock clk2 2.0 [get_ports in1] - The –reference_pin option is used to specify an arrival time with respect to the arrival on a pin in the clock network. For propagated clocks, the input arrival time is relative to the clock arrival time at the reference pin (the clock source latency and network latency from the clock source to the reference pin). For ideal clocks, input arrival time is relative to the reference pin clock source latency. With the -clock_fall flag the arrival time is relative to the falling transition at the reference pin. If no clocks arrive at the reference pin the set_input_delay command is ignored. If no -clock is specified the arrival time is with respect to all clocks that arrive at the reference pin. The -source_latency_included and -network_latency_included options cannot be used with -reference_pin. - Paths from inputs that do not have an arrival time defined by set_input_delay are not reported. Set the sta_input_port_default_clock variable to 1 to report paths from inputs without a set_input_delay. - - - - - - set_input_transition - - - [-rise][-fall][-max][-min]transitionport_list - - - - - -rise - - - Set the rising edge transition. - - - - - -fall - - - Set the falling edge transition. - - - - - -max - - - Set the minimum transition time. - - - - - -min - - - Set the maximum transition time. - - - - - transition - - - The transition time (slew). - - - - - port_list - - - A list of ports. - - - - The set_input_transition command is used to specify the transition time (slew) of an input signal. - - - - - - set_level_shifter_strategy - - - [-rule rule_type] - - - - This command is parsed and ignored by timing analysis. - - - - - - - set_level_shifter_threshold - - - [-voltage voltage] - - - - This command is parsed and ignored by timing analysis. - - - - - - set_load - - - [-rise][-fall][-max][-min][-subtract_pin_load][-pin_load][-wire_load]capacitanceobjects - - - - - -rise - - - Set the external port rising capacitance (ports only). - - - - - -fall - - - Set the external port falling capacitance (ports only). - - - - - -max - - - Set the max capacitance. - - - - - -min - - - Set the min capacitance. - - - - - -subtract_pin_load - - - Subtract the capacitance of all instance pins connected to the net from capacitance (nets only). If the resulting capacitance is negative, zero is used. Pin capacitances are ignored by delay calculation when this option is used. - - - - - -pin_load - - - capacitance is external instance pin capacitance (ports only). - - - - - -wire_load - - - capacitance is external wire capacitance (ports only). - - - - - capacitance - - - The capacitance, in library capacitance units. - - - - - objects - - - A list of nets or ports. - - - - The set_load command annotates wire capacitance on a net or external capacitance on a port. There are four different uses for the set_load commanc: - set_load -wire_load port external port wire capacitanceset_load -pin_load port external port pin capacitanceset_load port same as -pin_loadset_load net net wire capacitance - External port capacitance can be annotated separately with the -pin_load and ‑wire_load options. Without the -pin_load and -wire_load options pin capacitance is annotated. - When annotating net wire capacitance with the -subtract_pin_load option the capacitance of all instance pins connected to the net is subtracted from capacitance. Setting the capacitance on a net overrides SPEF parasitics for delay calculation. - - - - - - set_logic_dc - - - port_list - - - - - port_pin_list - - - List of ports or pins. - - - - Set a port or pin to a constant unknown logic value. No paths are propagated from constant pins. - - - - - - set_logic_one - - - port_list - - - - - port_pin_list - - - List of ports or pins. - - - - Set a port or pin to a constant logic one value. No paths are propagated from constant pins. Constant values set with the set_logic_one command are not propagated through downstream gates. - - - - - - set_logic_zero - - - port_list - - - - - port_pin_list - - - List of ports or pins. - - - - Set a port or pin to a constant logic zero value. No paths are propagated from constant pins. Constant values set with the set_logic_zero command are not propagated through downstream gates. - - - - - - set_max_area - - - area - - - - - area - - - - - - - The set_max_area command is ignored during timing but is included in SDC files that are written. - - - - - - set_max_capacitance - - - capacitanceobjects - - - - - capacitance - - - - - - - - - objects - - - List of ports or cells. - - - - The set_max_capacitance command is ignored during timing but is included in SDC files that are written. - - - - - - set_max_delay - - - [-rise][-fall][-from from_list][-rise_from from_list][-fall_from from_list][-through through_list][-rise_through through_list][-fall_through through_list][-to to_list][-rise_to to_list][-fall_to to_list][-ignore_clock_latency][-probe][-reset_path]delay - - - - - -rise - - - Set max delay for rising paths. - - - - - -fall - - - Set max delay for falling paths. - - - - - -from from_list - - - A list of clocks, instances, ports or pins. - - - - - -through through_list - - - A list of instances, pins or nets. - - - - - -to to_list - - - A list of clocks, instances, ports or pins. - - - - - -ignore_clock_latency - - - Ignore clock latency at the source and target registers. - - - - - -probe - - - Do not break paths at internal pins (non startpoints). - - - - - -reset_path - - - Remove any matching set_false_path, set_multicycle_path, set_max_delay, set_min_delay exceptions first. - - - - - delay - - - The maximum delay. - - - - The set_max_delay command constrains the maximum delay through combinational logic paths. See set_false_path for a description of allowed from_list, through_list and to_list objects. If the to_list ends at a timing check the setup/hold time is included in the path delay. - When the -ignore_clock_latency option is used clock latency at the source and destination of the path delay is ignored. The constraint is reported in the default path group (**default**) rather than the clock path group when the path ends at a timing check. - - - - - - set_max_dynamic_power - - - power [unit] - - - - The set_max_dynamic_power command is ignored during timing but is included in SDC files that are written. - - - - - - set_max_fanout - - - fanoutobjects - - - - - fanout - - - - - - - - objects - - - List of ports or cells. - - - - The set_max_fanout command is ignored during timing but is included in SDC files that are written. - - - - - - set_max_leakage_power - - - power [unit] - - - - The set_max_leakage_power command is ignored during timing but is included in SDC files that are written. - - - - - - set_max_time_borrow - - - delayobjects - - - - - delay - - - The maximum time the latches can borrow. - - - - - objects - - - List of clocks, instances or pins. - - - - The set_max_time_borrow command specifies the maximum amount of time that latches can borrow. Time borrowing is the time that a data input to a transparent latch arrives after the latch opens. - - - - - - set_max_transition - - - [-data_path][-clock_path][-rise][-fall]transitionobjects - - - - - -data_path - - - Set the max slew for data paths. - - - - - -clock_path - - - Set the max slew for clock paths. - - - - - - -rise - - - Set the max slew for rising paths. - - - - - -fall - - - Set the max slew for falling paths. - - - - - transition - - - The maximum slew/transition time. - - - - - objects - - - List of clocks, ports or designs. - - - - The set_max_transition command is specifies the maximum transition time (slew) design rule checked by the report_check_types –max_transition command. - If specified for a design, the default maximum transition is set for the design. - If specified for a clock, the maximum transition is applied to all pins in the clock domain. The –clock_path option restricts the maximum transition to clocks in clock paths. The -data_path option restricts the maximum transition to clocks data paths. The –clock_path, -data_path, -rise and –fall options only apply to clock objects. - - - - - - set_min_capacitance - - - capacitanceobjects - - - - - capacitance - - - Minimum capacitance. - - - - - objects - - - List of ports or cells. - - - - The set_min_capacitance command is ignored during timing but is included in SDC files that are written. - - - - - - set_min_delay - - - [-rise][-fall][-from from_list][-rise_from from_list][-fall_from from_list][-through through_list][-rise_through through_list][-fall_through through_list][-to to_list][-rise_to to_list][-fall_to to_list][-ignore_clock_latency][-probe][-reset_path]delay - - - - - -rise - - - Set min delay for rising paths. - - - - - - -fall - - - Set min delay for falling paths. - - - - - -from from_list - - - A list of clocks, instances, ports or pins. - - - - - -through through_list - - - A list of instances, pins or nets. - - - - - -to to_list - - - A list of clocks, instances, ports or pins. - - - - - -ignore_clock_latency - - - Ignore clock latency at the source and target registers. - - - - - -probe - - - Do not break paths at internal pins (non startpoints). - - - - - -reset_path - - - Remove any matching set_false_path, set_multicycle_path, set_max_delay, set_min_delay exceptions first. - - - - - delay - - - The minimum delay. - - - - The set_min_delay command constrains the minimum delay through combinational logic. See set_false_path for a description of allowed from_list, through_list and to_list objects. If the to_list ends at a timing check the setup/hold time is included in the path delay. - When the -ignore_clock_latency option is used clock latency at the source and destination of the path delay is ignored. The constraint is reported in the default path group (**default**) rather than the clock path group when the path ends at a timing check. - - - - - - set_min_pulse_width - - - [-high][-low]min_widthobjects - - - - - -high - - - Set the minimum high pulse width. - - - - - -low - - - Set the minimum low pulse width. - - - - - min_width - - - - - - - - objects - - - List of pins, instances or clocks. - - - - If -low and -high are not specified the minimum width applies to both high and low pulses. - - - - - - set_mode - - - mode_name - - - - Set the mode for SDC commands in the TCL interpreter. If mode mode_name does not exist, it is created. When modes are created the default mode is deleted. - - - - - - - set_multicycle_path - - - [-setup][-hold][-rise][-fall][-start][-end][-from from_list][-rise_from from_list][-fall_from from_list][-through through_list][-rise_through through_list][-fall_through through_list][-to to_list][-rise_to to_list][-fall_to to_list][-reset_path]path_multiplier - - - - - -setup - - - Set cycle count for setup checks. - - - - - -hold - - - Set cycle count for hold checks. - - - - - -rise - - - Set cycle count for rising path edges. - - - - - -fall - - - Set cycle count for falling path edges. - - - - - -start - - - Multiply the source clock period by period_multiplier. - - - - - -end - - - Multiply the target clock period by period_multiplier. - - - - - -from from_list - - - A list of clocks, instances, ports or pins. - - - - - -through through_list - - - A list of instances, pins or nets. - - - - - -to to_list - - - A list of clocks, instances, ports or pins. - - - - - -reset_path - - - Remove any matching set_false_path, set_multicycle_path, set_max_delay, set_min_delay exceptions first. - - - - - path_multiplier - - - The number of clock periods to add to the path required time. - - - - Normally the path between two registers or latches is assumed to take one clock cycle. The set_multicycle_path command overrides this assumption and allows multiple clock cycles for a timing check. See set_false_path for a description of allowed from_list, through_list and to_list objects. - - - - - - - set_operating_conditions - - - [-analysis_type single|bc_wc|on_chip_variation][-library lib][condition][-min min_condition][-max max_condition][-min_library min_lib][-max_library max_lib] - - - - - -analysis_type single - - - Use one operating condition for min and max paths. - - - - - -analysis_type bc_wc - - - Best case, worst case analysis. Setup checks use max_condition for clock and data paths. Hold checks use the min_condition for clock and data paths. - - - - - ‑analysis_type on_chip_variation - - - The min and max operating conditions represent variations on the chip that can occur simultaneously. Setup checks use max_condition for data paths and min_condition for clock paths. Hold checks use min_condition for data paths and max_condition for clock paths. This is the default analysis type. - - - - - -library lib - - - The name of the library that contains condition. - - - - - condition - - - The operating condition for analysis type single. - - - - - -min min_condition - - - The operating condition to use for min paths and hold checks. - - - - - -max max_condition - - - The operating condition to use for max paths and setup checks. - - - - - -min_library min_lib - - - The name of the library that contains min_condition. - - - - - -max_library max_lib - - - The name of the library that contains max_condition. - - - - The set_operating_conditions command is used to specify the type of analysis performed and the operating conditions used to derate library data. - - - - - - set_output_delay - - - [-rise][-fall][-max][-min][-clock clock][-clock_fall][-reference_pin ref_pin][-source_latency_included][-network_latency_included][-add_delay]delayport_pin_list - - - - - - -rise - - - Set the output delay for the rising edge of the input. - - - - - -fall - - - Set the output delay for the falling edge of the input. - - - - - -max - - - Set the maximum output delay. - - - - - -min - - - Set the minimum output delay. - - - - - -clock clock - - - The external check is to clock. The default clock edge is rising. - - - - - -clock_fall - - - The external check is to the falling edge of clock. - - - - - -reference_pin ref_pin - - - The external check is clocked by the clock that arrives at ref_pin. - - - - - -add_delay - - - Add this output delay to any existing output delays. - - - - - delay - - - The external delay to the check clocked by clock. - - - - - pin_port_list - - - A list of pins or ports. - - - - The set_output_delay command is used to specify the external delay to a setup/hold check on an output port or internal pin that is clocked by clock. Unless the -add_delay option is specified any existing output delays are replaced. - The –reference_pin option is used to specify a timing check with respect to the arrival on a pin in the clock network. For propagated clocks, the timing check is relative to the clock arrival time at the reference pin (the clock source latency and network latency from the clock source to the reference pin). For ideal clocks, the timing check is relative to the reference pin clock source latency. With the -clock_fall flag the timing check is relative to the falling edge of the reference pin. If no clocks arrive at the reference pin the set_output_delay command is ignored. If no -clock is specified the timing check is with respect to all clocks that arrive at the reference pin. The -source_latency_included and -network_latency_included options cannot be used with -reference_pin. - - - - - - set_path_margin - - - [-setup][-hold][-rise][-fall][-from from_list][-rise_from from_list][-fall_from from_list][-through through_list][-rise_through through_list][-fall_through through_list][-to to_list][-rise_to to_list][-fall_to to_list][-comment comment]margin - - - - - -setup - - - Apply the margin to setup checks. - - - - - -hold - - - Apply the margin to hold checks. - - - - - -rise - - - Apply the margin to rising path edges. - - - - - -fall - - - Apply the margin to falling path edges. - - - - - -from from_list - - - A list of clocks, instances, ports or pins. - - - - - -through through_list - - - A list of instances, pins or nets. - - - - - -to to_list - - - A list of clocks, instances, ports or pins. - - - - - -comment comment - - - Optional comment written by write_sdc. - - - - - margin - - - Signed slack adjustment applied on the capture clock. A positive margin tightens the path and a negative margin loosens it. - - - - The set_path_margin command applies a signed slack adjustment to matching timing paths on the capture-clock side. A positive margin makes the path harder to meet and a negative margin makes it easier. If neither -setup nor -hold is specified the margin applies to both. See set_false_path for a description of allowed from_list, through_list and to_list objects. At least one of -from, -through, or -to is required. Matching exceptions are removed with unset_path_exceptions. - - - - - - set_port_fanout_number - - - [-min][-max]fanoutports - - - - - -min - - - Set the min fanout. - - - - - -max - - - Set the max fanout. - - - - - fanout - - - The external fanout of the ports. - - - - - port_list - - - A list of ports. - - - - Set the external fanout for ports. - - - - - - set_power_activity - - - [-global][-input][-input_ports ports][-pins pins][-activity activity | -density density][-duty duty][-clock clock] - - - - - -global - - - Set the activity/duty for all non-clock pins. - - - - - -input - - - Set the default input port activity/duty. - - - - - -input_ports input_ports - - - Set the input port activity/duty. - - - - - -pins pins - - - Set the pin activity/duty. - - - - - -activity activity - - - The activity, or number of transitions per clock cycle. If clock is not specified the clock with the minimum period is used. If no clocks are defined an error is reported. - - - - - -density density - - - Transitions per library time unit. - - - - - -duty duty - - - The duty, or probability the signal is high (0 <= duty <= 1.0). Defaults to 0.5. - - - - - -clock clock - - - The clock to use for the period with -activity. This option is ignored if -density is used. - - - - The set_power_activity command is used to set the activity and duty used for power analysis globally or for input ports or pins in the design. - The default input activity for inputs is 0.1 transitions per minimum clock period if a clock is defined or 0.0 if there are no clocks defined. The default input duty is 0.5. This is equivalent to the following command: - set_power_activity -input -activity 0.1 -duty 0.5 - - - - - - set_propagated_clock - - - objects - - - - - objects - - - A list of clocks, ports or pins. - - - - The set_propagated_clock command changes a clock tree from an ideal network that has no delay one that uses calculated or back-annotated gate and interconnect delays. When objects is a port or pin, clock delays downstream of the object are used. - - - - - - - set_pvt - - - [-min][-max][-process process][-voltage voltage] - [-temperature temperature]instances - - - - - -min - - - Set the PVT values for max delays. - - - - - -max - - - Set the PVT values for min delays. - - - - - -process process - - - A process value (float). - - - - - -voltage voltage - - - A voltage value (float). - - - - - -temperature temperature - - - A temperature value (float). - - - - - instances - - - A list instances. - - - - The set_pvt command sets the process, voltage and temperature values used during delay calculation for a specific instance in the design. - - - - - - set_sense - - - [-type clock|data][-positive][-negative][-pulse pulse_type][-stop_propagation][-clock clocks]pins - - - - - -type clock - - - Set the sense for clock paths. - - - - - -type data - - - Set the sense for data paths (not supported). - - - - - -positive - - - The clock sense is positive unate. - - - - - -negative - - - The clock sense is negative unate. - - - - - - -pulse pulse_type - - - rise_triggered_high_pulserise_triggered_low_pulsefall_triggered_high_pulsefall_triggered_low_pulseNot supported. - - - - - -stop_propagation - - - Stop propagating clocks at pins. - - - - - clocks - - - A list of clocks to apply the sense. - - - - - pins - - - A list of pins. - - - - The set_sense command is used to modify the propagation of a clock signal. The clock sense is set with the ‑positive and –negative flags. Use the –stop_propagation flag to stop the clock from propagating beyond a pin. The –positive, -negative, -stop_propagation, and –pulse options are mutually exclusive. If the –clock option is not used the command applies to all clocks that traverse pins. The –pulse option is currently not supported. - - - - - - set_timing_derate - - - [-rise][-fall][-early][-late][-clock][-data][-net_delay][-cell_delay][-cell_check]derate[objects] - - - - - -rise - - - Set the derating for rising delays. - - - - - -fall - - - Set the derating for falling delays. - - - - - -early - - - Derate early (min) paths. - - - - - -late - - - Derate late (max) paths. - - - - - -clock - - - Derate paths in the clock network. - - - - - -data - - - Derate data paths. - - - - - -net_delay - - - Derate net (interconnect) delays. - - - - - - -cell_delay - - - Derate cell delays. - - - - - -cell_check - - - Derate cell timing check margins. - - - - - derate - - - The derating factor to apply to delays. - - - - - objects - - - A list of instances, library cells, or nets. - - - - The set_timing_derate command is used to derate delay calculation results used by the STA. If the –early and –late flags are omitted the both min and max paths are derated. If the –clock and –data flags are not used the derating both clock and data paths are derated. - Use the unset_timing_derate command to remove all derating factors. - - - - - - set_resistance - - - [-max][-min]resistancenets - - - - - -min - - - The resistance for minimum path delay calculation. - - - - - -max - - - The resistance for maximum path delay calculation. - - - - - resistance - - - The net resistance. - - - - - nets - - - A list of nets. - - - - - - - - - - set_units - - - [-capacitance cap_unit][-resistance res_unit][-time time_unit][-voltage voltage_unit][-current current_unit][-power power_unit][-distance distance_unit] - - - - - -capacitance cap_unit - - - The capacitance scale factor followed by 'f'. - - - - - -resistance res_unit - - - The resistance scale factor followed by 'ohm'. - - - - - -time time_unit - - - The time scale factor followed by 's'. - - - - - - -voltage voltage_unit - - - The voltage scale factor followed by 'v'. - - - - - -current current_unit - - - The current scale factor followed by 'A'. - - - - - -power power_unit - - - The power scale factor followed by 'w'. - - - - The set_units command is used to check the units used by the STA command interpreter when parsing commands and reporting results. If the current units differ from the set_unit value a warning is printed. Use the set_cmd_units command to change the command units. - Units are specified as a scale factor followed by a unit name. The scale factors are as follows. - M 1E+6k 1E+3m 1E-3u 1E-6n 1E-9p 1E-12f 1E-15 - An example of the set_units command is shown below. - set_units -time ns -capacitance pF -current mA -voltage V -resistance kOhm - - - - - - set_wire_load_min_block_size - - - size - - - - The set_wire_load_min_block_size command is not supported. - - - - - - set_wire_load_mode - - - top|enclosed|segmented - - - - - top - - - - - - - - enclosed - - - - - - - - segmented - - - - - - - The set_wire_load_mode command is ignored during timing but is included in SDC files that are written. - - - - - - set_wire_load_model - - - -name model_name[-library library][-max][-min][objects] - - - - - - -name model_name - - - The name of a wire load model. - - - - - -library library - - - Library to look for model_name. - - - - - -max - - - The wire load model is for maximum path delays. - - - - - -min - - - The wire load model is for minimum path delays. - - - - - objects - - - Not supported. - - - - - - - - - - set_wire_load_selection_group - - - [-library library][-max][-min]group_name[objects] - - - - - library - - - Library to look for group_name. - - - - - -max - - - The wire load selection is for maximum path delays. - - - - - -min - - - The wire load selection is for minimum path delays. - - - - - group_name - - - A wire load selection group name. - - - - - objects - - - Not supported. - - - - The set_wire_load_selection_group command is parsed but not supported. - - - - - - suppress_msg - - - msg_ids - - - - - msg_ids - - - A list of error/warning message IDs to suppress. - - - - The suppress_msg command suppresses specified error/warning messages by ID. The list of message IDs can be found in doc/messages.txt. - - - - - - unset_case_analysis - - - port_or_pin_list - - - - - port_or_pin_list - - - A list of ports or pins. - - - - The unset_case_analysis command removes the constant values defined by the set_case_analysis command. - - - - - - unset_clock_latency - - - [-source]objects - - - - - -source - - - Specifies source clock latency (clock insertion delay). - - - - - objects - - - A list of clocks, pins or ports. - - - - The unset_clock_latency command removes the clock latency set with the set_clock_latency command. - - - - - - unset_clock_transition - - - clocks - - - - - clocks - - - A list of clocks. - - - - The unset_clock_transition command removes the clock transition set with the set_clock_transition command. - - - - - - unset_clock_uncertainty - - - [-from|-rise_from|-fall_from from_clock][-to|-rise_to|-fall_to to_clock][-rise][-fall][-setup][-hold][objects] - - - - - -from from_clock - - - - - - - - -to to_clock - - - - - - - - -rise - - - The uncertainty is for the rising edge of the clock. - - - - - -fall - - - The uncertainty is for the falling edge of the clock. - - - - - -setup - - - uncertainty is the setup check uncertainty. - - - - - -hold - - - uncertainty is the hold uncertainty. - - - - - uncertainty - - - Clock uncertainty. - - - - - objects - - - A list of clocks, ports or pins. - - - - The unset_clock_uncertainty command removes clock uncertainty defined with the set_clock_uncertainty command. - - - - - - unset_data_check - - - [-from|-rise_from|-fall_from from_object][-to|-rise_to|-fall_to to_object][-setup][-hold][-clock clock] - - - - - -from from_object - - - A pin used as the timing check reference. - - - - - -to to_object - - - A pin that the setup/hold check is applied to. - - - - - -setup - - - Add a setup timing check. - - - - - -hold - - - Add a hold timing check. - - - - - clock - - - The setup/hold check clock. - - - - The unset_clock_transition command removes a setup or hold check defined by the set_data_check command. - - - - - - unset_disable_inferred_clock_gating - - - objects - - - - - objects - - - A list of clock gating instances, clock gating pins, or clock enable pins. - - - - The unset_disable_inferred_clock_gating command removes a previous set_disable_inferred_clock_gating command. - - - - - - unset_disable_timing - - - [-from from_port][-to to_port]objects - - - - - from_port - - - - - - - - to_port - - - - - - - - objects - - - A list of instances, ports, pins, cells or [library/]cell/port. - - - - The unset_disable_timing command is used to remove the effect of previous set_disable_timing commands. - - - - - - - unset_input_delay - - - [-rise][-fall][-max][-min][-clock clock][-clock_fall]port_pin_list - - - - - -rise - - - Unset the arrival time for the rising edge of the input. - - - - - -fall - - - Unset the arrival time for the falling edge of the input. - - - - - -max - - - Unset the minimum arrival time. - - - - - -min - - - Unset the maximum arrival time. - - - - - clock - - - Unset the arrival time from clock. - - - - - -clock_fall - - - Unset the arrival time from the falling edge of clock - - - - - pin_port_list - - - A list of pins or ports. - - - - The unset_input_delay command removes a previously defined set_input_delay. - - - - - - unset_output_delay - - - [-rise][-fall][-max][-min][-clock clock][-clock_fall]port_pin_list - - - - - -rise - - - This is the arrival time for the rising edge of the input. - - - - - -fall - - - This is the arrival time for the falling edge of the input. - - - - - -max - - - This is the minimum arrival time. - - - - - -min - - - This is the maximum arrival time. - - - - - clock - - - The arrival time is from this clock. - - - - - - -clock_fall - - - The arrival time is from the falling edge of clock - - - - - pin_port_list - - - A list of pins or ports. - - - - The unset_output_delay command a previously defined set_output_delay. - - - - - - unset_path_exceptions - - - [-setup][-hold][-rise][-fall][-from|-rise_from|-fall_from from][-through|-rise_through|-fall_through through][-to|-rise_to|-fall_to to] - - - - - -setup - - - Unset path exceptions for setup checks. - - - - - -hold - - - Unset path exceptions for hold checks. - - - - - -rise - - - Unset path exceptions for rising path edges. - - - - - -fall - - - Unset path exceptions for falling path edges. - - - - - -from from - - - A list of clocks, instances, ports or pins. - - - - - -through through - - - A list of instances, pins or nets. - - - - - -to to - - - A list of clocks, instances, ports or pins. - - - - The unset_path_exceptions command removes any matching set_false_path, set_multicycle_path, set_max_delay, set_min_delay, and set_path_margin exceptions. - - - - - - - unset_power_activity - - - [-global][-input][-input_ports ports][-pins pins] - - - - - -global - - - Set the activity/duty for all non-clock pins. - - - - - -input - - - Set the default input port activity/duty. - - - - - -input_ports input_ports - - - Set the input port activity/duty. - - - - - - -pins pins - - - Set the pin activity/duty. - - - - - -activity activity - - - The activity, or number of transitions per clock cycle. If clock is not specified the clock with the minimum period is used. If no clocks are defined an error is reported. - - - - The unset_power_activity_command is used to undo the effects of the set_power_activity command. - - - - - - unset_propagated_clock - - - objects - - - - - objects - - - A list of clocks, ports or pins. - - - - Remove a previous set_propagated_clock command. - - - - - - unset_timing_derate - - - - - - - Remove all derating factors set with the set_timing_derate command. - - - - - - unsuppress_msg - - - msg_ids - - - - - msg_ids - - - A list of error/warning message IDs to unsuppress. - - - - The unsuppress_msg command removes suppressions for the specified error/warning messages by ID. The list of message IDs can be found in doc/messages.txt. - - - - - - user_run_time - - - - - - - Returns the total user cpu run time in seconds as a float. - - - - - - with_output_to_variable - - - var { commands } - - - - - var - - - The name of a variable to save the output of commands to. - - - - - commands - - - TCL commands that the output will be redirected from. - - - - The with_output_to_variable command redirects the output of TCL commands to a variable. - - - - - - - write_path_spice - - - -path_args path_args-spice_file spice_file-lib_subckt_file lib_subckts_file-model_file model_file-power power-ground ground[-simulator hspice|ngspice|xyce] - - - - - path_args - - - -from|-through|-to arguments as in report_checks. - - - - - spice_file - - - Directory and path prefix for spice output files. - - - - - lib_subckts_file - - - Cell transistor level subckts. - - - - - model_file - - - Transistor model definitions .included by spice_file. - - - - - power - - - Voltage supply name in voltage_map of the default liberty library. - - - - - ground - - - Ground supply name in voltage_map of the default liberty library. - - - - - -simulator - - - Simulator that will read the spice netlist. - - - - The write_path_spice command writes a spice netlist for timing paths. Use path_args to specify -from/-through/-to as arguments to the find_timing_paths command. For each path, a spice netlist and the subckts referenced by the path are written in spice_directory. The spice netlist is written in path_<id>.sp and subckt file is path_<id>.subckt. - The spice netlists used by the path are written to subckt_file, which spice_file .includes. The device models used by the spice subckt netlists in model_file are also .included in spice_file. Power and ground names are specified with the -power and -ground arguments. The spice netlist includes a piecewise linear voltage source at the input and .measure statement for each gate delay and pin slew. - Example command: - write_path_spice -path_args {-from "in0" -to "out1" -unconstrained} \ -spice_directory $result_dir \ -lib_subckt_file "write_spice1.subckt" \ -model_file "write_spice1.models" \ -power VDD -ground VSS - When the simulator is hspice, .measure statements will be added to the spice netlist. - When the simulator is Xyce, the .print statement selects the CSV format and writes the waveform data to a file name path_<id>.csv so the results can be used by gnuplot. - - - - - - write_sdc - - - [-digits digits][-gzip][-no_timestamp]filename - - - - - - digits - - - The number of digits after the decimal point to report. The default is 4. - - - - - -gzip - - - Compress the SDC with gzip. - - - - - -no_timestamp - - - Do not include a time and date in the SDC file. - - - - - filename - - - The name of the file to write the constraints to. - - - - Write the constraints for the design in SDC format to filename. - - - - - - write_sdf - - - [-scene scene][-divider /|.][-include_typ][-digits digits][-gzip][-no_timestamp][-no_version]filename - - - - - scene - - - Write delays for scene. - - - - - -divider - - - Divider to use between hierarchy levels in pin and instance names. - - - - - -include_typ - - - Include a 'typ' value in the SDF triple that is the average of min and max delays to satisfy some Verilog simulators that require three values in the delay triples. - - - - - -digits digits - - - The number of digits after the decimal point to report. The default is 4. - - - - - -gzip - - - Compress the SDF using gzip. - - - - - -no_timestamp - - - Do not write a DATE statement. - - - - - -no_version - - - Do not write a VERSION statement. - - - - - filename - - - The SDF filename to write. - - - - Write the delay calculation delays for the design in SDF format to filename. If -corner is not specified the min/max delays are across all corners. With -corner the min/max delays for corner are written. The SDF TIMESCALE is same as the time_unit in the first liberty file read. - - - - - - write_timing_model - - - [-library_name lib_name][-cell_name cell_name] - [-scene scene]filename - - - - - - lib_name - - - The name to use for the liberty library. Defaults to cell_name. - - - - - cell_name - - - The name to use for the liberty cell. Defaults to the top level module name. - - - - - scene - - - The scene to use for extracting the model. - - - - - filename - - - Filename for the liberty timing model. - - - - The write_timing_model command constructs a liberty timing model for the current design and writes it to filename. cell_name defaults to the cell name of the top level block in the design. - The SDC used to extract the block should include the clock definitions. If the block contains a clock network set_propagated_clock should be used so the clock delays are included in the timing model. The following SDC commands are ignored when building the timing model. - set_input_delayset_output_delayset_loadset_timing_derate - Using set_input_transition with the slew from the block context will be used will improve the match between the timing model and the block netlist. Paths defined on clocks that are defined on internal pins are ignored because the model has no way to include the clock definition. - The resulting timing model can be used in a hierarchical timing flow as a replacement for the block to speed up timing analysis. This hierarchical timing methodology does not handle timing exceptions that originate or terminate inside the block. The timing model includes: - combinational paths between inputs and outputssetup and hold timing constraints on inputsclock to output timing paths - Resistance of long wires on inputs and outputs of the block cannot be modeled in Liberty. To reduce inaccuracies from wire resistance in technologies with resistive wires place buffers on inputs and ouputs. - The extracted timing model setup/hold checks are scalar (no input slew dependence). Delay timing arcs are load dependent but do not include input slew dependency. - - - - - - write_verilog - - - [-include_pwr_gnd][-remove_cells lib_cells]filename - - - - - -include_pwr_gnd - - - Include power and ground pins on instances. - - - - - -remove_cells lib_cells - - - Liberty cells to remove from the Verilog netlist. Use get_lib_cells, a list of cells names, or a cell name with wildcards. - - - - - filename - - - Filename for the liberty library. - - - - The write_verilog command writes a Verilog netlist to filename. Use -sort to sort the instances so the results are reproducible across operating systems. Use -remove_cells to remove instances of lib_cells from the netlist. - Filter Expressions - The get_cells, get_pins, get_ports and get_timing_edges functions support filtering the returned objects by property values. Supported filter expressions are shown below. - - - - - - property - - - Return objects with property value equal to 1. - - - - - property==value - - - Return objects with property value equal to value. - - - - - property=~pattern - - - Return objects with property value that matches pattern. - - - - - property!=value - - - Return objects with property value not equal to value. - - - - - property!~value - - - Return objects with property value that does not match pattern. - - - - - expr1&&expr2 - - - Return objects with expr1 and expr2. expr1 and expr2 are one of the first three property value forms shown above. - - - - - expr1||expr2 - - - Return objects with expr1 or expr2. expr1 and expr2 are one of the first three property value forms shown above. - - - - Where property is a property supported by the get_property command. Note that if there are spaces in the expression it must be enclosed in quotes so that it is a single argument. - Variables - - - - - - hierarchy_separator - - - Any character. - - - - The hierarchy_separator separates instance names in a hierarchical instance, net, or pin name. The default value is '/'. - - - - - - sta_continue_on_error - - - 0|1 - - - - The include and read_sdc commands stop and report any errors encountered while reading a file unless sta_continue_on_error is 1. The default value is 0. - - - - - - sta_crpr_mode - - - same_pin|same_transition - - - - When the data and clock paths of a timing check overlap (see sta_crpr_enabled), pessimism is removed independent of whether of the path rise/fall transitions. When sta_crpr_mode is same_transition, the pessimism is only removed if the path rise/fall transitions are the same. The default value is same_pin. - - - - - - - sta_cond_default_arcs_enabled - - - 0|1 - - - - When set to 0, default timing arcs with no condition (Liberty timing arcs with no “when” expression) are disabled if there are other conditional timing arcs between the same pins. The default value is 1. - - - - - - sta_crpr_enabled - - - 0|1 - - - - During min/max timing analysis for on_chip_variation the data and clock paths may overlap. For a setup check the maximum path delays are used for the data and the minimum path delays are used for the clock. Because the gates cannot simultaneously have minimum and maximum delays the timing check slack is pessimistic. This pessimism is known as Common Reconvergent Pessimism Removal, or “CRPR”. Enabling CRPR slows down the analysis. The default value is 1. - - - - - - sta_dynamic_loop_breaking - - - 0|1 - - - - When sta_dynamic_loop_breaking is 0, combinational logic loops are disabled by disabling a timing arc that closes the loop. When sta_dynamic_loop_breaking is 1, all paths around the loop are reported. The default value is 0. - - - - - - sta_gated_clock_checks_enabled - - - 0|1 - - - - When sta_gated_clock_checks_enabled is 1, clock gating setup and hold timing checks are checked. The default value is 1. - - - - - - sta_input_port_default_clock - - - 0|1 - - - - When sta_input_port_default_clock is 1 a default input arrival is added for input ports that do not have an arrival time specified with the set_input_delay command. The default value is 0. - - - - - - sta_internal_bidirect_instance_paths_enabled - - - 0|1 - - - - When set to 0, paths from bidirectional (inout) ports back into the instance are disabled. When set to 1, paths from bidirectional ports back into the instance are enabled. The default value is 0. - - - - - - sta_pocv_mode - - - scalar|normal|skew_normal - - - - Enable parametric on chip variation using statistical timing analysis. The default value is scalar. - - - - - - sta_pocv_quartile - - - quartile - - - - The target quantile of a delay probability distribution (confidence level).The default value is 3 standard deviations, or sigma. - - - - - - sta_propagate_all_clocks - - - 0|1 - - - - All clocks defined after sta_propagate_all_clocks is set to 1 are propagated. If it is set before any clocks are defined it has the same effect as - set_propagated_clock [all_clocks] - After all clocks have been defined. The default value is 0. - - - - - - sta_propagate_gated_clock_enable - - - 0|1 - - - - When set to 1, paths of gated clock enables are propagated through the clock gating instances. If the gated clock controls sequential elements setting sta_propagate_gated_clock_enable to 0 prevents spurious paths from the clock enable. The default value is 1. - - - - - - sta_recovery_removal_checks_enabled - - - 0|1 - - - - When sta_recovery_removal_checks_enabled is 0, recovery and removal timing checks are disabled. The default value is 1. - - - - - - sta_report_default_digits - - - integer - - - - The number of digits to print after a decimal point. The default value is 2. - - - - - - sta_preset_clear_arcs_enabled - - - 0|1 - - - - When set to 1, paths through asynchronous preset and clear timing arcs are searched. The default value is 0. - - - - Alphabetical Index - - - - - - - - - - - - - - - - - - - - - - Alphabetical Index - - all_clocks7 - all_inputs7 - all_outputs8 - all_registers8 - check_setup9 - Command Line Arguments1 - Commands7 - connect_pin9 - create_generated_clock11 - create_voltage_area12 - current_design12 - current_instance13 - define_scene13 - delete_clock13 - delete_from_list13 - delete_generated_clock14 - delete_instance14 - delete_net14 - disconnect_pin14 - elapsed_run_time14 - Example Command Scripts1 - Filter Expressions84 - find_timing_paths15 - get_cells17 - get_clocks17 - get_fanin18 - get_fanout19 - get_full_name19 - get_lib_pins20 - get_libs21 - get_name22 - get_nets22 - get_pins23 - get_ports23 - get_property24 - get_scenes28 - get_timing_edges28 - group_path29 - hierarchy_separator85 - include30 - link_design30 - make_instance30 - make_net31 - Power Analysis3 - read_liberty31 - read_saif32 - read_sdc33 - read_sdf33 - read_spef34 - read_vcd35 - read_verilog35 - redirection5 - replace_activity_annotation36 - replace_cell35 - report_annotated_check36 - report_annotated_delay37 - report_check_types41 - report_checks38 - report_clock_latency42 - report_clock_min_period42 - report_clock_properties43 - report_clock_skew43 - report_dcalc43 - report_disabled_edges44 - report_edges44 - report_instance44 - report_lib_cell44 - report_net45 - report_parasitic_annotation45 - report_power45 - report_slews46 - report_tns46 - report_units46 - report_wns47 - report_worst_slack47 - set_assigned_check48 - set_assigned_delay49 - set_assigned_transition49 - set_case_analysis50 - set_clock_gating_check50 - set_clock_groups51 - set_clock_latency52 - set_clock_transition52 - set_clock_uncertainty53 - set_cmd_units54 - set_data_check55 - set_disable_inferred_clock_gating55 - set_disable_timing55 - set_drive56 - set_driving_cell57 - set_false_path58 - set_fanout_load59 - set_hierarchy_separator59 - set_ideal_latency59 - set_ideal_network59 - set_ideal_transition59 - set_input_delay59 - set_input_transition61 - set_level_shifter_strategy61 - set_level_shifter_threshold61 - set_load61 - set_logic_dc62 - set_logic_one62 - set_logic_zero63 - set_max_area63 - set_max_capacitance63 - set_max_delay63 - set_max_dynamic_power64 - set_max_fanout64 - set_max_leakage_power64 - set_max_time_borrow64 - set_max_transition65 - set_min_capacitance65 - set_min_delay66 - set_min_pulse_width67 - set_mode67 - set_multicycle_path67 - set_operating_conditions68 - set_output_delay69 - set_path_margin70 - set_port_fanout_number70 - set_power_activity70 - set_propagated_clock71 - set_pvt71 - set_resistance73 - set_sense72 - set_timing_derate73 - set_units74 - set_wire_load_min_block_size75 - set_wire_load_mode75 - set_wire_load_model75 - set_wire_load_selection_group75 - SPEF34 - sta_cond_default_arcs_enabled85 - sta_continue_on_error85 - sta_crpr_enabled85 - sta_crpr_mode85 - sta_dynamic_loop_breaking85 - sta_gated_clock_checks_enabled85 - sta_input_port_default_clock86 - sta_internal_bidirect_instance_paths_enabled86 - sta_pocv_enabled86 - sta_preset_clear_arcs_enabled87 - sta_propagate_all_clocks86 - sta_propagate_gated_clock_enable86 - sta_recovery_removal_checks_enabled86 - sta_report_default_digits86 - suppress_msg76 - TCL Interpreter5 - Timing Analysis using SDF2 - Timing Analysis with Multiple Corners and Modes3 - Timing Analysis with Multiple Process Corners2 - unset_case_analysis76 - unset_clock_latency76 - unset_clock_transition76 - unset_clock_uncertainty77 - unset_data_check77 - unset_disable_inferred_clock_gating78 - unset_disable_timing78 - unset_input_delay78 - unset_output_delay79 - unset_path_exceptions79 - unset_power_activity80 - unset_propagated_clock80 - unset_timing_derate80 - unsuppress_msg81 - user_run_time81 - Variables85 - verilog netlist35 - with_output_to_variable81 - write_path_spice81 - write_sdc82 - write_sdf82 - write_timing_model83 - write_verilog84 - - - - Version 3.0.0, Mar 7, 2026Copyright (c) 2026, 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/>. - - - - \ No newline at end of file diff --git a/doc/OpenSTA.pdf b/doc/OpenSTA.pdf deleted file mode 100644 index b261ba45f..000000000 Binary files a/doc/OpenSTA.pdf and /dev/null differ diff --git a/doc/StaApi.txt b/doc/StaApi.md similarity index 50% rename from doc/StaApi.txt rename to doc/StaApi.md index e48eff981..8090d2eb9 100644 --- a/doc/StaApi.txt +++ b/doc/StaApi.md @@ -1,159 +1,120 @@ -# 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 . -# -# 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. +# STA API The STA is built in C++ with heavy use of STL (Standard Template -Libraries). It also uses the zlib library to read compressed Liberty, +Libraries). It also uses the zlib library to read compressed Liberty, Verilog, SDF, SPF, and SPEF files. The sub-directories of the STA code are: -doc - Documentation files. -util - Basic utilities. -liberty - Liberty timing library classes and file reader. -network - Network and library API used by all STA code. -verilog - Verilog netlist reader that implements the network API. -graph - Timing graph built from network and library cell timing arcs. -sdc - SDC timing constraint classes. -sdf - SDF reader, writer and annotator. -dcalc - Delay calculator API and implementations. -search - Search engine used to annotate the graph with arrival, required times - and find timing check slacks. -parasitics - Parasitics API, Spef and Spf readers. -app - Interface between Tcl and STA (built with SWIG). - Main program definition. -tcl - User interface code. - SDC argument parsing. +| Directory | Description | +| --- | --- | +| `doc` | Documentation files. | +| `util` | Basic utilities. | +| `liberty` | Liberty timing library classes and file reader. | +| `network` | Network and library API used by all STA code. | +| `verilog` | Verilog netlist reader that implements the network API. | +| `graph` | Timing graph built from network and library cell timing arcs. | +| `sdc` | SDC timing constraint classes. | +| `sdf` | SDF reader, writer and annotator. | +| `dcalc` | Delay calculator API and implementations. | +| `search` | Search engine used to annotate the graph with arrival, required times and find timing check slacks. | +| `parasitics` | Parasitics API, Spef and Spf readers. | +| `app` | Interface between Tcl and STA (built with SWIG). Main program definition. | +| `tcl` | User interface code. SDC argument parsing. | Each sub-directory builds a library that is linked to build the STA executable or linked into another application. -The file doc/CodingGuidelines.txt defines naming conventions used in +The file [Coding guidelines](CodingGuidelines.md) defines naming conventions used in the code. -STA API -------- - Major components of the STA such as the network, timing graph, sdc, -and search are implemented as separate classes. The Sta class +and search are implemented as separate classes. The `Sta` class contains an instance of each of these components. -The Sta class defines the bulk of the externally visible API used by +The `Sta` class defines the bulk of the externally visible API used by the Tcl interface, and coordinates operations that involve multiple components. For example, when a false path command is entered into -the Tcl command interpreter, the Sta passes the declaration on to the -Sdc component and tells the Search component to invalidate all arrival +the Tcl command interpreter, the `Sta` passes the declaration on to the +`Sdc` component and tells the `Search` component to invalidate all arrival and required times. -Applications should call functions defined by the Sta class rather +Applications should call functions defined by the `Sta` class rather than functions defined by the components. Calling functions defined by the components will get you in trouble unless you understand them in detail. For example, telling the delay calculator to recompute the delays leaves the arrival times that depend on them wrong. Always -remember that the Sta coordinates the components. +remember that the `Sta` coordinates the components. -In general, objects passed as arguments to Sta functions that are +In general, objects passed as arguments to `Sta` functions that are constructors become "owned" by the STA and should not be deleted by the caller. For example, a set of pins passed into -Sta::makeExceptionFrom are used in the resulting object (rather than +`Sta::makeExceptionFrom` are used in the resulting object (rather than copied into another set). On the other hand, strings passed as -arguments are copied by the Sta functions before they are retained in +arguments are copied by the `Sta` functions before they are retained in STA data structures. In many cases the major components contain pointers to other -components. The StaState class is a simple container for these +components. The `StaState` class is a simple container for these components that makes initialization of pointers to the components easier. An STA with modified behavior can be built by defining classes derived from the component classes and overloading some of the member functions (which may have to be modified to be virtual). Components -are created by Sta::makeComponents(). The Sta::makeComponents() -function in turn calls each of the Sta::make component +are created by `Sta::makeComponents()`. The `Sta::makeComponents()` +function in turn calls each of the `Sta::make` component constructors. These constructors can be overloaded by redefining them -in a class derived from Sta. Because the components refer to each -other, Sta::updateComponentsState() must be called to notify the -components if any of them are changed after creation. +in a class derived from `Sta`. Because the components refer to each +other, `Sta::updateComponentsState()` must be called to notify the +components if any of them are changed after creation. -Units ------ +## Units -Units for values in Sta and liberty data structures are always the +Units for values in `Sta` and liberty data structures are always the following: - time seconds - length meters - capacitance farads - resistance ohms +| Quantity | Unit | +| --- | --- | +| time | seconds | +| length | meters | +| capacitance | farads | +| resistance | ohms | +| voltage | volts | +| current | amperes | +| power | watts | All file readers and the user interface are responsible for converting any user input or output to these units. -Utilities ---------- +## Utilities -The most significant utilities are the Vector, Map and Set templated -classes built on top the respective STL classes. The main point of -these classes is to provide Java-like iterators that can be passed -around as one object. STL iterators require the container to be -useful. Iterators uniformly use the hasNext() function to test to see -if there is another member and next() to access the next iteration -member. +The STA uses the C++ standard library containers (`std::vector`, +`std::map`, `std::set`, and related types). Helper functions for +lookups and iteration live in `ContainerHelpers.hh` (`sta::findKey`, +`sta::findKeyValue`, and range helpers). Prefer range-`for` over +hand-written iterators. -All printing done by the STA core is done using the Report class API. +All printing done by the STA core is done using the `Report` class API. The report class supports output redirection to a file and logging to a file. The Tcl interpreter prints to "channels" that are -encapsulated by functions in the the ReportTcl class. Printing inside +encapsulated by functions in the `ReportTcl` class. Printing inside the STA is directed to the Tcl channels so that it appears with the Tcl interpreter output. -Network -------- +## Network The network API is the key to making the STA a timing engine that can be bolted onto another application. This API allows the STA to efficiently communicate with external network data structures without -the overhead of making and maintaining a copying of it. +the overhead of making and maintaining a copy of it. The network API encapsulates both library and netlist accessors. Libraries are composed of cells that have ports that define connections to the cell. Netlists are built out of cell instances, pins and nets. -The ConcreteLibrary and ConcreteNetwork classes are used by the STA -netlist readers (notibly Verilog). These class definitions are to +The `ConcreteLibrary` and `ConcreteNetwork` classes are used by the STA +netlist readers (notably Verilog). These class definitions are to support a stand alone STA that does not depend on external netlist data structures. @@ -169,7 +130,7 @@ iterators are provided for the expanded and unexpanded set of cell ports. Network instances are calls of cells in the design hierarchy. Both -hierarchcial and leaf instances are in the network. Hierarchical +hierarchical and leaf instances are in the network. Hierarchical instances have children instances at the next lower hierarchy level. Leaf instances have liberty cells with timing model data. At the top of the hierarchy is a top level instance that has instances for the @@ -178,7 +139,7 @@ sub-tree of hierarchy is repeated in the network. This "unfolded" network representation allows optimization to specialize instances of a hierarchical block. A "folded" network representation that has only one sub-tree for each hierarchical block means that all copies must -have identical sub-trees, preventing optimations that specialize the +have identical sub-trees, preventing optimizations that specialize the contents. Pins are a connection between an instance and a net corresponding to a @@ -196,66 +157,73 @@ undefined class objects. The implementation and definition of the network objects themselves is never visible inside the STA. The network API is implemented as an adapter that performs all operations on all network objects. There is one network adapter instance used by -all STA code. For example, to find the cell of an instance - - Cell *cell = network->cell(instance); - +all STA code. For example, to find the cell of an instance: + +```cpp +Cell *cell = network->cell(instance); +``` + The network adapter returns iterators for looping over groups of network objects. For example, the following code iterates over the children of the top level instance. - Instance *top_instance = network->topInstance(); - InstanceChildIterator *child_iter = network->childIterator(top_instance); - while (child_iter->hasNext()) { - Instance *child = child_iter->next(); - ... - } - delete child_iter; +```cpp +Instance *top_instance = network->topInstance(); +InstanceChildIterator *child_iter = network->childIterator(top_instance); +while (child_iter->hasNext()) { + Instance *child = child_iter->next(); + ... +} +delete child_iter; +``` An adapter to a network database is built by defining a class derived -from the base class Network, or NetworkEdit if it supports incremental -editing operations. network/ConcreteNetwork.cc is a example of -a network adapter the supports hierarchy. An example of a network adapter -for a flat DEF based netlist, see -https://github.com/The-OpenROAD-Project/OpenROAD/blob/master/src/dbSta/include/db_sta/dbNetwork.hh, -https://github.com/The-OpenROAD-Project/OpenROAD/blob/master/src/dbSta/src/dbNetwork.cc. +from the base class `Network`, or `NetworkEdit` if it supports incremental +editing operations. `network/ConcreteNetwork.cc` is an example of +a network adapter that supports hierarchy. An example of a network adapter +for a flat DEF based netlist is in OpenROAD: +[dbNetwork.hh](https://github.com/The-OpenROAD-Project/OpenROAD/blob/master/src/dbSta/include/db_sta/dbNetwork.hh), +[dbNetwork.cc](https://github.com/The-OpenROAD-Project/OpenROAD/blob/master/src/dbSta/src/dbNetwork.cc). A network adaptor to interface to an external network database must -define the virtual functions of the Network class (about 45 +define the virtual functions of the `Network` class (about 45 functions). The external network objects do not have to use any STA network objects as base classes or even be C++ objects. These network adapter functions should cast the network object pointers to the underlying network object. -Network adapters built on the Network class must define the following +Network adapters built on the `Network` class must define the following functions to find corresponding liberty objects. - virtual LibertyLibrary *libertyLibrary(Library *library) const; - virtual LibertyLibrary *makeLibertyLibrary(const char *name, - LibraryAnalysisPt *ap); - virtual LibertyCell *libertyCell(Cell *cell) const; - virtual LibertyPort *libertyPort(Port *port) const; +```cpp +virtual LibertyLibrary *libertyLibrary(Library *library) const; +virtual LibertyLibrary *makeLibertyLibrary(const char *name, + LibraryAnalysisPt *ap); +virtual LibertyCell *libertyCell(Cell *cell) const; +virtual LibertyPort *libertyPort(Port *port) const; +``` -The NetworkLiberty class provides implementations of the first two +The `NetworkLiberty` class provides implementations of the first two functions for derived network classes. -If the network adapter implements the NetworkEdit API the following -TCL commands are supported: - - make_cell - replace_cell - delete_cell - make_net - delete_net - connect_pins - disconnect_pins - -Each of these commands call correponding functions in app/StaTcl.i -that notify the Sta before and/or after the network operation is +If the network adapter implements the `NetworkEdit` API the following +Tcl commands are supported: + +```tcl +make_cell +replace_cell +delete_cell +make_net +delete_net +connect_pins +disconnect_pins +``` + +Each of these commands call corresponding functions in `network/NetworkEdit.i` +that notify the `Sta` before and/or after the network operation is performed. -Liberty -------- +## Liberty The liberty timing library reader builds classes that are derived from the concrete library classes. In addition to the library, cell and @@ -268,30 +236,35 @@ ports. For example, a buffer has two timing arcs between the input and output; one for a rising output and another for a falling output. The timing arcs are: - A r -> Z r - A f -> Z f +``` +A r -> Z r +A f -> Z f +``` Since a buffer is non-inverting, the timing arc set is positive-unate. Similarly, an inverter has two negative-unate timing arcs. - A f -> Z r - A r -> Z f +``` +A f -> Z r +A r -> Z f +``` On the other hand, a multiplexor, has a non-unate path from the select input to the output because a rise or fall change on the input can cause the output to either rise or fall. There are four timing arcs in this arc set: - S f -> Z r - S f -> Z f - S r -> Z r - S r -> Z f +``` +S f -> Z r +S f -> Z f +S r -> Z r +S r -> Z f +``` The liberty file reader can be customized to read attributes that are not used by the STA. -Graph ------ +## Graph The timing graph is the central data structure used by the delay calculation and search algorithms. It is annotated with timing arc @@ -303,77 +276,83 @@ The graph is composed of vertices and edges. Each pin in the design has a vertex. Bidirect pins have two vertices, one for its use as an input and another for its use as an output. -The Network adapter supplies functions to find and set the index +The `Network` adapter supplies functions to find and set the index (unsigned) of a graph vertex corresponding to a pin. - Network::vertexIndex(const Pin *pin) const; - Network::setVertexIndex(Pin *pin, VertexIndex index); +```cpp +Network::vertexIndex(const Pin *pin) const; +Network::setVertexIndex(Pin *pin, VertexIndex index); +``` An STL map can be used for the lookup, but it is rather memory hungry compared to storing the value in the pin structure. A pointer to the vertex used for a bidirectional pin driver is kept in -a map owned by the Graph class. +a map owned by the `Graph` class. Edges in the graph connect vertices. The pins connected together by a net have wire edges between the pin vertices. Timing arc sets in the leaf instance timing models have corresponding edges in the graph between pins on the instance. -SDC ---- +## SDC There is no support for updating SDC when network edits delete -the instance, pin, or net objects refered to by the SDC. +the instance, pin, or net objects referred to by the SDC. -Delay Calculation ------------------ +## Delay Calculation The graph is annotated with arc delay values and slews (also known as transition times) by the graph delay calculator or the SDF reader. -The GraphDelayCalc class seeds slews from SDC constraints and uses a -breadth first search to visit each gate output pin. The GraphDelayCalc +The `GraphDelayCalc` class seeds slews from SDC constraints and uses a +breadth first search to visit each gate output pin. The `GraphDelayCalc` then calls a timing arc delay calculator for each timing arc and annotates the graph arc delays and vertex slews. -The delay calculator is architeched to support multiple delay +The delay calculator is architected to support multiple delay calculation results. Each result has an associated delay calculation -analysis point (class DcalcAnalysisPt) that specifies the operating +analysis point (class `DcalcAnalysisPt`) that specifies the operating conditions and parasitics used to find the delays. -The ArcDelayCalc class defines the API used by the GraphDelayCalc to +The `ArcDelayCalc` class defines the API used by the `GraphDelayCalc` to calculate the gate delay, driver slew, load delays and load slews driven by a timing arc. The following delay calculation algorithms -are defined in the dcalc directory: +are defined in the `dcalc` directory. + +### `UnitDelayCalc` + +All gate delays are 1. Wire delays are zero. + +### `LumpedCapArcDelayCalc` + +Liberty table models using lumped capacitive load (RSPF pi model +total capacitance). Wire delays are zero. - UnitDelayCalc - All gate delays are 1. Wire delays are zero. +### `DmpCeffElmoreDelayCalc` - LumpedCapArcDelayCalc - Liberty table models using lumped capacitive - load (RSPF pi model total capacitance). Wire delays are zero. +RSPF (Driver Pi model with elmore interconnect delays) delay +calculator. Liberty table models using effective capacitive model as +described in "Performance Computation for Precharacterized CMOS Gates +with RC Loads", Florentin Dartu, Noel Menezes and Lawrence Pileggi, +IEEE Transactions on Computer-Aided Design of Integrated Circuits and +Systems, Vol 15, No 5, May 1996. Wire delays are computed by applying +the driver waveform to the RSPF dependent source and solving the RC +network. - DmpCeffElmoreDelayCalc - RSPF (Driver Pi model with elmore interconnect - delays) delay calculator. Liberty table models using effective capacitive - model as described in the following paper: - "Performance Computation for Precharacterized CMOS Gates with RC Loads", - Florentin Dartu, Noel Menezes and Lawrence Pileggi, IEEE Transactions - on Computer-Aided Design of Integrated Circuits and Systems, Vol 15, No 5, - May 1996. - Wire delays are computed by applying the driver waveform to - the RSPF dependent source and solving the RC network. +### `DmpCeffTwoPoleDelayCalc` - DmpCeffTwoPoleDelayCalc - Driver Pi model with two pole interconnect - delays and effective capacitance as in DmpCeffElmoreDelayCalc. +Driver Pi model with two pole interconnect delays and effective +capacitance as in `DmpCeffElmoreDelayCalc`. Other delay calculators can be interfaced by defining a class based on -ArcDelayCalc and using the registerDelayCalc function to register it -for the "set_delay_calculator" Tcl command. The Sta::setArcDelayCalc +`ArcDelayCalc` and using the `registerDelayCalc` function to register it +for the `set_delay_calculator` Tcl command. The `Sta::setArcDelayCalc` function can be used to set the delay calculator at run time. -Search ------- +## Search A breadth first forward search is used to find arrival times at graph -vertices. Vertices are annotated with instances of the Event class to +vertices. Vertices are annotated with instances of the `Event` class to record signal arrival and required times. As each vertex is visited in the forward search its required time is found using If the vertex is constrained by setup or hold timing checks, min/max path delay @@ -393,19 +372,21 @@ for any vertex with a lower/higher logic level when the arrival/required time is requested. Clock arrival times are found before data arrival times by -Search::findClkArrivals(). Clock arrival times include insertion delay +`Search::findClkArrivals()`. Clock arrival times include insertion delay (source latency). When an incremental netlist change is made (for instance, changing the -drive strengh of a gate with swap_cell), the STA incrementally updates +drive strength of a gate with `swap_cell`), the STA incrementally updates delay calculation, arrival times, required times and slacks. Because gate delay is only weakly dependent on slew, the effect of the change -will diminish in gates downstream of the change. The STA uses a +will diminish in gates downstream of the change. The STA uses a tolerance on the gate delays to determine when to stop propagating the change. The tolerance is set using the -Sta::setIncrementalDelayTolerance function. +`Sta::setIncrementalDelayTolerance` function. - void Sta::setIncrementalDelayTolerance(float tol); +```cpp +void Sta::setIncrementalDelayTolerance(float tol); +``` The tolerance is a percentage (0.0:1.0) change in delay that causes downstream delays to be recomputed during incremental delay @@ -416,144 +397,147 @@ than the tolerance. Required times must be recomputed backward from any gate delay changes, so increasing the tolerance can significantly reduce incremental timing run time. -Tcl Interface -------------- +## Tcl Interface -The interface from Tcl to C++ is written in a SWIG (www.swig.org) -interface description (tcl/StaTcl.i). SWIG generates the interface -code from the description file. +The interface from Tcl to C++ is written in a SWIG +([www.swig.org](https://www.swig.org)) interface description +(`app/StaApp.i`). SWIG generates the interface code from the +description file. All commands are written in Tcl. SDC argument parsing and checking is done with Tcl procedures that call a SWIG interface function. -The Tcl 'sta' namespace is used to segregate internal STA functions +The Tcl `sta` namespace is used to segregate internal STA functions from the global Tcl namespace. All user visible STA and SDC commands are exported to the global Tcl namespace. A lot of the internal STA state can be accessed from Tcl to make -debugging a easier. Some debugging commands require a namespace -qualifier because they are not intended for casual users. Some -examples are shown below. - - sta::report_arrival - sta::report_required - sta::report_slack - sta::report_edges - sta::report_slews - sta::report_level pin - sta::report_constant pin|instance - sta::report_network - - sta::network_pin_count - sta::network_net_count - sta::network_leaf_instance_count - sta::network_leaf_pin_count - -Additionally, many of the STA network and graph objects themselvs are +debugging easier. Some debugging commands are not intended for casual +users and live in the `sta` namespace. Others, such as `report_arrival`, +`report_required`, `report_slack`, and `report_edges`, are also exported +to the global namespace. Examples: + +```tcl +report_arrival +report_required +report_slack +report_edges +report_slews +sta::report_level pin +sta::report_constant pin|instance +sta::report_network + +sta::network_pin_count +sta::network_net_count +sta::network_leaf_instance_count +sta::network_leaf_pin_count +``` + +Additionally, many of the STA network and graph objects themselves are exposed to Tcl using SWIG. These Tcl objects have methods for inspecting them. Examples of how to use these methods can be found in -the tcl/Graph.tcl and tcl/Network.tcl files. +the `tcl/Graph.tcl` and `tcl/Network.tcl` files. -Architecture alternatives for using the STA Engine --------------------------------------------------- +## Architecture alternatives for using the STA Engine There are a number of alternatives for using the STA engine with an application. -* STA with TCL application +### STA with Tcl application -The simplest example is an application written in TCL. The application -calls STA commands and primitives defined in the swig c++/tcl -interface. A stand-alone STA executable is built and a TCL file that +The simplest example is an application written in Tcl. The application +calls STA commands and primitives defined in the SWIG C++/Tcl +interface. A stand-alone STA executable is built and a Tcl file that defines the application is included as part of the STA by modifying -CMakeLists.txt to add the TCL file to app/TclInitVar.cc. +`CMakeLists.txt` to add the Tcl file to `STA_TCL_FILES` (encoded into +`StaTclInitVar.cc`). The user calls STA commands to read design files (liberty, verilog, SDF, parasitics) to define and link the design. The user defines SDC -commands or sources an SDC file. The user calls the application's TCL +commands or sources an SDC file. The user calls the application's Tcl commands. A simple gate sizer is an example of an application that can be built this way because it has very little computation in the sizer itself. -STA TCL commands can be used to find the worst path and upsize gates +STA Tcl commands can be used to find the worst path and upsize gates or insert buffers. -* STA with C++ application +### STA with C++ application -The application is built by adding C++ files to the /app directory and -modifying CMakeLists.txt to include them in the executable. Interface -commands between C++ and TCL are put in a SWIG .i file in the /app -directory and modifying app/StaApp.i to include them. TCL commands are -added to the STA by modifying CMakeLists.txt to add the application's -TCL files to TclInitVar.cc. +The application is built by adding C++ files to the `app` directory and +modifying `CMakeLists.txt` to include them in the executable. Interface +commands between C++ and Tcl are put in a SWIG `.i` file in the `app` +directory and modifying `app/StaApp.i` to include them. Tcl commands are +added to the STA by modifying `CMakeLists.txt` to add the application's +Tcl files to `STA_TCL_FILES`. The user calls STA commands to read design files (liberty, verilog, SDF, parasitics) to define and link the design. The user defines SDC -commands or sources an SDC file. The user calls the application's TCL +commands or sources an SDC file. The user calls the application's Tcl commands. -* C++ application without native Network data structures linking STA libraries +### C++ application without native Network data structures linking STA libraries -The application builds main() and links STA libraries. On startup it -calls STA initialization functions like staMain() defined in -app/StaMain.cc. +The application builds `main()` and links STA libraries. On startup it +calls STA initialization functions like `staMain()` defined in +`app/StaMain.cc`. -The application must link and instanciate a TCL interpreter to read -SDC commands like staMain(). The application can choose to expose the TCL +The application must link and instantiate a Tcl interpreter to read +SDC commands like `staMain()`. The application can choose to expose the Tcl interpreter to the user or not. The STA depends on the following data -that can be read by calling TCL commands or Sta class member functions. +that can be read by calling Tcl commands or `Sta` class member functions. -Liberty files that define the leaf cells used in the design. -Read using the read_liberty command or by calling Sta::readLibertyFile(). +Liberty files that define the leaf cells used in the design. +Read using the `read_liberty` command or by calling `Sta::readLibertyFile()`. -Verilog files that define the netlist. Read using the read_verilog -command or by calling readVerilogFile() (see verilog/Verilog.i -read_verilog). +Verilog files that define the netlist. Read using the `read_verilog` +command or by calling `readVerilogFile()` (see `verilog/Verilog.i` +`read_verilog`). -Link the design using the link_design command or calling Sta::linkDesign(). +Link the design using the `link_design` command or calling `Sta::linkDesign()`. SDC commands to define timing constraints. -Defined using SDC commands in the TCL interpreter, or sourced -from a file using Tcl_Eval(sta::tclInterp()). +Defined using SDC commands in the Tcl interpreter, or sourced +from a file using `Tcl_Eval(sta::tclInterp())`. Parasitics used by delay calculation. -Read using the read_parasitics command, Sta::readParasitics(), or -using the Sta::Parasitics class API. +Read using the `read_spef` command, `Sta::readSpef()`, or +using the `Sta::Parasitics` class API. The application calls network editing functions such as -Sta::deleteInstance() to edit the network. +`Sta::deleteInstance()` to edit the network. -* C++ application with native Network data structures linking STA libraries +### C++ application with native Network data structures linking STA libraries The application defines a Network adapter (described above) so that the STA can use the native network data structures without duplicating -them in the STA. The application defines a class built on class Sta -that defines the makeNetwork() member function to build an instance of +them in the STA. The application defines a class built on class `Sta` +that defines the `makeNetwork()` member function to build an instance of the network adapter. -The application builds main() and links STA libraries. On startup it -calls STA initialization functions like staMain() defined in -app/StaMain.cc. The application reads the netlist and builds network +The application builds `main()` and links STA libraries. On startup it +calls STA initialization functions like `staMain()` defined in +`app/StaMain.cc`. The application reads the netlist and builds network data structures that the STA accesses through the Network adapter. -The application must link and instanciate a TCL interpreter to read -SDC commands like staMain(). The application can choose to expose the TCL +The application must link and instantiate a Tcl interpreter to read +SDC commands like `staMain()`. The application can choose to expose the Tcl interpreter to the user or not. The STA depends on the following data -that can be read by calling TCL commands or Sta class member functions. +that can be read by calling Tcl commands or `Sta` class member functions. -Liberty files that define the leaf cells used in the design. -Read using the read_liberty command or by calling Sta::readLibertyFile. +Liberty files that define the leaf cells used in the design. +Read using the `read_liberty` command or by calling `Sta::readLibertyFile`. SDC commands to define timing constraints. -Defined using SDC commands in the TCL interpreter, or sourced -from a file using sta::sourceTclFile. +Defined using SDC commands in the Tcl interpreter, or sourced +from a file using `sta::sourceTclFile`. Parasitics used by delay calculation. -Read using the read_parasitics command, Sta::readParasitics(), or -using the Sta::Parasitics class API. +Read using the `read_spef` command, `Sta::readSpef()`, or +using the `Sta::Parasitics` class API. The application calls network editing before/after functions such as -Sta::deleteInstanceBefore() to notify the Sta of network edits. +`Sta::deleteInstanceBefore()` to notify the `Sta` of network edits. A placement tool is likely to use this pattern to integrate the STA because the DEF file includes netlist connectivity. diff --git a/doc/TclInterpreter.md b/doc/TclInterpreter.md new file mode 100644 index 000000000..8ff3fbce4 --- /dev/null +++ b/doc/TclInterpreter.md @@ -0,0 +1,32 @@ +# Tcl interpreter + +Keyword arguments to commands may be abbreviated. For example, + +```tcl +report_checks -unique +``` + +is equivalent to + +```tcl +report_checks -unique_paths_to_endpoint +``` + +The `help` command lists matching commands and their arguments. + +```tcl +% help report_checks +report_checks [-from from_list|-rise_from from_list|-fall_from from_list] + ... +``` + +Use `help -verbose ` to print the full description and option +list. Use `help ` for documented `sta_*` variables. + +Many reporting commands support redirection of the output to a file +much like a Unix shell. + +```tcl +report_checks -to out1 > path.log +report_checks -to out2 >> path.log +``` diff --git a/doc/index.md b/doc/index.md new file mode 100644 index 000000000..c5eb9a8e7 --- /dev/null +++ b/doc/index.md @@ -0,0 +1,10 @@ +# OpenSTA documentation + +OpenSTA is a gate-level static timing analyzer. + +Use the navigation to browse the user guide, command reference, and +developer notes. Command, variable, and CLI pages are generated from a +built `sta` binary and are not checked in. Use `help ` in the +Tcl interpreter for the same command documentation that appears here. + +Contributors should sign the [Contributor License Agreement](CLA.txt). diff --git a/doc/requirements.txt b/doc/requirements.txt new file mode 100644 index 000000000..4b20f2b48 --- /dev/null +++ b/doc/requirements.txt @@ -0,0 +1,3 @@ +mkdocs>=1.6,<2 +mkdocs-material>=9.5,<10 +pymdown-extensions>=10.0 diff --git a/etc/CheckCmdHelp.tcl b/etc/CheckCmdHelp.tcl new file mode 100644 index 000000000..361bcc23f --- /dev/null +++ b/etc/CheckCmdHelp.tcl @@ -0,0 +1,94 @@ +#!/bin/sh +# The next line is executed by /bin/sh, but not Tcl \ +exec sta -no_splash -no_init -exit $0 ${1+"$@"} + +# OpenSTA, Static Timing Analyzer +# Copyright (c) 2026, Parallax Software, Inc. +# +# Hidden commands may have a synopsis but no -help prose, so they are +# omitted from the generated command reference. Exit 1 if any other +# command is missing help. +# Usage: sta -no_splash -no_init -exit etc/CheckCmdHelp.tcl + +namespace eval sta { + +# Exported commands that are intentionally undocumented (internal or +# specialist). They are skipped by WriteCmdDocs.tcl. +variable hidden_cmds { + report_constant + report_path + set_ideal_net + show_copying + show_splash + show_warranty + write_gate_gnuplot + write_gate_spice +} + +proc check_cmd_help {} { + variable cmd_args + variable cmd_help + variable hidden_cmds + + set missing {} + foreach cmd [lsort [array names cmd_args]] { + if { ![info exists cmd_help($cmd)] || $cmd_help($cmd) == "" } { + lappend missing $cmd + } + } + + set unexpected {} + set hidden {} + foreach cmd $missing { + if { [lsearch -exact $hidden_cmds $cmd] >= 0 } { + lappend hidden $cmd + } else { + lappend unexpected $cmd + } + } + + puts "Hidden commands: [llength $hidden]" + foreach cmd $hidden { + puts " $cmd" + } + + if { $unexpected != {} } { + puts stderr "Commands missing help that are not hidden:" + foreach cmd $unexpected { + puts stderr " $cmd" + } + exit 1 + } +} + +proc check_cmd_arg_help {} { + variable cmd_args + variable cmd_help + + set missing_pairs {} + foreach cmd [lsort [array names cmd_args]] { + if { ![info exists cmd_help($cmd)] || $cmd_help($cmd) == "" } { + continue + } + foreach opt [cmd_synopsis_options $cmd_args($cmd)] { + if { [cmd_arg_help_text $cmd $opt] == "" } { + lappend missing_pairs [list $cmd $opt] + } + } + } + + if { $missing_pairs != {} } { + puts stderr "Documented commands with undocumented options:" + foreach pair $missing_pairs { + lassign $pair cmd opt + puts stderr " $cmd $opt" + } + exit 1 + } +} + +check_cmd_help +check_cmd_arg_help + +# namespace end +} diff --git a/etc/FindMessages.tcl b/etc/FindMessages.tcl index 40f00d292..0baa1f2fb 100755 --- a/etc/FindMessages.tcl +++ b/etc/FindMessages.tcl @@ -27,7 +27,7 @@ exec tclsh $0 ${1+"$@"} # This notice may not be removed or altered from any source distribution. # Find warning/error message IDs and detect collisions. -# Usage: FindMessages.tcl > doc/messages.txt +# Usage: FindMessages.tcl [doc/Messages.md] set has_error 0 @@ -91,12 +91,32 @@ proc check_msgs { } { } } -proc report_msgs { } { +proc md_escape { text } { + return [string map {| \\| ` \\`} $text] +} + +proc report_msgs { {out_file ""} } { global msgs + if { $out_file != "" } { + set out [open $out_file w] + } else { + set out stdout + } + puts $out "# Messages" + puts $out "" + puts $out "This page is generated by `etc/FindMessages.tcl`." + puts $out "Do not edit it by hand; rebuild OpenSTA to regenerate." + puts $out "" + puts $out "| ID | Location | Message |" + puts $out "| --- | --- | --- |" foreach msg_info $msgs { lassign $msg_info msg_id file line msg1 - puts "[format %04d $msg_id] [format %-25s [file tail $file]:$line] $msg1" + set loc "[file tail $file]:$line" + puts $out "| [format %04d $msg_id] | $loc | [md_escape $msg1] |" + } + if { $out_file != "" } { + close $out } } @@ -104,7 +124,11 @@ set msgs {} scan_files $files_c $warn_regexp_c scan_files $files_tcl $warn_regexp_tcl check_msgs -report_msgs +if { $argc >= 1 } { + report_msgs [lindex $argv 0] +} else { + report_msgs +} if {$has_error} { exit 1 diff --git a/etc/WriteCmdDocs.tcl b/etc/WriteCmdDocs.tcl new file mode 100644 index 000000000..f6c0e428f --- /dev/null +++ b/etc/WriteCmdDocs.tcl @@ -0,0 +1,254 @@ +#!/bin/sh +# The next line is executed by /bin/sh, but not Tcl \ +exec sta -no_splash -no_init -exit $0 ${1+"$@"} + +# OpenSTA, Static Timing Analyzer +# Copyright (c) 2026, Parallax Software, Inc. +# +# Write doc/Commands.md, doc/Variables.md, and doc/CommandLine.md +# from the live command/variable help registry. These files are not +# checked in; CMake and Read the Docs regenerate them. +# Usage: sta -no_splash -no_init -exit etc/WriteCmdDocs.tcl + +namespace eval sta { + +proc write_cmd_docs {} { + set script [info script] + set sta_home [file dirname [file dirname [file normalize $script]]] + write_commands_md [file join $sta_home doc Commands.md] + write_variables_md [file join $sta_home doc Variables.md] + write_command_line_md [file join $sta_home doc CommandLine.md] +} + +proc write_commands_md { path } { + variable cmd_args + + set f [open $path w] + puts $f "# Commands" + puts $f "" + puts $f "This page is generated from the live command registry." + puts $f "Do not edit it by hand; rebuild `sta` to regenerate." + puts $f "" + puts $f "Use `help ` in the Tcl interpreter for the same text." + puts $f "" + + foreach cmd [lsort [array names cmd_args]] { + set desc [cmd_help_text $cmd] + if { $desc == "" } { + # Hidden commands (etc/CheckCmdHelp.tcl hidden_cmds) have no prose. + continue + } + puts $f "## $cmd" + puts $f "" + # HTML
 so option flags can link to the descriptions below.
+    # A markdown fence cannot contain links.
+    puts $f "
[cmd_synopsis_html $cmd]
" + puts $f "" + puts $f $desc + puts $f "" + set opts [cmd_synopsis_options $cmd_args($cmd)] + set any 0 + foreach opt $opts { + set opt_desc [cmd_arg_help_text $cmd $opt] + if { $opt_desc != "" } { + if { !$any } { + puts $f "### Options" + puts $f "" + set any 1 + } + write_opt_help_md $f $cmd $opt $opt_desc + } + } + } + close $f +} + +# Split "`min`: foo. `max`: bar." style help into one list item per value. +proc enum_help_items { desc } { + set re {`[^`]+`: } + set spans [regexp -all -inline -indices $re $desc] + if { [llength $spans] < 2 } { + return {} + } + set items {} + set n [llength $spans] + for { set i 0 } { $i < $n } { incr i } { + lassign [lindex $spans $i] start end + set marker [string range $desc $start $end] + regexp {`([^`]+)`: } $marker -> token + if { $i + 1 < $n } { + lassign [lindex $spans [expr { $i + 1 }]] next_start + set text [string range $desc [expr { $end + 1 }] \ + [expr { $next_start - 1 }]] + } else { + set text [string range $desc [expr { $end + 1 }] end] + } + lappend items [list $token [string trim $text]] + } + return $items +} + +proc write_opt_help_md { f cmd opt desc } { + puts $f "`$opt` \{: #[cmd_opt_anchor $cmd $opt] \}" + set items [enum_help_items $desc] + if { $items != {} } { + set first 1 + foreach item $items { + lassign $item token text + if { $first } { + puts $f ": - `$token`: $text" + set first 0 + } else { + puts $f " - `$token`: $text" + } + } + } else { + set lines [split $desc "\n"] + puts $f ": [lindex $lines 0]" + foreach line [lrange $lines 1 end] { + puts $f " $line" + } + } + puts $f "" +} + +proc html_escape { s } { + return [string map {& & < < > > \" "} $s] +} + +# Fragment for a documented option, unique per command (many share -from). +proc cmd_opt_anchor { cmd opt } { + return "opt-$cmd-[string range $opt 1 end]" +} + +# One option/argument token per line so long synopses stay readable. +# Documented flags are links to the option description. +proc cmd_synopsis_html { cmd } { + variable cmd_args + + set arglist [string trim $cmd_args($cmd)] + set html [html_escape $cmd] + if { $arglist == "" } { + return $html + } + set tokens [cmd_synopsis_tokens $arglist] + if { $tokens == {} } { + append html " " [html_escape $arglist] + return $html + } + foreach tok $tokens { + append html "\n " [cmd_synopsis_token_html $cmd $tok] + } + return $html +} + +proc cmd_synopsis_token_html { cmd token } { + variable cmd_args + + set html "" + set i 0 + set n [string length $token] + while { $i < $n } { + set rest [string range $token $i end] + if { [regexp {^(-[a-zA-Z][a-zA-Z0-9_]*)} $rest match] } { + set desc [cmd_arg_help_text $cmd $match] + if { $desc != "" } { + set canon [cmd_arg_help_group_canonical $cmd_args($cmd) $match] + set href [cmd_opt_anchor $cmd $canon] + append html "[html_escape $match]" + } else { + append html [html_escape $match] + } + incr i [string length $match] + } else { + append html [html_escape [string index $token $i]] + incr i + } + } + return $html +} + +# Same token split as show_cmd_args in tcl/CmdUtil.tcl: a [bracketed] +# group or a word of letters, digits, _, |, -, and backslash. +proc cmd_synopsis_tokens { arglist } { + set tokens {} + while {1} { + if {[regexp {(^[\n ]*)([a-zA-Z0-9_\\\|\-]+|\[[^\[]+\])(.*)} \ + $arglist ignore space arg rest]} { + lappend tokens $arg + set arglist $rest + } else { + set rest [string trim $arglist] + if { $rest != "" } { + lappend tokens $rest + } + break + } + } + return $tokens +} + +proc write_variables_md { path } { + variable var_help + + set f [open $path w] + puts $f "# Variables" + puts $f "" + puts $f "This page is generated from `define_var_help`." + puts $f "Do not edit it by hand; rebuild `sta` to regenerate." + puts $f "" + puts $f "Use `help ` in the Tcl interpreter for the same text." + puts $f "" + + foreach var [lsort [array names var_help]] { + puts $f "## $var" + puts $f "" + set values [var_help_values $var] + if { $values != "" } { + puts $f "```" + puts $f "$var $values" + puts $f "```" + puts $f "" + } + set desc [var_help_text $var] + if { $desc != "" } { + puts $f $desc + puts $f "" + } + } + close $f +} + +proc write_command_line_md { path } { + set sta_bin [info nameofexecutable] + set usage [exec $sta_bin -help] + # Usage line includes the absolute argv[0]; normalize to "sta". + set usage [regsub {Usage: [^ ]+} $usage {Usage: sta}] + set f [open $path w] + puts $f "# Command line arguments" + puts $f "" + puts $f "The command line arguments for `sta` are shown below." + puts $f "" + puts $f "```" + puts -nonewline $f $usage + if { ![string match "*\n" $usage] } { + puts $f "" + } + puts $f "```" + puts $f "" + puts $f "When OpenSTA starts up, commands are first read from the user" + puts $f "initialization file `~/.sta` if it exists. If a Tcl command file" + puts $f "`cmd_file` is specified on the command line, commands are read from" + puts $f "the file and executed before entering an interactive Tcl command" + puts $f "interpreter. If `-exit` is specified the application exits after" + puts $f "reading `cmd_file`. Use the Tcl `exit` command to exit the" + puts $f "application. The `-threads` option specifies how many parallel" + puts $f "threads to use. Use `-threads max` to use one thread per processor." + puts $f "" + close $f +} + +write_cmd_docs + +# namespace end +} diff --git a/etc/build_sta.sh b/etc/build_sta.sh new file mode 100755 index 000000000..77fb6b9ee --- /dev/null +++ b/etc/build_sta.sh @@ -0,0 +1,43 @@ +#!/bin/sh +# OpenSTA, Static Timing Analyzer +# Copyright (c) 2026, Parallax Software, Inc. +# +# Configure and build sta so WriteCmdDocs.tcl can generate command docs. +# Used by Read the Docs, not the main CI test build. +# Usage: etc/build_sta.sh + +set -eu + +root=$(CDPATH= cd -- "$(dirname "$0")/.." && pwd) +cd "$root" + +build_dir="${STA_DOCS_BUILD_DIR:-$root/build/docs-sta}" +cudd_dir="${STA_DOCS_CUDD_DIR:-$root/build/cudd}" +jobs=$(nproc 2>/dev/null || echo 2) +cudd_tar=/tmp/cudd-3.0.0.tar.gz +cudd_url=https://github.com/oscc-ip/artifact/releases/download/cudd-3.0.0/build.tar.gz + +if [ ! -d "$cudd_dir" ]; then + echo "Downloading CUDD 3.0.0..." + mkdir -p "$cudd_dir" + wget -nv -O "$cudd_tar" "$cudd_url" + tar -xzf "$cudd_tar" -C "$cudd_dir" + rm -f "$cudd_tar" +fi + +set -- -S "$root" -B "$build_dir" +if command -v ninja >/dev/null 2>&1; then + set -- "$@" -G Ninja +fi + +echo "Configuring OpenSTA in $build_dir ..." +# Debug + -g0: skip LTO (CMakeLists enables it for Release) and debug info +# so Read the Docs stays under the community build-time limit. +cmake "$@" \ + -DCUDD_DIR="$cudd_dir" \ + -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_CXX_FLAGS_DEBUG="-O0 -g0" \ + -DUSE_TCL_READLINE=OFF + +echo "Building sta..." +cmake --build "$build_dir" --target sta -- -j "$jobs" diff --git a/graph/Graph.tcl b/graph/Graph.tcl index 3d04bf682..a743aeb22 100644 --- a/graph/Graph.tcl +++ b/graph/Graph.tcl @@ -27,7 +27,12 @@ namespace eval sta { define_cmd_args "report_edges" {[-from from_pin] [-to to_pin]\ - [-digits digits] [-report_variance]} + [-digits digits] [-report_variance]} \ + -help {Report the edges/timing arcs and their delays in the timing graph from/to/between pins.} \ + -arg_help { + -from {Report edges/timing arcs from pin from_pin.} + -to {Report edges/timing arcs to pin to_pin.} + } proc report_edges { args } { global sta_report_default_digits diff --git a/include/sta/TimingArc.hh b/include/sta/TimingArc.hh index 158caec34..dd2ebf360 100644 --- a/include/sta/TimingArc.hh +++ b/include/sta/TimingArc.hh @@ -119,6 +119,10 @@ public: TimingModel *model(const RiseFall *rf) const; void setModel(const RiseFall *rf, TimingModel *model); + // retaining_rise/fall and retain_rise_slew/retain_fall_slew tables. + TimingModel *retainModel(const RiseFall *rf) const; + void setRetainModel(const RiseFall *rf, + TimingModel *model); float ocvArcDepth() const { return ocv_arc_depth_; } void setOcvArcDepth(float depth); @@ -133,6 +137,7 @@ protected: std::string mode_value_; float ocv_arc_depth_; TimingModel *models_[RiseFall::index_count]; + TimingModel *retain_models_[RiseFall::index_count]; }; // A timing arc set is a group of related timing arcs between from/to @@ -156,6 +161,7 @@ public: TimingType timingType() const { return attrs_->timingType(); } TimingSense sense() const; TimingModel *model(const RiseFall *rf) const { return attrs_->model(rf); } + TimingModel *retainModel(const RiseFall *rf) const { return attrs_->retainModel(rf); } // Rise/fall if the arc set is rising_edge or falling_edge. const RiseFall *isRisingFallingEdge() const; size_t arcCount() const { return arcs_.size(); } @@ -257,6 +263,7 @@ public: // Index in TimingArcSet. size_t index() const { return index_; } TimingModel *model() const { return model_; } + TimingModel *retainModel() const; GateTimingModel *gateModel(const Scene *scene, const MinMax *min_max) const; CheckTimingModel *checkModel(const Scene *scene, @@ -279,6 +286,8 @@ protected: void setIndex(size_t index); void addScaledModel(const OperatingConditions *op_cond, TimingModel *scaled_model); + void addScaledRetainModel(const OperatingConditions *op_cond, + TimingModel *scaled_model); TimingArcSet *set_; const Transition *from_rf_; @@ -286,6 +295,7 @@ protected: unsigned index_; TimingModel *model_; ScaledTimingModelMap *scaled_models_{nullptr}; + ScaledTimingModelMap *scaled_retain_models_{nullptr}; std::vector scene_arcs_; private: diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index 31ec2654f..6c9da9d14 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -1492,6 +1492,11 @@ LibertyCell::addScaledCell(OperatingConditions *op_cond, TimingModel *model = scaled_arc->model(); model->setIsScaled(true); arc->addScaledModel(op_cond, model); + TimingModel *retain_model = scaled_arc->retainModel(); + if (retain_model) { + retain_model->setIsScaled(true); + arc->addScaledRetainModel(op_cond, retain_model); + } } } } diff --git a/liberty/Liberty.tcl b/liberty/Liberty.tcl index 698289c33..acdf4ccb2 100644 --- a/liberty/Liberty.tcl +++ b/liberty/Liberty.tcl @@ -27,7 +27,50 @@ namespace eval sta { define_cmd_args "read_liberty" \ - {[-corner corner] [-min] [-max] [-infer_latches] filename} + {[-corner corner] [-min] [-max] [-infer_latches] filename} \ + -help {The `read_liberty` command reads a Liberty format library file. The first library that is read sets the units used by SDC/Tcl commands and reporting. The include_file attribute is supported. + +Some Liberty libraries do not include latch groups for cells that describe transparent latches. In that situation the `-infer_latches` command flag can be used to infer the latches. The timing arcs required for a latch to be inferred should look like the following: + +``` +cell (inferred_latch) { + pin(D) { + direction : input ; + timing () { + related_pin : "E" ; + timing_type : setup_falling ; + } + timing () { + related_pin : "E" ; + timing_type : hold_falling ; + } + } + pin(E) { + direction : input; + } + pin(Q) { + direction : output ; + timing () { + related_pin : "D" ; + } + timing () { + related_pin : "E" ; + timing_type : rising_edge ; + } + } +} +``` + +In this example a positive level-sensitive latch is inferred. + +Files compressed with gzip are automatically uncompressed.} \ + -arg_help { + -corner {Deprecated. Use `define_scene` to assign Liberty libraries to a scene.} + -min {Use the library for min-delay (hold) analysis.} + -max {Use the library for max-delay (setup) analysis.} + filename {The Liberty file name to read.} + -infer_latches {Infer latches from timing arcs when the Liberty file has no latch groups.} + } proc_redirect read_liberty { parse_key_args "read_liberty" args keys {-corner} \ @@ -52,7 +95,11 @@ proc write_liberty { args } { ################################################################ -define_cmd_args "report_lib_cell" {cell_name [> filename] [>> filename]} +define_cmd_args "report_lib_cell" {cell_name [> filename] [>> filename]} \ + -help {Describe the liberty library cell cell_name.} \ + -arg_help { + cell_name {The name of a library cell.} + } proc_redirect report_lib_cell { check_argc_eq1 "report_lib_cell" $args diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc index 09733ca87..289379324 100644 --- a/liberty/LibertyReader.cc +++ b/liberty/LibertyReader.cc @@ -2188,6 +2188,9 @@ LibertyReader::makeTableModels(LibertyCell *cell, found_model = true; } + if (makeRetainTableModels(cell, timing_group, rf, slew_model, timing_attrs)) + found_model = true; + std::string constraint_attr_name = sta::format("{}_constraint", rf->to_string()); ScaleFactorType scale_factor_type = timingTypeScaleFactorType(timing_attrs.timingType()); @@ -2212,6 +2215,57 @@ LibertyReader::makeTableModels(LibertyCell *cell, warn(1311, timing_group, "no table models found in timing group."); } +bool +LibertyReader::makeRetainTableModels(LibertyCell *cell, + const LibertyGroup *timing_group, + const RiseFall *rf, + TableModel *slew_model, + TimingArcAttrs &timing_attrs) +{ + std::string delay_name = sta::format("retaining_{}", rf->to_string()); + TableModel *delay_model = readTableModel(timing_group, delay_name, + rf, TableTemplateType::delay, + time_scale_, + ScaleFactorType::cell, + GateTableModel::checkAxes); + if (delay_model) { + TableModels *delay_models = new TableModels(delay_model); + readLvfModels(timing_group, + sta::format("ocv_sigma_{}", delay_name), + sta::format("ocv_std_dev_{}", delay_name), + sta::format("ocv_mean_shift_{}", delay_name), + sta::format("ocv_skewness_{}", delay_name), + rf, delay_models, GateTableModel::checkAxes); + + // retain_*_slew is the slew of the retain (contamination) arc. + std::string slew_name = sta::format("retain_{}_slew", rf->to_string()); + TableModel *retain_slew_model = + readTableModel(timing_group, slew_name, + rf, TableTemplateType::delay, + time_scale_, + ScaleFactorType::transition, + GateTableModel::checkAxes); + TableModel *retain_slew = retain_slew_model; + if (retain_slew == nullptr && slew_model) + retain_slew = new TableModel(slew_model->table(), + slew_model->tblTemplate(), + slew_model->scaleFactorType(), rf); + TableModels *slew_models = new TableModels(retain_slew); + if (retain_slew_model) + readLvfModels(timing_group, + sta::format("ocv_sigma_{}", slew_name), + sta::format("ocv_std_dev_{}", slew_name), + sta::format("ocv_mean_shift_{}", slew_name), + sta::format("ocv_skewness_{}", slew_name), + rf, slew_models, GateTableModel::checkAxes); + + timing_attrs.setRetainModel(rf, new GateTableModel(cell, delay_models, + slew_models)); + return true; + } + return false; +} + bool LibertyReader::isGateTimingType(TimingType timing_type) { diff --git a/liberty/LibertyReaderPvt.hh b/liberty/LibertyReaderPvt.hh index eabdc2cc8..d5024cbf8 100644 --- a/liberty/LibertyReaderPvt.hh +++ b/liberty/LibertyReaderPvt.hh @@ -284,6 +284,11 @@ protected: void makeTableModels(LibertyCell *cell, const LibertyGroup *timing_group, TimingArcAttrs &timing_attrs); + bool makeRetainTableModels(LibertyCell *cell, + const LibertyGroup *timing_group, + const RiseFall *rf, + TableModel *slew_model, + TimingArcAttrs &timing_attrs); void readLvfModels(const LibertyGroup *timing_group, const std::string &sigma_group_name, const std::string &std_dev_group_name, diff --git a/liberty/LibertyWriter.cc b/liberty/LibertyWriter.cc index 695b2ccbe..9ea8d3bd6 100644 --- a/liberty/LibertyWriter.cc +++ b/liberty/LibertyWriter.cc @@ -70,6 +70,10 @@ class LibertyWriter void writeTimingArcSet(const TimingArcSet *arc_set); void writeTimingModels(const TimingArc *arc, const RiseFall *rf); + void writeGateTableModel(const GateTableModel *gate_model, + const RiseFall *rf, + bool retain, + const GateTableModel *cell_model); void writeTableModel(const TableModel *model); void writeTableModel0(const TableModel *model); void writeTableModel1(const TableModel *model); @@ -451,36 +455,64 @@ void LibertyWriter::writeTimingModels(const TimingArc *arc, const RiseFall *rf) { - TimingModel *model = arc->model(); + const TimingArcSet *arc_set = arc->set(); + TimingModel *model = arc_set->model(rf); + TimingModel *retain_model = arc_set->retainModel(rf); const GateTableModel *gate_model = dynamic_cast(model); + const GateTableModel *retain_gate = dynamic_cast(retain_model); const CheckTableModel *check_model = dynamic_cast(model); - if (gate_model) { - const TableModel *delay_model = gate_model->delayModel(); + if (gate_model) + writeGateTableModel(gate_model, rf, false, nullptr); + if (retain_gate) + writeGateTableModel(retain_gate, rf, true, gate_model); + if (check_model) { + const TableModel *check_table = check_model->checkModel(); + const std::string &template_name = check_table->tblTemplate()->name(); + sta::print(stream_, " {}_constraint({}) {{\n", rf->name(), + template_name); + writeTableModel(check_table); + sta::print(stream_, " }}\n"); + } + if (gate_model == nullptr && retain_gate == nullptr && check_model == nullptr) + report_->error(1341, "{}/{}/{} timing model not supported.", library_->name(), + arc->from()->libertyCell()->name(), arc->from()->name()); +} + +void +LibertyWriter::writeGateTableModel(const GateTableModel *gate_model, + const RiseFall *rf, + bool retain, + const GateTableModel *cell_model) +{ + const TableModel *delay_model = gate_model->delayModel(); + if (delay_model) { const std::string &template_name = delay_model->tblTemplate()->name(); - sta::print(stream_, " cell_{}({}) {{\n", rf->name(), template_name); + if (retain) + sta::print(stream_, " retaining_{}({}) {{\n", rf->name(), + template_name); + else + sta::print(stream_, " cell_{}({}) {{\n", rf->name(), template_name); writeTableModel(delay_model); sta::print(stream_, " }}\n"); + } - const TableModel *slew_model = gate_model->slewModel(); - if (slew_model) { + const TableModel *slew_model = gate_model->slewModel(); + if (slew_model) { + bool slew_is_fallback = false; + if (retain && cell_model && cell_model->slewModel()) + slew_is_fallback = cell_model->slewModel()->table() == slew_model->table(); + if (!slew_is_fallback) { const std::string &slew_template_name = slew_model->tblTemplate()->name(); - sta::print(stream_, " {}_transition({}) {{\n", rf->name(), - slew_template_name); + if (retain) + sta::print(stream_, " retain_{}_slew({}) {{\n", rf->name(), + slew_template_name); + else + sta::print(stream_, " {}_transition({}) {{\n", rf->name(), + slew_template_name); writeTableModel(slew_model); sta::print(stream_, " }}\n"); } } - else if (check_model) { - const TableModel *model = check_model->checkModel(); - const std::string &template_name = model->tblTemplate()->name(); - sta::print(stream_, " {}_constraint({}) {{\n", rf->name(), - template_name); - writeTableModel(model); - sta::print(stream_, " }}\n"); - } - else - report_->error(1341, "{}/{}/{} timing model not supported.", library_->name(), - arc->from()->libertyCell()->name(), arc->from()->name()); } void diff --git a/liberty/TableModel.cc b/liberty/TableModel.cc index 5cdd92f2e..1d5dc2415 100644 --- a/liberty/TableModel.cc +++ b/liberty/TableModel.cc @@ -103,9 +103,9 @@ GateTableModel::slewModel() const void GateTableModel::setIsScaled(bool is_scaled) { - if (delay_models_) + if (delay_models_ && delay_models_->model()) delay_models_->model()->setIsScaled(is_scaled); - if (slew_models_) + if (slew_models_ && slew_models_->model()) slew_models_->model()->setIsScaled(is_scaled); } diff --git a/liberty/TimingArc.cc b/liberty/TimingArc.cc index 8a03ae658..60d21bdb4 100644 --- a/liberty/TimingArc.cc +++ b/liberty/TimingArc.cc @@ -60,7 +60,8 @@ TimingArcAttrs::TimingArcAttrs() : timing_sense_(TimingSense::unknown), cond_(nullptr), ocv_arc_depth_(0.0), - models_{nullptr, nullptr} + models_{nullptr, nullptr}, + retain_models_{nullptr, nullptr} { } @@ -69,7 +70,8 @@ TimingArcAttrs::TimingArcAttrs(TimingSense sense) : timing_sense_(sense), cond_(nullptr), ocv_arc_depth_(0.0), - models_{nullptr, nullptr} + models_{nullptr, nullptr}, + retain_models_{nullptr, nullptr} { } @@ -78,6 +80,8 @@ TimingArcAttrs::~TimingArcAttrs() delete cond_; delete models_[RiseFall::riseIndex()]; delete models_[RiseFall::fallIndex()]; + delete retain_models_[RiseFall::riseIndex()]; + delete retain_models_[RiseFall::fallIndex()]; } void @@ -142,6 +146,19 @@ TimingArcAttrs::setModel(const RiseFall *rf, models_[rf->index()] = model; } +TimingModel * +TimingArcAttrs::retainModel(const RiseFall *rf) const +{ + return retain_models_[rf->index()]; +} + +void +TimingArcAttrs::setRetainModel(const RiseFall *rf, + TimingModel *model) +{ + retain_models_[rf->index()] = model; +} + void TimingArcAttrs::setOcvArcDepth(float depth) { @@ -560,6 +577,7 @@ TimingArc::~TimingArc() // The models referenced by scaled_models_ are owned by the scaled // cells and are deleted by ~LibertyCell. delete scaled_models_; + delete scaled_retain_models_; } std::string @@ -616,10 +634,22 @@ TimingArc::model(const Scene *scene, const MinMax *min_max) const { const TimingArc *scene_arc = sceneArc(scene->libertyIndex(min_max)); + const OperatingConditions *op_cond = + scene->sdc()->operatingConditions(min_max); + // Liberty retaining_* tables are contamination delay (min). + if (min_max == MinMax::min()) { + ScaledTimingModelMap *scaled_retain = scene_arc->scaled_retain_models_; + if (scaled_retain) { + TimingModel *scaled_model = findKey(*scaled_retain, op_cond); + if (scaled_model) + return scaled_model; + } + TimingModel *retain_model = scene_arc->retainModel(); + if (retain_model) + return retain_model; + } ScaledTimingModelMap *scaled_models = scene_arc->scaled_models_; if (scaled_models) { - const OperatingConditions *op_cond = - scene->sdc()->operatingConditions(min_max); TimingModel *scaled_model = findKey(*scaled_models, op_cond); if (scaled_model) return scaled_model; @@ -627,6 +657,12 @@ TimingArc::model(const Scene *scene, return scene_arc->model(); } +TimingModel * +TimingArc::retainModel() const +{ + return set_->retainModel(to_rf_->asRiseFall()); +} + void TimingArc::addScaledModel(const OperatingConditions *op_cond, TimingModel *scaled_model) @@ -636,6 +672,15 @@ TimingArc::addScaledModel(const OperatingConditions *op_cond, (*scaled_models_)[op_cond] = scaled_model; } +void +TimingArc::addScaledRetainModel(const OperatingConditions *op_cond, + TimingModel *scaled_model) +{ + if (scaled_retain_models_ == nullptr) + scaled_retain_models_ = new ScaledTimingModelMap; + (*scaled_retain_models_)[op_cond] = scaled_model; +} + bool TimingArc::equiv(const TimingArc *arc1, const TimingArc *arc2) diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 000000000..63034715e --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,53 @@ +site_name: OpenSTA +site_description: OpenSTA static timing analyzer +site_url: https://opensta.readthedocs.io/en/latest/ +repo_url: https://github.com/parallaxsw/OpenSTA +repo_name: parallaxsw/OpenSTA +edit_uri: "" + +docs_dir: doc + +theme: + name: material + features: + - navigation.sections + - navigation.expand + - search.suggest + - content.code.copy + palette: + - scheme: default + toggle: + icon: material/brightness-7 + name: Switch to dark mode + - scheme: slate + toggle: + icon: material/brightness-4 + name: Switch to light mode + +extra_css: + - Extra.css + +markdown_extensions: + - admonition + - attr_list + - def_list + - tables + - toc: + permalink: true + - pymdownx.superfences + - pymdownx.highlight + +nav: + - Home: index.md + - Command line: CommandLine.md + - Examples: Examples.md + - Tcl interpreter: TclInterpreter.md + - Debugging timing: Debugging.md + - Commands: Commands.md + - Filter expressions: FilterExpressions.md + - Variables: Variables.md + - ChangeLog: ChangeLog.md + - Developer: + - STA API: StaApi.md + - Coding guidelines: CodingGuidelines.md + - API changes: ApiChanges.md diff --git a/network/ConcreteNetwork.cc b/network/ConcreteNetwork.cc index df99ff9d7..7da65502d 100644 --- a/network/ConcreteNetwork.cc +++ b/network/ConcreteNetwork.cc @@ -29,6 +29,7 @@ #include #include "ConcreteLibrary.hh" +#include "Error.hh" #include "Liberty.hh" #include "Network.hh" #include "PatternMatch.hh" @@ -1422,21 +1423,26 @@ ConcreteNetwork::connect(Instance *inst, if (prev_net) disconnectNetPin(prev_net, cpin); } + // Bus and bundle ports have no pin index, so they have no pin to connect. + else if (cport->isBus() || cport->isBundle()) + report()->warn(2728, "port {} has no pin to connect.", cport->name()); else { cpin = new ConcretePin(cinst, cport, cnet); cinst->addPin(cpin); } - if (inst == top_instance_) { - // makeTerm - ConcreteTerm *cterm = new ConcreteTerm(cpin, cnet); - if (cnet) - cnet->addTerm(cterm); - cpin->term_ = cterm; - cpin->net_ = nullptr; - } - else { - cpin->net_ = cnet; - connectNetPin(cnet, cpin); + if (cpin) { + if (inst == top_instance_) { + // makeTerm + ConcreteTerm *cterm = new ConcreteTerm(cpin, cnet); + if (cnet) + cnet->addTerm(cterm); + cpin->term_ = cterm; + cpin->net_ = nullptr; + } + else { + cpin->net_ = cnet; + connectNetPin(cnet, cpin); + } } return reinterpret_cast(cpin); } @@ -1657,22 +1663,17 @@ ConcretePin * ConcreteInstance::findPin(std::string_view port_name) const { ConcreteCell *ccell = reinterpret_cast(cell_); - const ConcretePort *cport = - reinterpret_cast(ccell->findPort(port_name)); - if (cport - && !cport->isBus()) - return pins_[cport->pinIndex()]; - else - return nullptr; + return findPin(reinterpret_cast(ccell->findPort(port_name))); } ConcretePin * ConcreteInstance::findPin(const Port *port) const { const ConcretePort *cport = reinterpret_cast(port); - size_t port_index = cport->pinIndex(); - if (port_index < pins_.size()) - return pins_[port_index]; + if (cport + && !(cport->isBus() || cport->isBundle()) + && static_cast(cport->pinIndex()) < pins_.size()) + return pins_[cport->pinIndex()]; else return nullptr; } @@ -1758,8 +1759,11 @@ void ConcreteInstance::addPin(ConcretePin *pin) { ConcretePort *cport = reinterpret_cast(pin->port()); - size_t pin_index = cport->pinIndex(); - if (pin_index >= pins_.size()) + // Bus and bundle ports have no pin index; storing at pins_[-1] corrupts memory. + if (cport->isBus() || cport->isBundle()) + criticalError(2727, "port has no pin index"); + int pin_index = cport->pinIndex(); + if (static_cast(pin_index) >= pins_.size()) pins_.resize(pin_index + 1); pins_[pin_index] = pin; } @@ -1858,25 +1862,30 @@ ConcreteNet::ConcreteNet(std::string_view name, void ConcreteNet::mergeInto(ConcreteNet *net) { - ConcreteNetPinIterator pin_iter(this); - while (pin_iter.hasNext()) { - Pin *pin = pin_iter.next(); - ConcretePin *cpin = reinterpret_cast(pin); - net->addPin(cpin); - cpin->net_ = net; - } - pins_ = nullptr; - ConcreteNetTermIterator term_iter(this); - while (term_iter.hasNext()) { - Term *term = term_iter.next(); - ConcreteTerm *cterm = reinterpret_cast(term); - net->addTerm(cterm); - cterm->net_ = net; + // Merging a net into itself moves its pins and terms onto itself, nulls + // them, and leaves merged_into_ pointing at this, so following the merge + // chain never ends. + if (net != this) { + ConcreteNetPinIterator pin_iter(this); + while (pin_iter.hasNext()) { + Pin *pin = pin_iter.next(); + ConcretePin *cpin = reinterpret_cast(pin); + net->addPin(cpin); + cpin->net_ = net; + } + pins_ = nullptr; + ConcreteNetTermIterator term_iter(this); + while (term_iter.hasNext()) { + Term *term = term_iter.next(); + ConcreteTerm *cterm = reinterpret_cast(term); + net->addTerm(cterm); + cterm->net_ = net; + } + terms_ = nullptr; + // Leave name map pointing to merged net because otherwise a top + // level merged net has no pointer to it and it is leaked. + merged_into_ = net; } - terms_ = nullptr; - // Leave name map pointing to merged net because otherwise a top - // level merged net has no pointer to it and it is leaked. - merged_into_ = net; } void diff --git a/network/Link.tcl b/network/Link.tcl index 721960870..b4df694d9 100644 --- a/network/Link.tcl +++ b/network/Link.tcl @@ -27,7 +27,16 @@ namespace eval sta { define_cmd_args "link_design" {[-no_black_boxes]\ - [top_cell_name]} + [top_cell_name]} \ + -help {Link (elaborate, flatten) the top-level cell `cell_name`. The design must be linked after reading netlist and library files. The default value of `cell_name` is the current design. + +By default the linker creates empty black-box cells for instances that reference undefined cells. Use `-no_black_boxes` to report an error and fail the link instead. + +The `link_design` command returns 1 if the link succeeds and 0 if it fails.} \ + -arg_help { + -no_black_boxes {Do not make empty "black box" cells for instances that reference undefined cells.} + cell_name {The top level module/cell name of the design hierarchy to link.} + } proc_redirect link_design { variable current_design_name diff --git a/network/Network.tcl b/network/Network.tcl index 376bd289e..5886c316f 100644 --- a/network/Network.tcl +++ b/network/Network.tcl @@ -27,7 +27,13 @@ namespace eval sta { define_cmd_args "report_instance" \ - {[-connections] [-verbose] instance_path [> filename] [>> filename]} + {[-connections] [-verbose] instance_path [> filename] [>> filename]} \ + -help {Report information about an instance.} \ + -arg_help { + -connections {Deprecated; connections are always reported.} + -verbose {Deprecated; verbose output is always used.} + instance_path {Hierarchical path to an instance.} + } proc_redirect report_instance { parse_key_args "report_instance" args keys {} flags {-connections -verbose} @@ -141,7 +147,11 @@ proc instance_sorted_children { instance } { ################################################################ define_cmd_args "report_net" {[-scene scene] [-digits digits]\ - net_path [> filename] [>> filename]} + net_path [> filename] [>> filename]} \ + -help {Report the connections and capacitance of a net.} \ + -arg_help { + net_path {Hierarchical path to a net.} + } # -hpins to show hierarchical pins proc_redirect report_net { diff --git a/network/NetworkEdit.tcl b/network/NetworkEdit.tcl index cfddb7530..51edf09d2 100644 --- a/network/NetworkEdit.tcl +++ b/network/NetworkEdit.tcl @@ -26,7 +26,12 @@ namespace eval sta { -define_cmd_args "make_instance" {inst_path lib_cell} +define_cmd_args "make_instance" {inst_path lib_cell} \ + -help {The `make_instance` command makes an instance of library cell lib_cell.} \ + -arg_help { + inst_path {A hierarchical instance name.} + lib_cell {The library cell of the new instance.} + } proc make_instance { inst_path lib_cell } { set lib_cell [get_lib_cell_warn "lib_cell" $lib_cell] @@ -53,7 +58,11 @@ proc make_instance { inst_path lib_cell } { ################################################################ -define_cmd_args "make_net" {net_path} +define_cmd_args "make_net" {net_path} \ + -help {Creates a net for each hierarchical net name.} \ + -arg_help { + net_name_list {A list of net names.} + } proc make_net { net_path } { # Copy backslashes that will be removed by foreach. @@ -73,7 +82,12 @@ proc make_net { net_path } { ################################################################ -define_cmd_args "make_port" {port_name direction} +define_cmd_args "make_port" {port_name direction} \ + -help {The `make_port` command creates a port on the top-level cell. `direction` is `input`, `output`, `bidirect`, `tristate`, `internal`, `power`, or `ground`.} \ + -arg_help { + port_name {The name of the new port.} + direction {Port direction: `input`, `output`, `bidirect`, `tristate`, `internal`, `power`, or `ground`.} + } proc make_port { port_name direction } { make_port_pin_cmd $port_name $direction @@ -81,7 +95,13 @@ proc make_port { port_name direction } { ################################################################ -define_cmd_args "connect_pin" {net pin} +define_cmd_args "connect_pin" {net pin} \ + -help {The `connect_pin` command connects a port or instance pin to a net.} \ + -arg_help { + net {A net to add connections to.} + port {A port to connect to net.} + Pin {A pin to connect to net.} + } proc connect_pin { net pin } { set insts_port [parse_connect_pin $pin] @@ -143,7 +163,14 @@ proc parse_connect_pin { arg } { ################################################################ -define_cmd_args "disconnect_pin" {net -all|pin} +define_cmd_args "disconnect_pin" {net -all|pin} \ + -help {Disconnects a port or pin from a net. Parasitics connected to the pin are deleted.} \ + -arg_help { + net {The net to disconnect pins from.} + port {A port to connect to net.} + pin {A pin to connect to net.} + -all {Disconnect all pins from the net.} + } proc disconnect_pin { net pin } { set net [get_net_arg "net" $net] @@ -171,7 +198,11 @@ proc disconnect_pin { net pin } { ################################################################ -define_cmd_args "delete_instance" {inst} +define_cmd_args "delete_instance" {inst} \ + -help {The network editing command `delete_instance` removes an instance from the design.} \ + -arg_help { + instance {Instance to delete.} + } proc delete_instance { instance } { if { [is_object $instance] } { @@ -191,7 +222,11 @@ proc delete_instance { instance } { ################################################################ -define_cmd_args "delete_net" {net} +define_cmd_args "delete_net" {net} \ + -help {The network editing command `delete_net` removes a net from the design.} \ + -arg_help { + net {Net to delete.} + } proc delete_net { net } { if { [is_object $net] } { @@ -209,7 +244,12 @@ proc delete_net { net } { ################################################################ -define_cmd_args "replace_cell" {instance lib_cell} +define_cmd_args "replace_cell" {instance lib_cell} \ + -help {The `replace_cell` command changes the cell of an instance. The replacement cell must have the same port list (number, name, and order) as the instance's existing cell for the replacement to be successful.} \ + -arg_help { + instance_list {A list of instances to swap the cell.} + replacement_cell {The replacement lib cell.} + } proc replace_cell { instance lib_cell } { set cell [get_lib_cell_warn "lib_cell" $lib_cell] diff --git a/parasitics/Parasitics.tcl b/parasitics/Parasitics.tcl index e09f496be..13b35ea04 100644 --- a/parasitics/Parasitics.tcl +++ b/parasitics/Parasitics.tcl @@ -34,7 +34,45 @@ define_cmd_args "read_spef" \ [-keep_capacitive_coupling]\ [-coupling_reduction_factor factor]\ [-reduce]\ - filename} + filename} \ + -help {The `read_spef` command reads a file of net parasitics in SPEF format. Use the `-report_parasitic_annotation` command to check for nets that are not annotated. + +Files compressed with gzip are automatically uncompressed. + +Separate min/max parasitics can be annotated for each scene. + +``` +read_spef -name min spef1 +read_spef -name max spef2 +define_scene scene1 -mode mode1 -spef_min min -spef_max max +``` + +Coupling capacitors are multiplied by the `-coupling_reduction_factor` when a parasitic network is reduced. + +The following SPEF constructs are ignored. + +``` +*DESIGN_FLOW (all values are ignored) +*S slews +*D driving cell +*I pin capacitances (library cell capacitances are used instead) +*Q r_net load poles +*K r_net load residues +``` + +If the SPEF file contains triplet values the first value is used. + +Parasitic networks (DSPEF) can be annotated on hierarchical blocks using the `-path` argument to specify the instance path to the block. Parasitic networks in the higher level netlist are stitched together at the hierarchical pins of the blocks.} \ + -arg_help { + -name {The name of the SPEF parasitics to use for defining scenes. The default is the base name of filename.} + -corner {Process corner to annotate. Deprecated; use `-name` and `define_scene`.} + -pin_cap_included {SPEF pin capacitances are included (library pin capacitances are not added).} + -reduce {Reduce parasitic networks to the form used by the current delay calculator.} + -path {Hierarchical block instance path to annotate with parasitics.} + -keep_capacitive_coupling {Keep coupling capacitors in parasitic networks rather than converting them to grounded capacitors.} + -coupling_reduction_factor {`factor`: Factor to multiply coupling capacitance by when reducing parasitic networks. The default value is 1.0.} + filename {The name of the parasitics file to read.} + } # -scene/-min/-max are for compatibilty, Deprecated 11/21/2025 proc_redirect read_spef { @@ -73,7 +111,12 @@ proc_redirect read_spef { } define_cmd_args "report_parasitic_annotation" {[-name spef_name]\ - [-report_unannotated]} + [-report_unannotated]} \ + -help {Report SPEF parasitic annotation completeness.} \ + -arg_help { + -report_unannotated {Report unannotated and partially annotated nets.} + -name {SPEF annotation name from `read_spef -name`.} + } proc_redirect report_parasitic_annotation { parse_key_args "report_parasitic_annotation" args \ diff --git a/power/Power.tcl b/power/Power.tcl index e9ae00844..6708aba16 100644 --- a/power/Power.tcl +++ b/power/Power.tcl @@ -36,7 +36,28 @@ define_cmd_args "report_power" \ [-scene scene]\ [-digits digits]\ [-format format]\ - [> filename] [>> filename] } + [> filename] [>> filename] } \ + -help {The `report_power` command uses static power analysis based on propagated or annotated pin activities in the circuit using Liberty power models. The internal, switching, leakage and total power are reported. Design power is reported separately for combinational, sequential, macro and pad groups. Power values are reported in watts. + +The `read_vcd` or `read_saif` commands can be used to read activities from a file based on simulation. If no simulation activities are available, the `set_power_activity` command should be used to set the activity of input ports or pins in the design. The default input activity and duty for inputs are 0.1 and 0.5 respectively. The activities are propagated from annotated input ports or pins through gates and used in the power calculations. + +``` +Group Internal Switching Leakage Total + Power Power Power Power +---------------------------------------------------------------- +Sequential 3.29e-06 3.41e-08 2.37e-07 3.56e-06 92.4% +Combinational 1.86e-07 3.31e-08 7.51e-08 2.94e-07 7.6% +Macro 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.0% +Pad 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.0% +--------------------------------------------------------------- +Total 3.48e-06 6.72e-08 3.12e-07 3.86e-06 100.0% + 90.2% 1.7% 8.1% +```} \ + -arg_help { + -instances {`instances`: Report the power for each instance of instances. If the instance is hierarchical the total power for the instances inside the hierarchical instance is reported.} + -highest_power_instances {`count`: Report the power for the count highest power instances.} + -format {`text`: Print a text table (the default). `json`: Print JSON.} + } proc_redirect report_power { global sta_report_default_digits @@ -110,7 +131,24 @@ define_cmd_args "set_power_activity" { [-global]\ [-pins pins]\ [-activity activity | -density density]\ [-duty duty]\ - [-clock clock]} + [-clock clock]} \ + -help {The `set_power_activity` command is used to set the activity and duty used for power analysis globally or for input ports or pins in the design. + +The default input activity for inputs is 0.1 transitions per minimum clock period if a clock is defined or 0.0 if there are no clocks defined. The default input duty is 0.5. This is equivalent to the following command: + +``` +set_power_activity -input -activity 0.1 -duty 0.5 +```} \ + -arg_help { + -global {Set the activity/duty for all non-clock pins.} + -input {Set the default input port activity/duty.} + -input_ports {`input_ports`: Set the input port activity/duty.} + -pins {`pins`: Set the pin activity/duty.} + -activity {`activity`: The activity, or number of transitions per clock cycle. If clock is not specified the clock with the minimum period is used. If no clocks are defined an error is reported.} + -density {`density`: Transitions per library time unit.} + -duty {`duty`: The duty, or probability the signal is high (0 <= duty <= 1.0). Defaults to 0.5.} + -clock {`clock`: The clock to use for the period with `-activity`. This option is ignored if `-density` is used.} + } proc set_power_activity { args } { parse_key_args "set_power_activity" args \ @@ -187,7 +225,15 @@ define_cmd_args "unset_power_activity" { [-global]\ [-input]\ [-input_ports ports]\ [-pins pins]\ - [-clock clock]} + [-clock clock]} \ + -help {The unset_power_activity_command is used to undo the effects of the `set_power_activity` command.} \ + -arg_help { + -global {Unset the activity/duty for all non-clock pins.} + -input {Unset the default input port activity/duty.} + -input_ports {`input_ports`: Unset the input port activity/duty.} + -pins {`pins`: Unset the pin activity/duty.} + -clock {`clock`: Unset activity associated with this clock.} + } proc unset_power_activity { args } { parse_key_args "unset_power_activity" args \ @@ -225,7 +271,13 @@ proc unset_power_activity { args } { ################################################################ # Deprecated 9/2024 -define_cmd_args "read_power_activities" { [-scope scope] -vcd filename } +define_cmd_args "read_power_activities" { [-scope scope] -vcd filename } \ + -help {The `read_power_activities` command is deprecated. Use `read_vcd` instead.} \ + -arg_help { + -scope {The VCD scope of the current design. Typically the test bench name and design under test instance name. Scope levels are separated with '/'.} + -vcd {VCD file to read. Use `read_vcd` instead.} + filename {The name of the VCD file to read.} + } proc read_power_activities { args } { parse_key_args "read_power_activities" args \ @@ -245,7 +297,15 @@ proc read_power_activities { args } { ################################################################ define_cmd_args "read_vcd" \ - {[-scope scope] [-mode mode_name] [-begin_time begin_time] [-end_time end_time] filename} + {[-scope scope] [-mode mode_name] [-begin_time begin_time] [-end_time end_time] filename} \ + -help {The `read_vcd` command reads a VCD (Value Change Dump) file from a Verilog simulation and extracts pin activities and duty cycles for use in power estimation. Files compressed with gzip are supported. Annotated activities are propagated to the fanout of the annotated pins.} \ + -arg_help { + -scope {The VCD scope of the current design to extract simulation data. Typically the test bench name and design under test instance name. Scope levels are separated with '/'.} + -mode {Mode to annotate activities.} + -begin_time {Ignore VCD activity before this time.} + -end_time {Ignore VCD activity after this time.} + filename {The name of the VCD file to read.} + } proc read_vcd { args } { parse_key_args "read_vcd" args \ @@ -274,7 +334,12 @@ proc read_vcd { args } { ################################################################ -define_cmd_args "read_saif" { [-scope scope] filename } +define_cmd_args "read_saif" { [-scope scope] filename } \ + -help {The `read_saif` command reads a SAIF (Switching Activity Interchange Format) file from a Verilog simulation and extracts pin activities and duty cycles for use in power estimation. Files compressed with gzip are supported. Annotated activities are propagated to the fanout of the annotated pins.} \ + -arg_help { + -scope {The SAIF scope of the current design to extract simulation data. Typically the test bench name and design under test instance name. Scope levels are separated with '/'.} + filename {The name of the SAIF file to read.} + } proc read_saif { args } { parse_key_args "read_saif" args keys {-scope} flags {} @@ -291,7 +356,12 @@ proc read_saif { args } { ################################################################ define_cmd_args "report_activity_annotation" { [-report_unannotated] \ - [-report_annotated] } + [-report_annotated] } \ + -help {Report a summary of pins that are annotated by `read_vcd`, `read_saif` or `set_power_activity`. Sequential internal pins and hierarchical pins are ignored.} \ + -arg_help { + -report_unannotated {Report unannotated pins.} + -report_annotated {Report annotated pins.} + } proc_redirect report_activity_annotation { parse_key_args "report_activity_annotation" args \ diff --git a/sdc/CycleAccting.cc b/sdc/CycleAccting.cc index 8c0ca1eb7..eb07d0b2a 100644 --- a/sdc/CycleAccting.cc +++ b/sdc/CycleAccting.cc @@ -305,6 +305,7 @@ CycleAccting::setSetupAccting(int src_cycle, setAccting(TimingRole::outputSetup(), src_cycle, tgt_cycle, delay, req); setAccting(TimingRole::gatedClockSetup(), src_cycle, tgt_cycle, delay, req); setAccting(TimingRole::recovery(), src_cycle, tgt_cycle, delay, req); + setAccting(TimingRole::nonSeqSetup(), src_cycle, tgt_cycle, delay, req); } void @@ -317,6 +318,7 @@ CycleAccting::setHoldAccting(int src_cycle, setAccting(TimingRole::outputHold(), src_cycle, tgt_cycle, delay, req); setAccting(TimingRole::removal(), src_cycle, tgt_cycle, delay, req); setAccting(TimingRole::latchHold(), src_cycle, tgt_cycle, delay, req); + setAccting(TimingRole::nonSeqHold(), src_cycle, tgt_cycle, delay, req); } void diff --git a/sdc/FilterObjects.cc b/sdc/FilterObjects.cc index eeea29f49..a52c71d6c 100644 --- a/sdc/FilterObjects.cc +++ b/sdc/FilterObjects.cc @@ -311,8 +311,7 @@ filterObjects(std::string_view filter_expression, std::set all; for (auto object: *objects) all.insert(object); - // Delete objects before parsing so errors to not leak them. - delete objects; + // SWIG %typemap(freearg) owns the container. Do not delete it here. FilterExpr filter(filter_expression, report); auto postfix = filter.postfix(); diff --git a/sdc/Sdc.tcl b/sdc/Sdc.tcl index 64fdbfc34..1e755e93f 100644 --- a/sdc/Sdc.tcl +++ b/sdc/Sdc.tcl @@ -34,7 +34,19 @@ namespace eval sta { -define_cmd_args "read_sdc" {[-echo] [-mode mode_name] filename} +define_cmd_args "read_sdc" {[-echo] [-mode mode_name] filename} \ + -help {Read SDC commands from filename. + +If the mode does not exist it is created. Multiple SDC files can append commands to a mode by using the `-mode_name` argument for each one. If no `-mode` arguement is is used the commands are added to the current mode. + +The `read_sdc` command stops and reports any errors encountered while reading a file unless `sta_continue_on_error` is 1. + +Files compressed with gzip are automatically uncompressed.} \ + -arg_help { + -mode {Mode for the SDC commands in the file.} + -echo {Print each command before evaluating it.} + filename {SDC command file.} + } proc_redirect read_sdc { parse_key_args "read_sdc" args keys {-mode} flags {-echo} @@ -62,7 +74,15 @@ proc_redirect read_sdc { ################################################################ define_cmd_args "write_sdc" \ - {[-mode mode] [-map_hpins] [-digits digits] [-gzip] [-no_timestamp] filename} + {[-mode mode] [-map_hpins] [-digits digits] [-gzip] [-no_timestamp] filename} \ + -help {Write the constraints for the design in SDC format to filename.} \ + -arg_help { + -gzip {Compress the SDC with gzip.} + -no_timestamp {Do not include a time and date in the SDC file.} + -mode {SDC mode to write. The default is the current mode.} + -map_hpins {Map hierarchical pins to leaf pins in the SDC.} + filename {The name of the file to write the constraints to.} + } proc write_sdc { args } { parse_key_args "write_sdc" args keys {-mode -digits} \ @@ -94,7 +114,11 @@ proc write_sdc { args } { # ################################################################ -define_cmd_args "current_instance" {[instance]} +define_cmd_args "current_instance" {[instance]} \ + -help {Set or report the current instance used for relative name lookup.} \ + -arg_help { + instance {Not supported.} + } proc current_instance { {inst ""} } { if { $inst == "" } { @@ -111,7 +135,11 @@ proc current_instance { {inst ""} } { ################################################################ -define_cmd_args "set_hierarchy_separator" { seperator } +define_cmd_args "set_hierarchy_separator" { separator } \ + -help {Set the character used to separate names in a hierarchical instance, net or pin name. This separator is used by the command interpreter to read arguments and print results. The default separator is '/'.} \ + -arg_help { + separator {Character used to separate hierarchical names.} + } set ::hierarchy_separator "/" @@ -135,7 +163,31 @@ proc check_path_divider { divider } { define_cmd_args "set_units" \ {[-time time_unit] [-capacitance cap_unit] [-resistance res_unit]\ [-voltage voltage_unit] [-current current_unit] [-power power_unit]\ - [-distance distance_unit]} + [-distance distance_unit]} \ + -help {The `set_units` command is used to check the units used by the STA command interpreter when parsing commands and reporting results. If the current units differ from the set_unit value a warning is printed. Use the `set_cmd_units` command to change the command units. + +Units are specified as a scale factor followed by a unit name. The scale factors are as follows. + +M 1E+6 +k 1E+3 +m 1E-3 +u 1E-6 +n 1E-9 +p 1E-12 +f 1E-15 + +An example of the `set_units` command is shown below. + +`set_units` `-time` ns `-capacitance` pF `-current` mA `-voltage` V `-resistance` kOhm} \ + -arg_help { + -capacitance {`cap_unit`: The capacitance scale factor followed by 'f'.} + -resistance {`res_unit`: The resistance scale factor followed by 'ohm'.} + -time {`time_unit`: The time scale factor followed by 's'.} + -voltage {`voltage_unit`: The voltage scale factor followed by 'v'.} + -current {`current_unit`: The current scale factor followed by 'A'.} + -power {`power_unit`: The power scale factor followed by 'w'.} + -distance {`distance_unit`: The distance scale factor followed by 'm'.} + } # Note that the set_units command does NOT actually set the units. # It merely checks that the current units are the same as the @@ -204,7 +256,8 @@ proc check_unit_scale { unit scale } { # ################################################################ -define_cmd_args "all_clocks" {} +define_cmd_args "all_clocks" {} \ + -help {The `all_clocks` command returns a list of all clocks that have been defined.} proc all_clocks { } { return [get_clocks -quiet *] @@ -212,7 +265,11 @@ proc all_clocks { } { ################################################################ -define_cmd_args "all_inputs" {[-no_clocks]} +define_cmd_args "all_inputs" {[-no_clocks]} \ + -help {The `all_inputs` command returns a list of all input and bidirect ports of the current design.} \ + -arg_help { + -no_clocks {Exclude inputs defined as clock sources.} + } proc all_inputs { args } { parse_key_args "all_inputs" args keys {} flags {-no_clocks} @@ -222,7 +279,8 @@ proc all_inputs { args } { ################################################################ -define_cmd_args "all_outputs" {} +define_cmd_args "all_outputs" {} \ + -help {The `all_outputs` command returns a list of all output and bidirect ports of the design.} proc all_outputs { args } { check_argc_eq0 "all_outputs" $args @@ -233,7 +291,20 @@ proc all_outputs { args } { define_cmd_args all_registers \ {[-clock clocks] [-rise_clock clocks] [-fall_clock clocks] [-cells] [-data_pins] [-clock_pins]\ - [-async_pins] [-output_pins] [-level_sensitive] [-edge_triggered]} + [-async_pins] [-output_pins] [-level_sensitive] [-edge_triggered]} \ + -help {The `all_registers` command returns a list of register instances or register pins in the design. Options allow the list of registers to be restricted in various ways. The `-clock` keyword restrcts the registers to those that are clocked by a set of clocks. The `-cells` option returns the list of registers or latches (the default). The `-data_pins`, `-clock_pins`, `-async_pins` and `-output_pins` options cause `all_registers` to return a list of register pins rather than instances.} \ + -arg_help { + -clock {`clock_names`: A list of clock names. Only registers clocked by these clocks are returned.} + -rise_clock {Only registers clocked by the rising edge of these clocks are returned.} + -fall_clock {Only registers clocked by the falling edge of these clocks are returned.} + -cells {Return a list of register instances.} + -data_pins {Return the register data pins.} + -clock_pins {Return the register clock pins.} + -async_pins {Return the register set/clear pins.} + -output_pins {Return the register output pins.} + -level_sensitive {Return level-sensitive latches.} + -edge_triggered {Return edge-triggered registers.} + } proc all_registers { args } { parse_key_args "all_registers" args keys {-clock -rise_clock -fall_clock} \ @@ -297,7 +368,8 @@ proc all_registers { args } { ################################################################ -define_cmd_args "current_design" {[design]} +define_cmd_args "current_design" {[design]} \ + -help {Set or report the current design. OpenSTA only supports one design.} variable current_design_name "" @@ -324,7 +396,17 @@ proc current_design { {design ""} } { define_cmd_args "get_cells" \ {[-hierarchical] [-hsc separator] [-filter expr]\ - [-regexp] [-nocase] [-quiet] [-of_objects objects] [patterns]} + [-regexp] [-nocase] [-quiet] [-of_objects objects] [patterns]} \ + -help {The `get_cells` command returns a list of all cell instances that match patterns.} \ + -arg_help { + -hierarchical {Searches hierarchy levels below the current instance for matches.} + -hsc {`separator`: Character to use to separate hierarchical instance names in patterns.} + -filter {A filter expression of the form + "property==value" +where property is a property supported by the `get_property` command. See the section "Filter Expressions" for additional forms.} + -of_objects {The name of a pin or net, a list of pins returned by `get_pins`, or a list of nets returned by `get_nets`. The `-hierarchical` option cannot be used with `-of_objects`.} + patterns {A list of instance name patterns.} + } define_cmd_alias "get_cell" "get_cells" @@ -407,7 +489,14 @@ proc get_cells { args } { ################################################################ -define_cmd_args "get_clocks" {[-regexp] [-nocase] [-quiet] [-filter expr] [patterns]} +define_cmd_args "get_clocks" {[-regexp] [-nocase] [-quiet] [-filter expr] [patterns]} \ + -help {The `get_clocks` command returns a list of all clocks that have been defined.} \ + -arg_help { + -filter {A filter expression of the form + "property==value" +where property is a property supported by the `get_property` command. See the section "Filter Expressions" for additional forms.} + patterns {A list of clock name patterns.} + } define_cmd_alias "get_clock" "get_clocks" @@ -452,7 +541,16 @@ proc get_clocks { args } { define_cmd_args "get_lib_cells" \ {[-hsc separator] [-regexp] [-nocase] [-quiet] [-filter expr]\ - [-of_objects objects] [patterns]} + [-of_objects objects] [patterns]} \ + -help {The `get_lib_cells` command returns a list of library cells that match pattern. The library name can be prepended to the cell name pattern with the separator character, which defaults to `hierarchy_separator`.} \ + -arg_help { + -of_objects {A list of instance objects.} + -hsc {`separator`: Character that separates the library name and cell name in patterns. Defaults to '/'.} + -filter {A filter expression of the form + "property==value" +where property is a property supported by the `get_property` command. See the section "Filter Expressions" for additional forms.} + patterns {A list of library cell name patterns of the form library_name/cell_name.} + } define_cmd_alias "get_lib_cell" "get_lib_cells" @@ -533,7 +631,16 @@ proc get_lib_cells { args } { define_cmd_args "get_lib_pins" \ {[-hsc separator] [-regexp] [-nocase] [-quiet] [-filter expr]\ - [-of_objects objects] [patterns]} + [-of_objects objects] [patterns]} \ + -help {The `get_lib_pins` command returns a list of library ports that match pattern. Use separator to separate the library and cell name patterns from the port name in pattern.} \ + -arg_help { + -of_objects {A list of library cell objects.} + -hsc {`separator`: Character that separates the library name, cell name and port name in pattern. Defaults to '/'.} + -filter {A filter expression of the form + "property==value" +where property is a property supported by the `get_property` command. See the section "Filter Expressions" for additional forms.} + patterns {A list of library port name patterns of the form library_name/cell_name/port_name.} + } define_cmd_alias "get_lib_pin" "get_lib_pins" @@ -642,7 +749,14 @@ proc check_nocase_flag { flags_var } { ################################################################ -define_cmd_args "get_libs" {[-regexp] [-nocase] [-quiet] [-filter expr] [patterns]} +define_cmd_args "get_libs" {[-regexp] [-nocase] [-quiet] [-filter expr] [patterns]} \ + -help {The `get_libs` command returns a list of clocks that match patterns.} \ + -arg_help { + -filter {A filter expression of the form + "property==value" +where property is a property supported by the `get_property` command. See the section "Filter Expressions" for additional forms.} + patterns {A list of library name patterns.} + } define_cmd_alias "get_lib" "get_libs" @@ -714,7 +828,17 @@ proc find_liberty_libraries_matching { pattern regexp nocase } { define_cmd_args "get_nets" \ {[-hierarchical] [-hsc separator] [-regexp] [-nocase] [-quiet] [-filter expr]\ - [-of_objects objects] [patterns]} + [-of_objects objects] [patterns]} \ + -help {The `get_nets` command returns a list of all nets that match patterns.} \ + -arg_help { + -hierarchical {Searches hierarchy levels below the current instance for matches.} + -hsc {`separator`: Character that separates the library name, cell name and port name in pattern. Defaults to '/'.} + -filter {A filter expression of the form + "property==value" +where property is a property supported by the `get_property` command. See the section "Filter Expressions" for additional forms.} + -of_objects {The name of a pin or instance, a list of pins returned by `get_pins`, or a list of instances returned by `get_cells`. The `-hierarchical` option cannot be used with `-of_objects`.} + patterns {A list of net name patterns.} + } define_cmd_alias "get_net" "get_nets" @@ -788,7 +912,23 @@ proc get_nets { args } { define_cmd_args "get_pins" \ {[-hierarchical] [-hsc separator] [-quiet] [-filter expr]\ - [-regexp] [-nocase] [-of_objects objects] [patterns]} + [-regexp] [-nocase] [-of_objects objects] [patterns]} \ + -help {The `get_pins` command returns a list of all instance pins that match patterns. + +A useful idiom to find the driver pin for a net is the following. + +``` +get_pins -of_objects [get_net net_name] -filter "direction==output" +```} \ + -arg_help { + -hierarchical {Searches hierarchy levels below the current instance for matches.} + -hsc {`separator`: Character that separates the library name, cell name and port name in pattern. Defaults to '/'.} + -filter {A filter expression of the form + "property==value" +where property is a property supported by the `get_property` command. See the section "Filter Expressions" for additional forms.} + -of_objects {The name of a net or instance, a list of nets returned by `get_nets`, or a list of instances returned by `get_cells`. The `-hierarchical` option cannot be used with `-of_objects`.} + patterns {A list of pin name patterns.} + } define_cmd_alias "get_pin" "get_pins" @@ -878,7 +1018,15 @@ proc get_pins { args } { ################################################################ define_cmd_args "get_ports" \ - {[-quiet] [-filter expr] [-regexp] [-nocase] [-of_objects objects] [patterns]} + {[-quiet] [-filter expr] [-regexp] [-nocase] [-of_objects objects] [patterns]} \ + -help {The `get_ports` command returns a list of all top level ports that match patterns.} \ + -arg_help { + -filter {A filter expression of the form + "property==value" +where property is a property supported by the `get_property` command. See the section "Filter Expressions" for additional forms.} + -of_objects {The name of net or a list of nets returned by `get_nets`.} + patterns {A list of port name patterns.} + } define_cmd_alias "get_port" "get_ports" @@ -939,7 +1087,35 @@ proc get_ports { args } { define_cmd_args "create_clock" \ {[-name name] [-period period] [-waveform waveform] [-add]\ - [-comment comment] [pins]} + [-comment comment] [pins]} \ + -help {The `create_clock` command defines the waveform of a clock used by the design. + +If no pin_list is specified the clock is virtual. A virtual clock can be refered to by name in input arrival and departure time commands but is not attached to any pins in the design. + +If no clock name is specified the name of the first pin is used as the clock name. + +If a wavform is not specified the clock rises at zero and falls at half the clock period. The waveform is a list with time the clock rises as the first element and the time it falls as the second element. + +If a clock is already defined on a pin the clock is redefined using the new clock parameters. If multiple clocks drive the same pin, use the `-add` option to prevent the existing definition from being overwritten. + +The following command creates a clock with a period of 10 time units that rises at time 0 and falls at 5 time units on the pin named clk1. + +``` +create_clock -period 10 clk1 +``` + +The following command creates a clock with a period of 10 time units that is high at time zero, falls at time 2 and rises at time 8. The clock drives three pins named clk1, clk2, and clk3. + +``` +create_clock -period 10 -waveform {8 2} -name clk {clk1 clk2 clk3} +```} \ + -arg_help { + -period {`period`: The clock period.} + -name {`clock_name`: The name of the clock.} + -waveform {`edge_list`: A list of edge rise and fall time.} + -add {Add this clock to the clocks on pin_list.} + pin_list {A list of pins driven by the clock.} + } proc create_clock { args } { parse_key_args "create_clock" args \ @@ -1007,7 +1183,12 @@ proc create_clock { args } { ################################################################ -define_cmd_args "delete_clock" {[-all] clocks} +define_cmd_args "delete_clock" {[-all] clocks} \ + -help {Delete clocks.} \ + -arg_help { + clocks {A list of clocks to remove.} + -all {Delete all clocks.} + } proc delete_clock { args } { parse_key_args "delete_clock" args keys {} flags {-all} @@ -1030,7 +1211,60 @@ define_cmd_args "create_generated_clock" \ [-divide_by divisor | -multiply_by multiplier]\ [-duty_cycle duty_cycle] [-invert] [-edges edge_list]\ [-edge_shift edge_shift_list] [-combinational] [-add]\ - [-comment comment] port_pin_list} + [-comment comment] port_pin_list} \ + -help {The `create_generated_clock` command is used to generate a clock from an existing clock definition. It is used to model clock generation circuits such as clock dividers and phase locked loops. + +The `-divide_by`, `-multiply_by` and `-edges` arguments are mutually exclusive. + +The `-multiply_by` option is used to generate a higher frequency clock from the source clock. The period of the generated clock is divided by multiplier. The clock multiplier must be a positive integer. If a duty cycle is specified the generated clock rises at zero and falls at period * duty_cycle / 100. If no duty cycle is specified the source clock edge times are divided by multiplier. + +The `-divide_by` option is used to generate a lower frequency clock from the source clock. The clock divisor must be a positive integer. If the clock divisor is a power of two the source clock period is multiplied by divisor, the clock rise time is the same as the source clock, and the clock fall edge is one half period later. If the clock divisor is not a power of two the source clock waveform edge times are multiplied by divisor. + +The `-edges` option forms the generated clock waveform by selecting edges from the source clock waveform. + +If the `-invert` option is specified the waveform derived above is inverted. + +If a clock is already defined on a pin the clock is redefined using the new clock parameters. If multiple clocks drive the same pin, use the `-add` option to prevent the existing definition from being overwritten. + +In the example show below generates a clock named gclk1 on register output pin r1/Q by dividing it by four. + +``` +create_clock -period 10 -waveform {1 8} clk1 +create_generated_clock -name gclk1 -source clk1 -divide_by 4 r1/Q +``` + +The generated clock has a period of 40, rises at time 1 and falls at time 21. + +In the example shown below the duty cycle is used to define the derived clock waveform. + +``` +create_generated_clock -name gclk1 -source clk1 -duty_cycle 50 \ + -multiply_by 2 r1/Q +``` + +The generated clock has a period of 5, rises at time .5 and falls at time 3. + +In the example shown below the first, third and fifth source clock edges are used to define the derived clock waveform. + +``` +create_generated_clock -name gclk1 -source clk1 -edges {1 3 5} r1/Q +``` + +The generated clock has a period of 20, rises at time 1 and falls at time 11.} \ + -arg_help { + -name {`clock_name`: The name of the generated clock.} + -source {`master_pin`: A pin or port in the fanout of the master clock that is the source of the generated clock.} + -master_clock {`master_clock`: Use `-master_clock` to specify which source clock to use when multiple clocks are present on master_pin.} + -divide_by {`divisor`: Divide the master clock period by divisor.} + -multiply_by {`multiplier`: Multiply the master clock period by multiplier.} + -duty_cycle {`duty_cycle`: The percent of the period that the generated clock is high (between 0 and 100).} + -invert {Invert the master clock.} + -edges {`edge_list`: List of master clock edges to use in the generated clock. Edges are numbered from 1. edge_list must be 3 edges long.} + -edge_shift {`shift_list`: Not supported.} + -add {Add this clock to the existing clocks on pin_list.} + -combinational {The generated clock is combinational, equivalent to `-divide_by 1`.} + pin_list {A list of pins driven by the generated clock.} + } proc create_generated_clock { args } { parse_key_args "create_generated_clock" args keys \ @@ -1161,7 +1395,12 @@ proc create_generated_clock { args } { ################################################################ -define_cmd_args "delete_generated_clock" {[-all] clocks} +define_cmd_args "delete_generated_clock" {[-all] clocks} \ + -help {Delete generated clocks.} \ + -arg_help { + clocks {A list of generated clocks to remove.} + -all {Delete all generated clocks.} + } proc delete_generated_clock { args } { remove_gclk_cmd "delete_generated_clock" $args @@ -1191,7 +1430,23 @@ define_cmd_args "group_path" \ [-from from_list] [-rise_from from_list] [-fall_from from_list]\ [-through through_list] [-rise_through through_list]\ [-fall_through through_list] [-to to_list] [-rise_to to_list]\ - [-fall_to to_list]} + [-fall_to to_list]} \ + -help {The `group_path` command is used to group paths reported by the `report_checks` command. See `set_false_path` for a description of allowed from_list, through_list and to_list objects.} \ + -arg_help { + -name {`group_name`: The name of the path group.} + -weight {`weight`: Not supported.} + -critical_range {`range`: Not supported.} + -from {Group paths from a list of clocks, instances, ports, register clock pins, or latch data pins.} + -rise_from {Group paths from the rising edge of clocks, instances, ports, register clock pins, or latch data pins.} + -fall_from {Group paths from the falling edge of clocks, instances, ports, register clock pins, or latch data pins.} + -through {Group paths through a list of instances, pins or nets.} + -rise_through {Group rising paths through a list of instances, pins or nets.} + -fall_through {Group falling paths through a list of instances, pins or nets.} + -to {Group paths to a list of clocks, instances, ports or pins.} + -rise_to {Group rising paths to a list of clocks, instances, ports or pins.} + -fall_to {Group falling paths to a list of clocks, instances, port-s or pins.} + -default {Restore the paths in the path group `-from`/`-to`/`-through`/`-to` to their default path group.} + } # The -weight and -critical_range arguments are ignored. proc group_path { args } { @@ -1251,7 +1506,27 @@ proc check_exception_pins { from to } { define_cmd_args "set_clock_gating_check" \ {[-setup setup_time] [-hold hold_time] [-rise] [-fall]\ - [-low] [-high] [objects]} + [-low] [-high] [objects]} \ + -help {The `set_clock_gating_check` command is used to add setup or hold timing checks for data signals used to gate clocks. + +If no objects are specified the setup/hold margin is global and applies to all clock gating circuits in the design. If neither of the `-rise` and `-fall` options are used the setup/hold margin applies to the rising and falling edges of the clock gating signal. + +Normally the library cell function is used to determine the active state of the clock. The clock is active high for AND/NAND functions and active low for OR/NOR functions. The `-high` and `-low` options are used to specify the active state of the clock for other cells, such as a MUX. + +If multiple `set_clock_gating_check` commands apply to a clock gating instance he priority of the commands is shown below (highest to lowest priority). + +``` +clock enable pin +instance +clock pin +clock +global +```} \ + -arg_help { + -high {The gating clock is active high (pin and instance objects only).} + -low {The gating clock is active low (pin and instance objects only).} + objects {A list of clocks, instances, pins or ports.} + } proc set_clock_gating_check { args } { parse_key_args "set_clock_gating_check" args keys {-setup -hold } \ @@ -1315,7 +1590,16 @@ proc set_clock_gating_check1 { args rf setup_hold margin active_value } { define_cmd_args "set_clock_groups" \ {[-name name] [-logically_exclusive] [-physically_exclusive]\ - [-asynchronous] [-allow_paths] [-comment comment] -group clocks} + [-asynchronous] [-allow_paths] [-comment comment] -group clocks} \ + -help {The `set_clock_groups` command is used to define groups of clocks that interact with each other. Clocks in different groups do not interact and paths between them are not reported. Use a `-group` argument for each clock group.} \ + -arg_help { + -name {`name`: The clock group name.} + -logically_exclusive {The clocks in different groups do not interact logically but can be physically present on the same chip. Paths between clock groups are considered for noise analysis.} + -physically_exclusive {The clocks in different groups cannot be present at the same time on a chip. Paths between clock groups are not considered for noise analysis.} + -asynchronous {The clock groups are asynchronous. Paths between clock groups are considered for noise analysis.} + -allow_paths {Allow paths between clock groups (do not mark them as false).} + -group {A list of clocks in one group. Repeat `-group` for each group.} + } proc set_clock_groups { args } { parse_key_args "set_clock_groups" args \ @@ -1369,7 +1653,15 @@ proc set_clock_groups { args } { define_cmd_args "unset_clock_groups" \ {[-logically_exclusive] [-physically_exclusive]\ - [-asynchronous] [-name names] [-all]} + [-asynchronous] [-name names] [-all]} \ + -help {The `unset_clock_groups` command removes clock groups defined with `set_clock_groups`. One of `-logically_exclusive`, `-physically_exclusive`, or `-asynchronous` is required. Use `-all` to remove every group of that type, or `-name` to remove named groups.} \ + -arg_help { + -logically_exclusive {Remove logically exclusive clock groups.} + -physically_exclusive {Remove physically exclusive clock groups.} + -asynchronous {Remove asynchronous clock groups.} + -name {Names of clock groups to remove.} + -all {Remove all clock groups of the specified type.} + } proc unset_clock_groups { args } { unset_clk_groups_cmd "unset_clock_groups" $args @@ -1429,7 +1721,16 @@ proc unset_clk_groups_cmd { cmd cmd_args } { define_cmd_args "set_clock_latency" \ {[-source] [-clock clock] [-rise] [-fall] [-min] [-max]\ - [-early] [-late] delay objects} + [-early] [-late] delay objects} \ + -help {The `set_clock_latency` command describes expected delays of the clock tree when analyzing a design using ideal clocks. Use the `-source` option to specify latency at the clock source, also known as insertion delay. Source latency is delay in the clock tree that is external to the design or a clock tree internal to an instance that implements a complex logic function. + +`set_clock_latency` removes propagated clock properties for the clocks and pins objects.} \ + -arg_help { + -source {The latency is at the clock source.} + -clock {`clock`: If multiple clocks are defined at a pin this use this option to specify the latency for a specific clock.} + delay {Clock source or insertion delay.} + objects {A list of clocks, pins or ports.} + } proc set_clock_latency { args } { parse_key_args "set_clock_latency" args keys {-clock} \ @@ -1486,7 +1787,13 @@ proc set_clock_latency { args } { ################################################################ -define_cmd_args "unset_clock_latency" {[-source] [-clock clock] objects} +define_cmd_args "unset_clock_latency" {[-source] [-clock clock] objects} \ + -help {The `unset_clock_latency` command removes the clock latency set with the `set_clock_latency` command.} \ + -arg_help { + -source {Specifies source clock latency (clock insertion delay).} + -clock {If multiple clocks are defined at a pin, specify which clock latency to remove.} + objects {A list of clocks, pins or ports.} + } proc unset_clock_latency { args } { unset_clk_latency_cmd "unset_clock_latency" $args @@ -1532,7 +1839,22 @@ proc unset_clk_latency_cmd { cmd cmd_args } { define_cmd_args "set_sense" \ {[-type clock|data] [-positive] [-negative] [-pulse pulse_type]\ - [-stop_propagation] [-clocks clocks] pins} + [-stop_propagation] [-clocks clocks] pins} \ + -help {The `set_sense` command is used to modify the propagation of a clock signal. The clock sense is set with the `-positive` and `-negative` flags. Use the `-stop_propagation` flag to stop the clock from propagating beyond a pin. The `-positive`, `-negative`, `-stop_propagation`, and `-pulse` options are mutually exclusive. If the `-clocks` option is not used the command applies to all clocks that traverse pins. The `-pulse` option is currently not supported.} \ + -arg_help { + -type {`clock`: Set the sense for clock paths. `data`: Set the sense for data paths (not supported).} + -positive {The clock sense is positive unate.} + -negative {The clock sense is negative unate.} + -pulse {`pulse_type`: rise_triggered_high_pulse +rise_triggered_low_pulse +fall_triggered_high_pulse +fall_triggered_low_pulse +Not supported.} + -stop_propagation {Stop propagating clocks at pins.} + -clocks {A list of clocks to apply the sense.} + clocks {A list of clocks to apply the sense.} + pins {A list of pins.} + } proc set_sense { args } { parse_key_args "set_sense" args keys {-type} flags {} 0 @@ -1553,7 +1875,16 @@ proc set_sense { args } { # deprecated in SDC 2.1 define_cmd_args "set_clock_sense" \ {[-positive] [-negative] [-pulse pulse_type] [-stop_propagation] \ - [-clock clocks] pins} + [-clock clocks] pins} \ + -help {The `set_clock_sense` command is deprecated as of SDC 2.1. Use `set_sense -type clock` instead.} \ + -arg_help { + -positive {The clock sense is positive unate.} + -negative {The clock sense is negative unate.} + -pulse {Pulse type. Not supported.} + -stop_propagation {Stop propagating clocks at pins.} + -clock {A list of clocks to apply the sense.} + pins {A list of pins.} + } proc set_clock_sense { args } { sta_warn 415 "set_clock_sense is deprecated as of SDC 2.1. Use set_sense -type clock." @@ -1599,7 +1930,12 @@ proc set_clock_sense_cmd1 { cmd cmd_args } { ################################################################ define_cmd_args "set_clock_transition" \ - {[-rise] [-fall] [-min] [-max] transition clocks} + {[-rise] [-fall] [-min] [-max] transition clocks} \ + -help {The `set_clock_transition` command describes expected transition times of the clock tree when analyzing a design using ideal clocks.} \ + -arg_help { + transition {Clock transition time (slew).} + clocks {A list of clocks.} + } proc set_clock_transition { args } { parse_key_args "set_clock_transition" args keys {} \ @@ -1623,7 +1959,11 @@ proc set_clock_transition { args } { ################################################################ -define_cmd_args "unset_clock_transition" {clocks} +define_cmd_args "unset_clock_transition" {clocks} \ + -help {The `unset_clock_transition` command removes the clock transition set with the `set_clock_transition` command.} \ + -arg_help { + clocks {A list of clocks.} + } proc unset_clock_transition { args } { check_argc_eq1 "unset_clock_transition" $args @@ -1639,7 +1979,31 @@ proc unset_clock_transition { args } { define_cmd_args "set_clock_uncertainty" \ {[-from|-rise_from|-fall_from from_clock]\ [-to|-rise_to|-fall_to to_clock] [-rise] [-fall]\ - [-setup] [-hold] uncertainty [objects]} + [-setup] [-hold] uncertainty [objects]} \ + -help {The `set_clock_uncertainty` command specifies the uncertainty or jitter in a clock. The uncertainty for a clock can be specified on its source pin or port, or the clock itself. + +``` +set_clock_uncertainty .1 [get_clock clk1] +``` + +Inter-clock uncertainty between the source and target clocks of timing checks is specified with the `-from`|`-rise_from`|`-fall_from` and `-to`|`-rise_to`|`-fall_to` arguments . + +``` +set_clock_uncertainty -from [get_clock clk1] -to [get_clocks clk2] .1 +``` + +The following commands are equivalent. + +``` +set_clock_uncertainty -from [get_clock clk1] -rise_to [get_clocks clk2] .1 +set_clock_uncertainty -from [get_clock clk1] -to [get_clocks clk2] -rise .1 +```} \ + -arg_help { + -from {`from_clock`: Inter-clock uncertainty source clock.} + -to {`to_clock`: Inter-clock uncertainty target clock.} + uncertainty {Clock uncertainty.} + objects {A list of clocks, ports or pins.} + } proc set_clock_uncertainty { args } { parse_key_args "set_clock_uncertainty" args \ @@ -1734,7 +2098,14 @@ proc set_clock_uncertainty { args } { define_cmd_args "unset_clock_uncertainty" \ {[-from|-rise_from|-fall_from from_clock]\ [-to|-rise_to|-fall_to to_clock] [-rise] [-fall]\ - [-setup] [-hold] [objects]} + [-setup] [-hold] [objects]} \ + -help {The `unset_clock_uncertainty` command removes clock uncertainty defined with the `set_clock_uncertainty` command.} \ + -arg_help { + -from {`from_clock`: Inter-clock uncertainty source clock.} + -to {`to_clock`: Inter-clock uncertainty target clock.} + uncertainty {Clock uncertainty.} + objects {A list of clocks, ports or pins.} + } proc unset_clock_uncertainty { args } { unset_clk_uncertainty_cmd "unset_clock_uncertainty" $args @@ -1820,7 +2191,14 @@ proc unset_clk_uncertainty_cmd { cmd cmd_args } { define_cmd_args "set_data_check" \ {[-from from_pin] [-rise_from from_pin] [-fall_from from_pin]\ [-to to_pin] [-rise_to to_pin] [-fall_to to_pin]\ - [-setup | -hold] [-clock clock] margin} + [-setup | -hold] [-clock clock] margin} \ + -help {The `set_data_check` command is used to add a setup or hold timing check between two pins.} \ + -arg_help { + -from {`from_pin`: A pin used as the timing check reference.} + -to {`to_pin`: A pin that the setup/hold check is applied to.} + -clock {`clock`: The setup/hold check clock.} + margin {The setup or hold time margin.} + } proc set_data_check { args } { parse_key_args "set_data_check" args \ @@ -1877,7 +2255,13 @@ proc set_data_check { args } { define_cmd_args "unset_data_check" \ {[-from from_pin] [-rise_from from_pin] [-fall_from from_pin]\ [-to to_pin] [-rise_to to_pin] [-fall_to to_pin]\ - [-setup | -hold] [-clock clock]} + [-setup | -hold] [-clock clock]} \ + -help {The `unset_clock_transition` command removes a setup or hold check defined by the `set_data_check` command.} \ + -arg_help { + -from {`from_object`: A pin used as the timing check reference.} + -to {`to_object`: A pin that the setup/hold check is applied to.} + -clock {The setup/hold check clock.} + } proc unset_data_check { args } { unset_data_checks_cmd "unset_data_check" $args @@ -1935,7 +2319,43 @@ proc unset_data_checks_cmd { cmd cmd_args } { ################################################################ define_cmd_args "set_disable_timing" \ - {[-from from_port] [-to to_port] objects} + {[-from from_port] [-to to_port] objects} \ + -help {The `set_disable_timing` command is used to disable paths though pins in the design. There are many different forms of the command depending on the objects specified in objects. + +All timing paths though an instance are disabled when objects contains an instance. Timing checks in the instance are not disabled. + +``` +set_disable_timing u2 +``` + +The `-from` and `-to` options can be used to restrict the disabled path to those from, to or between specific pins on the instance. + +``` +set_disable_timing -from A u2 +set_disable_timing -to Z u2 +set_disable_timing -from A -to Z u2 +``` + +A list of top level ports or instance pins can also be disabled. + +``` +set_disable_timing u2/Z +set_disable_timing in1 +``` + +Timing paths though all instances of a library cell in the design can be disabled by naming the cell using a hierarchy separator between the library and cell name. Paths from or to a cell port can be disabled with the `-from` and `-to` options or a port name after library and cell names. + +``` +set_disable_timing liberty1/snl_bufx2 +set_disable_timing -from A liberty1/snl_bufx +set_disable_timing -to Z liberty1/snl_bufx +set_disable_timing liberty1/snl_bufx2/A +```} \ + -arg_help { + -from {From pin of the disabled timing arc on an instance or cell.} + -to {To pin of the disabled timing arc on an instance or cell.} + objects {A list of instances, ports, pins, cells, cell/port, or library/cell/port.} + } # Parallax supports -from or -to alone. # OT requires both -from and -to args. @@ -2086,7 +2506,13 @@ proc parse_disable_cell_ports { cell port_name } { ################################################################ define_cmd_args "unset_disable_timing" \ - {[-from from_port] [-to to_port] objects} + {[-from from_port] [-to to_port] objects} \ + -help {The `unset_disable_timing` command is used to remove the effect of previous `set_disable_timing` commands.} \ + -arg_help { + -from {From pin of the disabled timing arc on an instance or cell.} + -to {To pin of the disabled timing arc on an instance or cell.} + objects {A list of instances, ports, pins, cells or [library/]cell/port.} + } proc unset_disable_timing { args } { unset_disable_cmd "unset_disable_timing" $args @@ -2189,7 +2615,20 @@ define_cmd_args "set_false_path" \ [-from from_list] [-rise_from from_list] [-fall_from from_list]\ [-through through_list] [-rise_through through_list]\ [-fall_through through_list] [-to to_list] [-rise_to to_list]\ - [-fall_to to_list]} + [-fall_to to_list]} \ + -help {The `set_false_path` command disables timing along a path from, through and to a group of design objects. + +Objects in from_list can be clocks, register/latch instances, or register/latch clock pins. The `-rise_from` and `-fall_from` keywords restrict the false paths to a specific clock edge. + +Objects in through_list can be nets, instances, instance pins, or hierarchical pins,. The `-rise_through` and `-fall_through` keywords restrict the false paths to a specific path edge that traverses through the object. + +Objects in to_list can be clocks, register/latch instances, or register/latch clock pins. The `-rise_to` and `-fall_to` keywords restrict the false paths to a specific transition at the path end.} \ + -arg_help { + -reset_path {Remove any matching `set_false_path`, `set_multicycle_path`, `set_max_delay`, `set_min_delay` exceptions first.} + -from {A list of clocks, instances, ports or pins.} + -through {A list of instances, pins or nets.} + -to {A list of clocks, instances, ports or pins.} + } proc set_false_path { args } { parse_key_args "set_false_path" args \ @@ -2235,7 +2674,8 @@ proc set_false_path { args } { ################################################################ define_cmd_args "set_ideal_latency" \ - {[-rise] [-fall] [-min] [-max] delay objects} + {[-rise] [-fall] [-min] [-max] delay objects} \ + -help {The `set_ideal_latency` command is parsed but ignored.} proc set_ideal_latency { args } { # ignored @@ -2248,7 +2688,11 @@ define_cmd_args "set_ideal_net" { nets } ################################################################ -define_cmd_args "set_ideal_network" {[-no_propagation] objects} +define_cmd_args "set_ideal_network" {[-no_propagation] objects} \ + -help {The `set_ideal_network` command is parsed but ignored.} \ + -arg_help { + -no_propagation {Do not propagate the ideal network. Ignored.} + } proc set_ideal_network { args } { # ignored @@ -2257,7 +2701,8 @@ proc set_ideal_network { args } { ################################################################ define_cmd_args "set_ideal_transition" \ - {[-rise] [-fall] [-min] [-max] transition_time objects} + {[-rise] [-fall] [-min] [-max] transition_time objects} \ + -help {The `set_ideal_transition` command is parsed but ignored.} proc set_ideal_transition { args } { # ignored @@ -2270,7 +2715,35 @@ define_cmd_args "set_input_delay" \ [-clock clock] [-clock_fall]\ [-reference_pin ref_pin]\ [-source_latency_included] [-network_latency_included]\ - [-add_delay] delay port_pin_list} + [-add_delay] delay port_pin_list} \ + -help {The `set_input_delay` command is used to specify the arrival time of an input signal. + +The following command sets the min, max, rise and fall times on the in1 input port 1.0 time units after the rising edge of clk1. + +``` +set_input_delay -clock clk1 1.0 [get_ports in1] +``` + +Use multiple commands with the `-add_delay` option to specify separate arrival times for min, max, rise and fall times or multiple clocks. For example, the following specifies separate arrival times with respect to clocks clk1 and clk2. + +``` +set_input_delay -clock clk1 1.0 [get_ports in1] +set_input_delay -add_delay -clock clk2 2.0 [get_ports in1] +``` + +The `-reference_pin` option is used to specify an arrival time with respect to the arrival on a pin in the clock network. For propagated clocks, the input arrival time is relative to the clock arrival time at the reference pin (the clock source latency and network latency from the clock source to the reference pin). For ideal clocks, input arrival time is relative to the reference pin clock source latency. With the `-clock_fall` flag the arrival time is relative to the falling transition at the reference pin. If no clocks arrive at the reference pin the `set_input_delay` command is ignored. If no `-clock` is specified the arrival time is with respect to all clocks that arrive at the reference pin. The `-source_latency_included` and `-network_latency_included` options cannot be used with `-reference_pin`. + +Paths from inputs that do not have an arrival time defined by `set_input_delay` are not reported. Set the `sta_input_port_default_clock` variable to 1 to report paths from inputs without a `set_input_delay`.} \ + -arg_help { + -clock {`clock`: The arrival time is from clock.} + -clock_fall {The arrival time is from the falling edge of clock.} + -reference_pin {`ref_pin`: The arrival time is with respect to the clock that arrives at ref_pin.} + -source_latency_included {D no add the clock source latency (insertion delay) to the delay value.} + -network_latency_included {Do not add the clock latency to the delay value when the clock is ideal.} + -add_delay {Add this arrival to any existing arrivals.} + delay {The arrival time after clock.} + pin_port_list {A list of pins or ports.} + } proc set_input_delay { args } { set_port_delay "set_input_delay" "set_input_delay_cmd" $args \ @@ -2336,7 +2809,13 @@ proc set_port_delay { cmd sta_cmd cmd_args port_dirs } { define_cmd_args "unset_input_delay" \ {[-rise] [-fall] [-max] [-min]\ [-clock clock] [-clock_fall]\ - port_pin_list} + port_pin_list} \ + -help {The `unset_input_delay` command removes a previously defined `set_input_delay`.} \ + -arg_help { + -clock {Unset the arrival time from clock.} + -clock_fall {Unset the arrival time from the falling edge of clock} + pin_port_list {A list of pins or ports.} + } proc unset_input_delay { args } { unset_port_delay "unset_input_delay" "unset_input_delay_cmd" $args @@ -2350,7 +2829,19 @@ define_cmd_args "set_max_delay" \ [-from from_list] [-rise_from from_list] [-fall_from from_list]\ [-through through_list] [-rise_through through_list]\ [-fall_through through_list]\ - [-to to_list] [-rise_to to_list] [-fall_to to_list] delay} + [-to to_list] [-rise_to to_list] [-fall_to to_list] delay} \ + -help {The `set_max_delay` command constrains the maximum delay through combinational logic paths. See `set_false_path` for a description of allowed from_list, through_list and to_list objects. If the to_list ends at a timing check the setup/hold time is included in the path delay. + +When the `-ignore_clock_latency` option is used clock latency at the source and destination of the path delay is ignored. The constraint is reported in the default path group (**default**) rather than the clock path group when the path ends at a timing check.} \ + -arg_help { + -from {A list of clocks, instances, ports or pins.} + -through {A list of instances, pins or nets.} + -to {A list of clocks, instances, ports or pins.} + -ignore_clock_latency {Ignore clock latency at the source and target registers.} + -probe {Do not break paths at internal pins (non startpoints).} + -reset_path {Remove any matching `set_false_path`, `set_multicycle_path`, `set_max_delay`, `set_min_delay` exceptions first.} + delay {The maximum delay.} + } proc set_max_delay { args } { set_path_delay "set_max_delay" $args max @@ -2397,7 +2888,12 @@ proc set_path_delay { cmd args min_max } { ################################################################ -define_cmd_args "set_max_time_borrow" {limit objects} +define_cmd_args "set_max_time_borrow" {limit objects} \ + -help {The `set_max_time_borrow` command specifies the maximum amount of time that latches can borrow. Time borrowing is the time that a data input to a transparent latch arrives after the latch opens.} \ + -arg_help { + delay {The maximum time the latches can borrow.} + objects {List of clocks, instances or pins.} + } proc set_max_time_borrow { limit objects } { check_positive_float "borrow_limit" $limit @@ -2422,7 +2918,19 @@ define_cmd_args "set_min_delay" \ [-from from_list] [-rise_from from_list] [-fall_from from_list]\ [-through through_list] [-rise_through through_list]\ [-fall_through through_list]\ - [-to to_list] [-rise_to to_list] [-fall_to to_list] delay} + [-to to_list] [-rise_to to_list] [-fall_to to_list] delay} \ + -help {The `set_min_delay` command constrains the minimum delay through combinational logic. See `set_false_path` for a description of allowed from_list, through_list and to_list objects. If the to_list ends at a timing check the setup/hold time is included in the path delay. + +When the `-ignore_clock_latency` option is used clock latency at the source and destination of the path delay is ignored. The constraint is reported in the default path group (**default**) rather than the clock path group when the path ends at a timing check.} \ + -arg_help { + -from {A list of clocks, instances, ports or pins.} + -through {A list of instances, pins or nets.} + -to {A list of clocks, instances, ports or pins.} + -ignore_clock_latency {Ignore clock latency at the source and target registers.} + -probe {Do not break paths at internal pins (non startpoints).} + -reset_path {Remove any matching `set_false_path`, `set_multicycle_path`, `set_max_delay`, `set_min_delay` exceptions first.} + delay {The minimum delay.} + } proc set_min_delay { args } { set_path_delay "set_min_delay" $args min @@ -2435,7 +2943,14 @@ define_cmd_args "set_path_margin" \ [-from from_list] [-rise_from from_list] [-fall_from from_list]\ [-through|-thr|-th through_list] [-rise_through|-rise_thr|-rise_th through_list]\ [-fall_through|-fall_thr|-fall_th through_list]\ - [-to to_list] [-rise_to to_list] [-fall_to to_list] margin} + [-to to_list] [-rise_to to_list] [-fall_to to_list] margin} \ + -help {The `set_path_margin` command applies a signed slack adjustment to matching timing paths on the capture-clock side. A positive margin makes the path harder to meet and a negative margin makes it easier. If neither `-setup` nor `-hold` is specified the margin applies to both. See `set_false_path` for a description of allowed from_list, through_list and to_list objects. At least one of `-from`, `-through`, or `-to` is required. Matching exceptions are removed with `unset_path_exceptions`.} \ + -arg_help { + -from {A list of clocks, instances, ports or pins.} + -through {A list of instances, pins or nets.} + -to {A list of clocks, instances, ports or pins.} + margin {Signed slack adjustment applied on the capture clock. A positive margin tightens the path and a negative margin loosens it.} + } proc set_path_margin { args } { parse_key_args "set_path_margin" args \ @@ -2485,7 +3000,13 @@ proc set_path_margin { args } { ################################################################ -define_cmd_args "set_min_pulse_width" {[-low] [-high] value [objects]} +define_cmd_args "set_min_pulse_width" {[-low] [-high] value [objects]} \ + -help {If `-low` and `-high` are not specified the minimum width applies to both high and low pulses.} \ + -arg_help { + -high {Set the minimum high pulse width.} + -low {Set the minimum low pulse width.} + objects {List of pins, instances or clocks.} + } proc set_min_pulse_width { args } { parse_key_args "set_min_pulse_width" args keys {} flags {-low -high} @@ -2528,7 +3049,17 @@ define_cmd_args "set_multicycle_path" \ [-from from_list] [-rise_from from_list]\ [-fall_from from_list] [-through through_list]\ [-rise_through through_list] [-fall_through through_list]\ - [-to to_list] [-rise_to to_list] [-fall_to to_list] path_multiplier} + [-to to_list] [-rise_to to_list] [-fall_to to_list] path_multiplier} \ + -help {Normally the path between two registers or latches is assumed to take one clock cycle. The `set_multicycle_path` command overrides this assumption and allows multiple clock cycles for a timing check. See `set_false_path` for a description of allowed from_list, through_list and to_list objects.} \ + -arg_help { + -start {Multiply the source clock period by period_multiplier.} + -end {Multiply the target clock period by period_multiplier.} + -from {A list of clocks, instances, ports or pins.} + -through {A list of instances, pins or nets.} + -to {A list of clocks, instances, ports or pins.} + -reset_path {Remove any matching `set_false_path`, `set_multicycle_path`, `set_max_delay`, `set_min_delay` exceptions first.} + path_multiplier {The number of clock periods to add to the path required time.} + } proc set_multicycle_path { args } { parse_key_args "set_multicycle_path" args \ @@ -2597,7 +3128,13 @@ define_cmd_args "unset_path_exceptions" \ [-rise_from from_list] [-fall_from from_list]\ [-through through_list] [-rise_through through_list]\ [-fall_through through_list] [-to to_list] [-rise_to to_list]\ - [-fall_to to_list]} + [-fall_to to_list]} \ + -help {The `unset_path_exceptions` command removes any matching `set_false_path`, `set_multicycle_path`, `set_max_delay`, `set_min_delay`, and `set_path_margin` exceptions.} \ + -arg_help { + -from {`from`: A list of clocks, instances, ports or pins.} + -through {`through`: A list of instances, pins or nets.} + -to {`to`: A list of clocks, instances, ports or pins.} + } proc unset_path_exceptions { args } { unset_path_exceptions_cmd "unset_path_exceptions" $args @@ -2647,7 +3184,20 @@ define_cmd_args "set_output_delay" \ [-clock clock] [-clock_fall]\ [-reference_pin ref_pin]\ [-source_latency_included] [-network_latency_included]\ - [-add_delay] delay port_pin_list} + [-add_delay] delay port_pin_list} \ + -help {The `set_output_delay` command is used to specify the external delay to a setup/hold check on an output port or internal pin that is clocked by clock. Unless the `-add_delay` option is specified any existing output delays are replaced. + +The `-reference_pin` option is used to specify a timing check with respect to the arrival on a pin in the clock network. For propagated clocks, the timing check is relative to the clock arrival time at the reference pin (the clock source latency and network latency from the clock source to the reference pin). For ideal clocks, the timing check is relative to the reference pin clock source latency. With the `-clock_fall` flag the timing check is relative to the falling edge of the reference pin. If no clocks arrive at the reference pin the `set_output_delay` command is ignored. If no `-clock` is specified the timing check is with respect to all clocks that arrive at the reference pin. The `-source_latency_included` and `-network_latency_included` options cannot be used with `-reference_pin`.} \ + -arg_help { + -clock {`clock`: The external check is to clock. The default clock edge is rising.} + -clock_fall {The external check is to the falling edge of clock.} + -reference_pin {`ref_pin`: The external check is clocked by the clock that arrives at ref_pin.} + -source_latency_included {Do not add the clock source latency (insertion delay) to the delay value.} + -network_latency_included {Do not add the clock latency to the delay value when the clock is ideal.} + -add_delay {Add this output delay to any existing output delays.} + delay {The external delay to the check clocked by clock.} + pin_port_list {A list of pins or ports.} + } proc set_output_delay { args } { set_port_delay "set_output_delay" "set_output_delay_cmd" $args \ @@ -2659,7 +3209,13 @@ proc set_output_delay { args } { define_cmd_args "unset_output_delay" \ {[-rise] [-fall] [-max] [-min]\ [-clock clock] [-clock_fall]\ - port_pin_list} + port_pin_list} \ + -help {The `unset_output_delay` command a previously defined `set_output_delay`.} \ + -arg_help { + -clock {The arrival time is from this clock.} + -clock_fall {The arrival time is from the falling edge of clock} + pin_port_list {A list of pins or ports.} + } proc unset_output_delay { args } { unset_port_delay "unset_output_delay" "unset_output_delay_cmd" $args @@ -2694,7 +3250,11 @@ proc unset_port_delay { cmd swig_cmd cmd_args } { ################################################################ -define_cmd_args "set_propagated_clock" {objects} +define_cmd_args "set_propagated_clock" {objects} \ + -help {The `set_propagated_clock` command changes a clock tree from an ideal network that has no delay one that uses calculated or back-annotated gate and interconnect delays. When objects is a port or pin, clock delays downstream of the object are used.} \ + -arg_help { + objects {A list of clocks, ports or pins.} + } proc set_propagated_clock { objects } { parse_clk_port_pin_arg $objects clks pins @@ -2712,7 +3272,11 @@ proc set_propagated_clock { objects } { ################################################################ -define_cmd_args "unset_propagated_clock" {objects} +define_cmd_args "unset_propagated_clock" {objects} \ + -help {Remove a previous `set_propagated_clock` command.} \ + -arg_help { + objects {A list of clocks, ports or pins.} + } proc unset_propagated_clock { objects } { parse_clk_port_pin_arg $objects clks pins @@ -2731,7 +3295,13 @@ proc unset_propagated_clock { objects } { ################################################################ define_cmd_args "set_case_analysis" \ - {0|1|zero|one|rise|rising|fall|falling pins} + {0|1|zero|one|rise|rising|fall|falling pins} \ + -help {The `set_case_analysis` command sets the signal on a port or pin to a constant logic value. No paths are propagated from constant pins. Constant values set with the `set_case_analysis` command are propagated through downstream gates. + +Conditional timing arcs with mode groups are controlled by logic values on the instance pins.} \ + -arg_help { + port_or_pin_list {A list of ports or pins.} + } proc set_case_analysis { value pins } { if { !($value == "0" \ @@ -2752,7 +3322,11 @@ proc set_case_analysis { value pins } { ################################################################ -define_cmd_args "unset_case_analysis" {pins} +define_cmd_args "unset_case_analysis" {pins} \ + -help {The `unset_case_analysis` command removes the constant values defined by the `set_case_analysis` command.} \ + -arg_help { + port_or_pin_list {A list of ports or pins.} + } proc unset_case_analysis { pins } { set pins1 [get_port_pins_error "pins" $pins] @@ -2764,7 +3338,12 @@ proc unset_case_analysis { pins } { ################################################################ define_cmd_args "set_drive" {[-rise] [-fall] [-min] [-max] \ - resistance ports} + resistance ports} \ + -help {The `set_drive` command describes the resistance of an input port external driver.} \ + -arg_help { + resistance {The external drive resistance.} + ports {A list of ports.} + } proc set_drive { args } { parse_key_args "set_drive" args keys {} flags {-rise -fall -min -max} @@ -2789,7 +3368,20 @@ define_cmd_args "set_driving_cell" \ [-rise] [-fall] [-min] [-max]\ [-pin pin] [-from_pin from_pin]\ [-input_transition_rise trans_rise] [-input_transition_fall trans_fall]\ - [-multiply_by factor] [-dont_scale] [-no_design_rule] ports} + [-multiply_by factor] [-dont_scale] [-no_design_rule] ports} \ + -help {The `set_driving_cell` command describes an input port external driver.} \ + -arg_help { + -lib_cell {`cell_name`: The driving cell.} + -library {`library`: The driving cell library.} + -pin {`pin`: The output port of the driving cell.} + -from_pin {`from_pin`: Use timing arcs from from_pin to the output pin.} + -input_transition_rise {`trans_rise`: The transition time for a rising input at from_pin.} + -input_transition_fall {`trans_fall`: The transition time for a falling input at from_pin.} + -multiply_by {Scale factor applied to the driving cell delay. Ignored.} + -dont_scale {Do not scale the driving cell delay. Ignored.} + -no_design_rule {Do not apply driving cell design rules. Ignored.} + ports {A list of ports.} + } proc set_driving_cell { args } { parse_key_args "set_driving_cell" args \ @@ -2907,7 +3499,8 @@ proc port_direction_any_output { dir } { ################################################################ -define_cmd_args "set_fanout_load" {fanout ports} +define_cmd_args "set_fanout_load" {fanout ports} \ + -help {This command is ignored.} proc set_fanout_load { fanout port_list } { sta_warn 461 "set_fanout_load not supported." @@ -2916,7 +3509,12 @@ proc set_fanout_load { fanout port_list } { ################################################################ define_cmd_args "set_input_transition" \ - {[-rise] [-fall] [-min] [-max] transition ports} + {[-rise] [-fall] [-min] [-max] transition ports} \ + -help {The `set_input_transition` command is used to specify the transition time (slew) of an input signal.} \ + -arg_help { + transition {The transition time (slew).} + port_list {A list of ports.} + } proc set_input_transition { args } { parse_key_args "set_input_transition" args keys {-clock} \ @@ -2953,7 +3551,26 @@ proc set_input_transition { args } { # set_load net overrides parasitics define_cmd_args "set_load" \ {[-rise] [-fall] [-max] [-min] [-subtract_pin_load]\ - [-pin_load] [-wire_load] capacitance objects} + [-pin_load] [-wire_load] capacitance objects} \ + -help {The `set_load` command annotates wire capacitance on a net or external capacitance on a port. There are four different uses for the `set_load` commanc: + +``` +set_load -wire_load port external port wire capacitance +set_load -pin_load port external port pin capacitance +set_load port same as -pin_load +set_load net net wire capacitance +``` + +External port capacitance can be annotated separately with the `-pin_load` and `-wire_load` options. Without the `-pin_load` and `-wire_load` options pin capacitance is annotated. + +When annotating net wire capacitance with the `-subtract_pin_load` option the capacitance of all instance pins connected to the net is subtracted from capacitance. Setting the capacitance on a net overrides SPEF parasitics for delay calculation.} \ + -arg_help { + -subtract_pin_load {Subtract the capacitance of all instance pins connected to the net from capacitance (nets only). If the resulting capacitance is negative, zero is used. Pin capacitances are ignored by delay calculation when this option is used.} + -pin_load {capacitance is external instance pin capacitance (ports only).} + -wire_load {capacitance is external wire capacitance (ports only).} + capacitance {The capacitance, in library capacitance units.} + objects {A list of nets or ports.} + } proc set_load { args } { parse_key_args "set_load" args keys {} \ @@ -3004,7 +3621,11 @@ proc set_load { args } { ################################################################ -define_cmd_args "set_logic_dc" {port_list} +define_cmd_args "set_logic_dc" {port_list} \ + -help {Set a port or pin to a constant unknown logic value. No paths are propagated from constant pins.} \ + -arg_help { + port_pin_list {List of ports or pins.} + } proc set_logic_dc { port_list } { set_logic_value $port_list "X" @@ -3021,7 +3642,11 @@ proc set_logic_value { port_list value } { ################################################################ -define_cmd_args "set_logic_one" {port_list} +define_cmd_args "set_logic_one" {port_list} \ + -help {Set a port or pin to a constant logic one value. No paths are propagated from constant pins. Constant values set with the `set_logic_one` command are not propagated through downstream gates.} \ + -arg_help { + port_pin_list {List of ports or pins.} + } proc set_logic_one { port_list } { set_logic_value $port_list "1" @@ -3029,7 +3654,11 @@ proc set_logic_one { port_list } { ################################################################ -define_cmd_args "set_logic_zero" {port_list} +define_cmd_args "set_logic_zero" {port_list} \ + -help {Set a port or pin to a constant logic zero value. No paths are propagated from constant pins. Constant values set with the `set_logic_zero` command are not propagated through downstream gates.} \ + -arg_help { + port_pin_list {List of ports or pins.} + } proc set_logic_zero { port_list } { set_logic_value $port_list "0" @@ -3037,7 +3666,8 @@ proc set_logic_zero { port_list } { ################################################################ -define_cmd_args "set_max_area" {area} +define_cmd_args "set_max_area" {area} \ + -help {The `set_max_area` command is ignored during timing but is included in SDC files that are written.} proc set_max_area { area } { check_positive_float "area" $area @@ -3046,7 +3676,11 @@ proc set_max_area { area } { ################################################################ -define_cmd_args "set_max_capacitance" {cap objects} +define_cmd_args "set_max_capacitance" {cap objects} \ + -help {The `set_max_capacitance` command is ignored during timing but is included in SDC files that are written.} \ + -arg_help { + objects {List of ports or cells.} + } proc set_max_capacitance { cap objects } { set_capacitance_limit $cap "max" $objects @@ -3069,7 +3703,11 @@ proc set_capacitance_limit { cap min_max objects } { ################################################################ -define_cmd_args "set_max_fanout" {fanout objects} +define_cmd_args "set_max_fanout" {fanout objects} \ + -help {The `set_max_fanout` command is ignored during timing but is included in SDC files that are written.} \ + -arg_help { + objects {List of ports or cells.} + } proc set_max_fanout { fanout objects } { set_fanout_limit $fanout "max" $objects @@ -3093,7 +3731,18 @@ proc set_fanout_limit { fanout min_max objects } { ################################################################ define_cmd_args "set_max_transition" \ - {[-clock_path] [-data_path] [-rise] [-fall] slew objects} + {[-clock_path] [-data_path] [-rise] [-fall] slew objects} \ + -help {The `set_max_transition` command is specifies the maximum transition time (slew) design rule checked by the `report_check_types` `-max_transition` command. + +If specified for a design, the default maximum transition is set for the design. + +If specified for a clock, the maximum transition is applied to all pins in the clock domain. The `-clock_path` option restricts the maximum transition to clocks in clock paths. The `-data_path` option restricts the maximum transition to clocks data paths. The `-clock_path`, `-data_path`, `-rise` and `-fall` options only apply to clock objects.} \ + -arg_help { + -data_path {Set the max slew for data paths.} + -clock_path {Set the max slew for clock paths.} + transition {The maximum slew/transition time.} + objects {List of clocks, ports or designs.} + } proc set_max_transition { args } { parse_key_args "set_max_transition" args keys {} \ @@ -3147,7 +3796,12 @@ proc set_max_transition { args } { ################################################################ define_cmd_args "set_port_fanout_number" \ - {[-max] [-min] fanout ports} + {[-max] [-min] fanout ports} \ + -help {Set the external fanout for ports.} \ + -arg_help { + fanout {The external fanout of the ports.} + port_list {A list of ports.} + } proc set_port_fanout_number { args } { parse_key_args "set_port_fanout_number" args keys {} flags {-max -min} @@ -3165,7 +3819,12 @@ proc set_port_fanout_number { args } { ################################################################ -define_cmd_args "set_resistance" {[-min] [-max] resistance nets} +define_cmd_args "set_resistance" {[-min] [-max] resistance nets} \ + -help {Set the resistance of nets.} \ + -arg_help { + resistance {The net resistance.} + nets {A list of nets.} + } proc set_resistance { args } { parse_key_args "set_resistance" args keys {} flags {-max -min} @@ -3186,7 +3845,21 @@ proc set_resistance { args } { define_cmd_args "set_timing_derate" \ {-early|-late [-rise] [-fall] [-clock] [-data] \ - [-net_delay] [-cell_delay] [-cell_check] derate [objects]} + [-net_delay] [-cell_delay] [-cell_check] derate [objects]} \ + -help {The `set_timing_derate` command is used to derate delay calculation results used by the STA. If the `-early` and `-late` flags are omitted the both min and max paths are derated. If the `-clock` and `-data` flags are not used the derating both clock and data paths are derated. + +Use the `unset_timing_derate` command to remove all derating factors.} \ + -arg_help { + -early {Derate early (min) paths.} + -late {Derate late (max) paths.} + -clock {Derate paths in the clock network.} + -data {Derate data paths.} + -net_delay {Derate net (interconnect) delays.} + -cell_delay {Derate cell delays.} + -cell_check {Derate cell timing check margins.} + derate {The derating factor to apply to delays.} + objects {A list of instances, library cells, or nets.} + } proc set_timing_derate { args } { parse_key_args "set_timing_derate" args keys {} \ @@ -3276,7 +3949,8 @@ proc set_timing_derate { args } { ################################################################ -define_cmd_args "unset_timing_derate" {} +define_cmd_args "unset_timing_derate" {} \ + -help {Remove all derating factors set with the `set_timing_derate` command.} proc unset_timing_derate { args } { check_argc_eq0 "unset_timing_derate" $args @@ -3418,7 +4092,12 @@ proc parse_comment_key { keys_var } { ################################################################ -define_cmd_args "set_min_capacitance" {cap objects} +define_cmd_args "set_min_capacitance" {cap objects} \ + -help {The `set_min_capacitance` command is ignored during timing but is included in SDC files that are written.} \ + -arg_help { + capacitance {Minimum capacitance.} + objects {List of ports or cells.} + } proc set_min_capacitance { cap objects } { set_capacitance_limit $cap "min" $objects @@ -3429,7 +4108,15 @@ proc set_min_capacitance { cap objects } { define_cmd_args "set_operating_conditions" \ {[-analysis_type single|bc_wc|on_chip_variation] [-library lib]\ [condition] [-min min_condition] [-max max_condition]\ - [-min_library min_lib] [-max_library max_lib]} + [-min_library min_lib] [-max_library max_lib]} \ + -help {The `set_operating_conditions` command is used to specify the type of analysis performed and the operating conditions used to derate library data.} \ + -arg_help { + -analysis_type {`single`: Use one operating condition for min and max paths. `bc_wc`: Best case, worst case analysis. Setup checks use max_condition for clock and data paths. Hold checks use the min_condition for clock and data paths. `on_chip_variation`: The min and max operating conditions represent variations on the chip that can occur simultaneously. Setup checks use max_condition for data paths and min_condition for clock paths. Hold checks use min_condition for data paths and max_condition for clock paths. This is the default analysis type.} + -library {`lib`: The name of the library that contains condition.} + condition {The operating condition for analysis type single.} + -min_library {`min_lib`: The name of the library that contains min_condition.} + -max_library {`max_lib`: The name of the library that contains max_condition.} + } proc set_operating_conditions { args } { parse_key_args "set_operating_conditions" args \ @@ -3495,7 +4182,8 @@ proc parse_op_cond_analysis_type { key_var } { ################################################################ -define_cmd_args "set_wire_load_min_block_size" {block_size} +define_cmd_args "set_wire_load_min_block_size" {block_size} \ + -help {The `set_wire_load_min_block_size` command is not supported.} proc set_wire_load_min_block_size { block_size } { sta_warn 477 "set_wire_load_min_block_size not supported." @@ -3503,7 +4191,8 @@ proc set_wire_load_min_block_size { block_size } { ################################################################ -define_cmd_args "set_wire_load_mode" "top|enclosed|segmented" +define_cmd_args "set_wire_load_mode" "top|enclosed|segmented" \ + -help {The `set_wire_load_mode` command is ignored during timing but is included in SDC files that are written.} proc set_wire_load_mode { mode } { if { $mode == "top" \ @@ -3518,7 +4207,13 @@ proc set_wire_load_mode { mode } { ################################################################ define_cmd_args "set_wire_load_model" \ - {-name model_name [-library lib_name] [-min] [-max] [objects]} + {-name model_name [-library lib_name] [-min] [-max] [objects]} \ + -help {Set the wire load model used to estimate net parasitics.} \ + -arg_help { + -name {`model_name`: The name of a wire load model.} + -library {`library`: Library to look for model_name.} + objects {Not supported.} + } proc set_wire_load_model { args } { parse_key_args "set_wire_load_model" args keys {-name -library} \ @@ -3557,7 +4252,13 @@ proc set_wire_load_model { args } { ################################################################ define_cmd_args "set_wire_load_selection_group" \ - {[-library lib] [-min] [-max] group_name [objects]} + {[-library lib] [-min] [-max] group_name [objects]} \ + -help {The `set_wire_load_selection_group` command is parsed but not supported.} \ + -arg_help { + -library {Library to look for group_name.} + group_name {A wire load selection group name.} + objects {Not supported.} + } proc set_wire_load_selection_group { args } { parse_key_args "set_wire_load_selection_group" args keys {-library} \ @@ -3599,7 +4300,13 @@ proc set_wire_load_selection_group { args } { ################################################################ define_cmd_args "set_voltage" \ - {[-min min_case_value] [-object_list power_nets] max_case_voltage} + {[-min min_case_value] [-object_list power_nets] max_case_voltage} \ + -help {The `set_voltage` command sets the supply voltage used by SDC. The max-case voltage is always set globally. If `-object_list` is given, it is also set on those power nets.} \ + -arg_help { + -min {Minimum (min delay) voltage. If omitted, only the max-case voltage is set.} + -object_list {Power nets to apply the voltage to.} + max_case_voltage {Maximum (max delay) voltage.} + } proc set_voltage { args } { parse_key_args "set_voltage" args keys {-min -object_list} flags {} @@ -3627,7 +4334,14 @@ proc set_voltage { args } { define_cmd_args "create_voltage_area" \ {[-name name] [-coordinate coordinates] [-guard_band_x guard_x]\ - [-guard_band_y guard_y] cells } + [-guard_band_y guard_y] cells } \ + -help {This command is parsed and ignored by timing analysis.} \ + -arg_help { + -name {Voltage area name. Ignored.} + -coordinate {Voltage area coordinates. Ignored.} + -guard_band_x {X guard band. Ignored.} + -guard_band_y {Y guard band. Ignored.} + } proc create_voltage_area { args } { # ignored @@ -3635,7 +4349,11 @@ proc create_voltage_area { args } { ################################################################ -define_cmd_args "set_level_shifter_strategy" {[-rule rule_type]} +define_cmd_args "set_level_shifter_strategy" {[-rule rule_type]} \ + -help {This command is parsed and ignored by timing analysis.} \ + -arg_help { + -rule {Level shifter rule. Ignored.} + } proc set_level_shifter_strategy { args } { # ignored @@ -3643,7 +4361,11 @@ proc set_level_shifter_strategy { args } { ################################################################ -define_cmd_args "set_level_shifter_threshold" {[-voltage volt]} +define_cmd_args "set_level_shifter_threshold" {[-voltage volt]} \ + -help {This command is parsed and ignored by timing analysis.} \ + -arg_help { + -voltage {Voltage threshold. Ignored.} + } proc set_level_shifter_threshold { args } { # ignored @@ -3651,7 +4373,8 @@ proc set_level_shifter_threshold { args } { ################################################################ -define_cmd_args "set_max_dynamic_power" {power [unit]} +define_cmd_args "set_max_dynamic_power" {power [unit]} \ + -help {The `set_max_dynamic_power` command is ignored during timing but is included in SDC files that are written.} proc set_max_dynamic_power { power {unit {}} } { check_positive_float "power" $power @@ -3661,7 +4384,8 @@ proc set_max_dynamic_power { power {unit {}} } { ################################################################ -define_cmd_args "set_max_leakage_power" {power [unit]} +define_cmd_args "set_max_leakage_power" {power [unit]} \ + -help {The `set_max_leakage_power` command is ignored during timing but is included in SDC files that are written.} proc set_max_leakage_power { power {unit {}} } { check_positive_float "power" $power @@ -3677,7 +4401,14 @@ proc set_max_leakage_power { power {unit {}} } { define_cmd_args "set_pvt"\ {insts [-min] [-max] [-process process] [-voltage voltage]\ - [-temperature temperature]} + [-temperature temperature]} \ + -help {The `set_pvt` command sets the process, voltage and temperature values used during delay calculation for a specific instance in the design.} \ + -arg_help { + -process {`process`: A process value (float).} + -voltage {`voltage`: A voltage value (float).} + -temperature {`temperature`: A temperature value (float).} + instances {A list instances.} + } proc set_pvt { args } { parse_key_args "set_pvt" args \ diff --git a/sdc/Variables.tcl b/sdc/Variables.tcl index 0ea666905..ed14b1650 100644 --- a/sdc/Variables.tcl +++ b/sdc/Variables.tcl @@ -191,6 +191,62 @@ proc trace_pocv_quantile { name1 name2 op } { ################################################################ +define_var_help hierarchy_separator {/ @ ^ # . |} \ + {The `hierarchy_separator` separates instance names in a hierarchical instance, net, or pin name. The default value is '/'.} + +define_var_help sta_continue_on_error {0|1} \ + {The `include` and `read_sdc` commands stop and report any errors encountered while reading a file unless `sta_continue_on_error` is 1. The default value is 0.} + +define_var_help sta_report_default_digits {integer} \ + {The number of digits to print after a decimal point. The default value is 2.} + +define_var_help sta_crpr_enabled {0|1} \ + {During min/max timing analysis for on_chip_variation the data and clock paths may overlap. For a setup check the maximum path delays are used for the data and the minimum path delays are used for the clock. Because the gates cannot simultaneously have minimum and maximum delays the timing check slack is pessimistic. This pessimism is known as Common Reconvergent Pessimism Removal, or CRPR. Enabling CRPR slows down the analysis. The default value is 1.} + +define_var_help sta_crpr_mode {same_pin|same_transition} \ + {When the data and clock paths of a timing check overlap (see `sta_crpr_enabled`), pessimism is removed independent of the path rise/fall transitions. When `sta_crpr_mode` is `same_transition`, the pessimism is only removed if the path rise/fall transitions are the same. The default value is `same_pin`.} + +define_var_help sta_cond_default_arcs_enabled {0|1} \ + {When set to 0, default timing arcs with no condition (Liberty timing arcs with no when expression) are disabled if there are other conditional timing arcs between the same pins. The default value is 1.} + +define_var_help sta_gated_clock_checks_enabled {0|1} \ + {When `sta_gated_clock_checks_enabled` is 1, clock gating setup and hold timing checks are checked. The default value is 1.} + +define_var_help sta_internal_bidirect_instance_paths_enabled {0|1} \ + {When set to 0, paths from bidirectional (inout) ports back into the instance are disabled. When set to 1, paths from bidirectional ports back into the instance are enabled. The default value is 0.} + +define_var_help sta_preset_clear_arcs_enabled {0|1} \ + {When set to 1, paths through asynchronous preset and clear timing arcs are searched. The default value is 0.} + +define_var_help sta_recovery_removal_checks_enabled {0|1} \ + {When `sta_recovery_removal_checks_enabled` is 0, recovery and removal timing checks are disabled. The default value is 1.} + +define_var_help sta_dynamic_loop_breaking {0|1} \ + {When `sta_dynamic_loop_breaking` is 0, combinational logic loops are disabled by disabling a timing arc that closes the loop. When `sta_dynamic_loop_breaking` is 1, all paths around the loop are reported. The default value is 0.} + +define_var_help sta_input_port_default_clock {0|1} \ + {When `sta_input_port_default_clock` is 1 a default input arrival is added for input ports that do not have an arrival time specified with the `set_input_delay` command. The default value is 0.} + +define_var_help sta_propagate_all_clocks {0|1} \ + {All clocks defined after `sta_propagate_all_clocks` is set to 1 are propagated. If it is set before any clocks are defined it has the same effect as + +``` +set_propagated_clock [all_clocks] +``` + +after all clocks have been defined. The default value is 0.} + +define_var_help sta_propagate_gated_clock_enable {0|1} \ + {When set to 1, paths of gated clock enables are propagated through the clock gating instances. If the gated clock controls sequential elements setting `sta_propagate_gated_clock_enable` to 0 prevents spurious paths from the clock enable. The default value is 1.} + +define_var_help sta_pocv_mode {scalar|normal|skew_normal} \ + {Enable parametric on chip variation using statistical timing analysis. The default value is `scalar`.} + +define_var_help sta_pocv_quantile {float} \ + {The target quantile of a delay probability distribution (confidence level). The default value is 3 standard deviations, or sigma.} + +################################################################ + proc trace_boolean_var { op var_name get_proc set_proc } { upvar 1 $var_name var diff --git a/sdf/Sdf.tcl b/sdf/Sdf.tcl index bdbb1de89..500c4d65f 100644 --- a/sdf/Sdf.tcl +++ b/sdf/Sdf.tcl @@ -27,7 +27,26 @@ namespace eval sta { define_cmd_args "read_sdf" \ {[-path path] [-scene scene]\ [-cond_use min|max|min_max]\ - [-unescaped_dividers] filename} + [-unescaped_dividers] filename} \ + -help {Read SDF delays from a file. The min and max values in the SDF tuples are used to annotate delays. Typical values in the SDF tuples are ignored. If multiple scenes are defined `-scene` must be specified. SDC annotation for MCMM analysis must follow the scene definitions. + +Files compressed with gzip are automatically uncompressed. + +INCREMENT is supported as an alias for INCREMENTAL. + +The following SDF statements are not supported. + +``` +PORT +INSTANCE wildcards +```} \ + -arg_help { + -scene {Scene delays to annotate.} + -path {Hierarchical instance path prefix for SDF annotation.} + -cond_use {`min`: Use SDF COND delays for min analysis. `max`: Use COND delays for max analysis. `min_max`: Use COND delays for min and max analysis.} + -unescaped_dividers {With this option path names in the SDF do not have to escape hierarchy dividers when the path name is escaped. For example, the escaped Verilog name "\inst1/inst2 " can be referenced as "inst1/inst2". The correct SDF name is "inst1\/inst2", since the divider does not represent a change in hierarchy in this case.} + filename {The name of the SDF file to read.} + } proc_redirect read_sdf { parse_key_args "read_sdf" args \ @@ -66,7 +85,18 @@ proc_redirect read_sdf { define_cmd_args "report_annotated_delay" \ {[-cell] [-net] [-from_in_ports] [-to_out_ports]\ [-scene scene] [-max_lines lines]\ - [-report_annotated] [-report_unannotated] [-constant_arcs]} + [-report_annotated] [-report_unannotated] [-constant_arcs]} \ + -help {The `report_annotated_delay` command reports a summary of SDF delay annotation. Without the `-from_in_ports` and `-to_out_ports` options arcs to and from top level ports are not reported. The `-report_annotated` and `-report_unannotated` options can be used to list arcs that are annotated or not annotated.} \ + -arg_help { + -cell {Report annotated cell delays.} + -net {Report annotated internal net delays.} + -from_in_ports {Report annotated delays from input ports.} + -to_out_ports {Report annotated delays to output ports.} + -max_lines {`lines`: Maximum number of lines listed by the `-report_annotated` and `-report_unannotated` options.} + -report_annotated {Report annotated timing arcs.} + -report_unannotated {Report unannotated timing arcs.} + -constant_arcs {Report separate annotation counts for arcs disabled by logic constants (`set_logic_one`, `set_logic_zero`).} + } proc_redirect report_annotated_delay { parse_key_args "report_annotated_delay" args keys {-scene -corner -max_lines} \ @@ -117,7 +147,20 @@ define_cmd_args "report_annotated_check" \ {[-setup] [-hold] [-recovery] [-removal] [-nochange]\ [-width] [-period] [-max_skew]\ [-scene scene] [-max_lines lines]\ - [-report_annotated] [-report_unannotated] [-constant_arcs]} + [-report_annotated] [-report_unannotated] [-constant_arcs]} \ + -help {The `report_annotated_check` command reports a summary of SDF timing check annotation. The `-report_annotated` and `-report_annotated` options can be used to list arcs that are annotated or not annotated.} \ + -arg_help { + -recovery {Report annotated recovery checks.} + -removal {Report annotated removal checks.} + -nochange {Report annotated nochange checks.} + -width {Report annotated width checks.} + -period {Report annotated period checks.} + -max_skew {Report annotated max skew checks.} + -max_lines {`lines`: Maximum number of lines listed by the `-report_annotated` and `-report_unannotated` options.} + -report_annotated {Report annotated timing arcs.} + -report_unannotated {Report unannotated timing arcs.} + -constant_arcs {Report separate annotation counts for arcs disabled by logic constants (`set_logic_one`, `set_logic_zero`).} + } proc_redirect report_annotated_check { parse_key_args "report_annotated_check" args keys {-scene -max_lines} \ @@ -176,7 +219,17 @@ proc_redirect report_annotated_check { define_cmd_args "write_sdf" \ {[-scene scene] [-divider /|.] [-include_typ]\ - [-digits digits] [-gzip] [-no_timestamp] [-no_version] filename} + [-digits digits] [-gzip] [-no_timestamp] [-no_version] filename} \ + -help {Write the delay calculation delays for the design in SDF format to `filename`. If `-scene` is not specified the min/max delays are across all scenes. With `-scene` the min/max delays for that scene are written. The SDF TIMESCALE is the same as the time_unit in the first Liberty file read.} \ + -arg_help { + -scene {Write delays for scene.} + -divider {Divider to use between hierarchy levels in pin and instance names.} + -include_typ {Include a 'typ' value in the SDF triple that is the average of min and max delays to satisfy some Verilog simulators that require three values in the delay triples.} + -gzip {Compress the SDF using gzip.} + -no_timestamp {Do not write a DATE statement.} + -no_version {Do not write a VERSION statement.} + filename {The SDF filename to write.} + } proc_redirect write_sdf { parse_key_args "write_sdf" args \ diff --git a/search/MakeTimingModel.cc b/search/MakeTimingModel.cc index 6ca5f935d..0ab2d9d8a 100644 --- a/search/MakeTimingModel.cc +++ b/search/MakeTimingModel.cc @@ -150,20 +150,25 @@ void MakeTimingModel::makeLibrary() { library_ = network_->makeLibertyLibrary(lib_name_, filename_); - LibertyLibrary *default_lib = network_->defaultLibertyLibrary(); - *library_->units() = *default_lib->units(); - - for (const RiseFall *rf : RiseFall::range()) { - library_->setInputThreshold(rf, default_lib->inputThreshold(rf)); - library_->setOutputThreshold(rf, default_lib->outputThreshold(rf)); - library_->setSlewLowerThreshold(rf, default_lib->slewLowerThreshold(rf)); - library_->setSlewUpperThreshold(rf, default_lib->slewUpperThreshold(rf)); - } + const LibertySeq &scene_libs = scene_->libertyLibraries(MinMax::max()); + if (!scene_libs.empty()) { + const LibertyLibrary *scene_lib = scene_libs[0]; + *library_->units() = *scene_lib->units(); + + for (const RiseFall *rf : RiseFall::range()) { + library_->setInputThreshold(rf, scene_lib->inputThreshold(rf)); + library_->setOutputThreshold(rf, scene_lib->outputThreshold(rf)); + library_->setSlewLowerThreshold(rf, scene_lib->slewLowerThreshold(rf)); + library_->setSlewUpperThreshold(rf, scene_lib->slewUpperThreshold(rf)); + } - library_->setDelayModelType(default_lib->delayModelType()); - library_->setNominalProcess(default_lib->nominalProcess()); - library_->setNominalVoltage(default_lib->nominalVoltage()); - library_->setNominalTemperature(default_lib->nominalTemperature()); + library_->setDelayModelType(scene_lib->delayModelType()); + library_->setNominalProcess(scene_lib->nominalProcess()); + library_->setNominalVoltage(scene_lib->nominalVoltage()); + library_->setNominalTemperature(scene_lib->nominalTemperature()); + } + else + report_->error(1381, "scene {} has no liberty libraries.", scene_->name()); } void @@ -342,8 +347,8 @@ MakeTimingModel::findTimingFromInput(Port *input_port) PinSet *from_pins = new PinSet(network_); from_pins->insert(input_pin); - ExceptionFrom *from = - sta_->makeExceptionFrom(from_pins, nullptr, nullptr, input_rf1, sdc_); + ExceptionFrom *from = sta_->makeExceptionFrom(from_pins, nullptr, + nullptr, input_rf1, sdc_); search_->findFilteredArrivals(from, nullptr, nullptr, false, false); end_visitor.setInputRf(input_rf); diff --git a/search/Search.i b/search/Search.i index 3aaeac2f7..a62ae2f70 100644 --- a/search/Search.i +++ b/search/Search.i @@ -494,7 +494,6 @@ void report_path_ends(PathEndSeq *ends) { Sta::sta()->reportPathEnds(ends); - delete ends; } //////////////////////////////////////////////////////////////// @@ -908,7 +907,6 @@ find_fanin_pins(PinSeq *to, PinSet fanin = sta->findFaninPins(to, flat, startpoints_only, inst_levels, pin_levels, thru_disabled, thru_constants, mode); - delete to; return fanin; } @@ -926,7 +924,6 @@ find_fanin_insts(PinSeq *to, InstanceSet fanin = sta->findFaninInstances(to, flat, startpoints_only, inst_levels, pin_levels, thru_disabled, thru_constants, mode); - delete to; return fanin; } @@ -944,7 +941,6 @@ find_fanout_pins(PinSeq *from, PinSet fanout = sta->findFanoutPins(from, flat, endpoints_only, inst_levels, pin_levels, thru_disabled, thru_constants, mode); - delete from; return fanout; } @@ -962,7 +958,6 @@ find_fanout_insts(PinSeq *from, InstanceSet fanout = sta->findFanoutInstances(from, flat, endpoints_only, inst_levels, pin_levels, thru_disabled, thru_constants, mode); - delete from; return fanout; } diff --git a/search/Search.tcl b/search/Search.tcl index a57b109b0..1a0cf9009 100644 --- a/search/Search.tcl +++ b/search/Search.tcl @@ -34,7 +34,19 @@ define_cmd_args "check_setup" \ { [-verbose] [-no_input_delay] [-no_output_delay]\ [-multiple_clock] [-no_clock]\ [-unconstrained_endpoints] [-loops] [-generated_clocks]\ - [> filename] [>> filename] } + [> filename] [>> filename] } \ + -help {The `check_setup` command performs sanity checks on the design. Individual checks can be performed with the keywords. If no check keywords are specified all checks are performed. Checks that fail are reported as warnings. If no checks fail nothing is reported. The command returns 1 if there are no warnings for use in scripts.} \ + -arg_help { + -verbose {Show offending objects rather than just error counts.} + -unconstrained_endpoints {Check path endpoints for timing constraints (timing check or `set_output_delay`).} + -multiple_clock {Check register/latch clock pins for multiple clocks.} + -no_clock {Check register/latch clock pins for a clock.} + -no_input_delay {Check for inputs that do not have a `set_input_delay` command.} + -no_output_delay {Check for outputs that do not have a `set_output_delay` command.} + -no_output_delay {Check for outputs that do not have a `set_output_delay` command.} + -loops {Check for combinational logic loops.} + -generated_clocks {Check that generated clock source pins have been defined as clocks.} + } proc_redirect check_setup { check_setup_cmd "check_setup" $args @@ -106,7 +118,30 @@ define_cmd_args "find_timing_paths" \ [-slack_max slack_max]\ [-slack_min slack_min]\ [-sort_by_slack]\ - [-path_group group_name]} + [-path_group group_name]} \ + -help {The `find_timing_paths` command returns a list of path objects for scripting. Use the `get_property` function to access properties of the paths.} \ + -arg_help { + -from {Return paths from a list of clocks, instances, ports, register clock pins, or latch data pins.} + -rise_from {Return paths from the rising edge of clocks, instances, ports, register clock pins, or latch data pins.} + -fall_from {Return paths from the falling edge of clocks, instances, ports, register clock pins, or latch data pins.} + -through {Return paths through a list of instances, pins or nets.} + -rise_through {Return rising paths through a list of instances, pins or nets.} + -fall_through {Return falling paths through a list of instances, pins or nets.} + -to {Return paths to a list of clocks, instances, ports or pins.} + -rise_to {Return rising paths to a list of clocks, instances, ports or pins.} + -fall_to {Return falling paths to a list of clocks, instances, ports or pins.} + -unconstrained {Report unconstrained paths also.} + -path_delay {`min`: Return min path (hold) checks. `min_rise`: Return min path (hold) checks for rising endpoints. `min_fall`: Return min path (hold) checks for falling endpoints. `max`: Return max path (setup) checks. `max_rise`: Return max path (setup) checks for rising endpoints. `max_fall`: Return max path (setup) checks for falling endpoints. `min_max`: Return min and max path (setup and hold) checks.} + -group_path_count {`path_count`: The number of paths to return in each path group.} + -endpoint_path_count {`endpoint_path_count`: The number of paths to return for each endpoint.} + -unique_paths_to_endpoint {Return multiple paths to an endpoint that traverse different pins without showing multiple paths with different rise/fall transitions.} + -unique_edges_to_endpoint {When multiple paths to an endpoint are requested, only the worst path through the same pins and rise/fall edges is returned.} + -scenes {`scenes`: Return paths for these scenes. The default is all scenes.} + -slack_max {`max_slack`: Return paths with slack less than max_slack.} + -slack_min {`min_slack`: Return paths with slack greater than min_slack.} + -sort_by_slack {Sort paths by slack rather than slack within path groups.} + -path_group {`groups`: Return paths in path groups. Paths in all groups are returned if this option is not specified.} + } proc find_timing_paths { args } { set path_ends [find_timing_paths_cmd "find_timing_paths" args] @@ -244,7 +279,13 @@ define_cmd_args "report_clock_skew" {[-setup|-hold]\ [-clocks clocks]\ [-scenes scenes]\ [-include_internal_latency] - [-digits digits]} + [-digits digits]} \ + -help {Report the maximum difference in clock arrival between every source and target register that has a path between the source and target registers.} \ + -arg_help { + -clocks {The clocks to report. The default is all clocks.} + -scenes {Report clocks for these scenes. The default is all scenes.} + -include_internal_latency {Include internal clock latency from liberty min/max_clock_tree_path timing groups.} + } proc_redirect report_clock_skew { global sta_report_default_digits @@ -288,7 +329,13 @@ proc_redirect report_clock_skew { define_cmd_args "report_clock_latency" {[-clocks clocks]\ [-scenes scene]\ [-include_internal_latency] - [-digits digits]} + [-digits digits]} \ + -help {Report the clock network latency.} \ + -arg_help { + -clocks {The clocks to report. The default is all clocks.} + -scenes {Report latency for these scenes. The default is all scenes.} + -include_internal_latency {Include internal clock latency from liberty min/max_clock_tree_path timing groups.} + } proc_redirect report_clock_latency { global sta_report_default_digits @@ -328,6 +375,7 @@ define_cmd_args "report_checks" \ [-group_path_count path_count] \ [-endpoint_path_count path_count]\ [-unique_paths_to_endpoint]\ + [-unique_edges_to_endpoint]\ [-slack_max slack_max]\ [-slack_min slack_min]\ [-sort_by_slack]\ @@ -336,7 +384,35 @@ define_cmd_args "report_checks" \ [-fields capacitance|slew|fanout|input_pin|net|src_attr|variation]\ [-digits digits]\ [-no_line_splits]\ - [> filename] [>> filename]} + [> filename] [>> filename]} \ + -help {The `report_checks` command reports paths in the design. Paths are reported in groups by capture clock, unclocked path delays, gated clocks and unconstrained. + +See `set_false_path` for a description of allowed from_list, through_list and to_list objects.} \ + -arg_help { + -from {Report paths from a list of clocks, instances, ports, register clock pins, or latch data pins.} + -rise_from {Report paths from the rising edge of clocks, instances, ports, register clock pins, or latch data pins.} + -fall_from {Report paths from the falling edge of clocks, instances, ports, register clock pins, or latch data pins.} + -through {Report paths through a list of instances, pins or nets.} + -rise_through {Report rising paths through a list of instances, pins or nets.} + -fall_through {Report falling paths through a list of instances, pins or nets.} + -to {Report paths to a list of clocks, instances, ports or pins.} + -rise_to {Report rising paths to a list of clocks, instances, ports or pins.} + -fall_to {Report falling paths to a list of clocks, instances, ports or pins.} + -unconstrained {Report unconstrained paths also. The unconstrained path group is not reported without this option.} + -path_delay {`min`: Report min path (hold) checks. `min_rise`: Report min path (hold) checks for rising endpoints. `min_fall`: Report min path (hold) checks for falling endpoints. `max`: Report max path (setup) checks. `max_rise`: Report max path (setup) checks for rising endpoints. `max_fall`: Report max path (setup) checks for falling endpoints. `min_max`: Report min and max path (setup and hold) checks.} + -group_path_count {`path_count`: The number of paths to report in each path group. The default is 1.} + -endpoint_path_count {`endpoint_path_count`: The number of paths to report for each endpoint. The default is 1.} + -unique_paths_to_endpoint {When multiple paths to an endpoint are specified with `-endpoint_path_count`, many of the paths may differ only in the rise/fall edges of the pins in the paths. With this option only the worst path through the set of pins is reported.} + -unique_edges_to_endpoint {When multiple paths to an endpoint are specified with `-endpoint_path_count`, conditional timing arcs result in paths that go through the same pins and rise/fall edges. With this option only the worst path through the set of pins and rise/fall edges is reported.} + -scenes {Report paths for these scenes. The default is all scenes.} + -slack_max {Only report paths with less slack than max_slack.} + -slack_min {Only report paths with more slack than min_slack.} + -sort_by_slack {Sort paths by slack rather than slack grouped by path group.} + -path_group {List of path groups to report. The default is to report all path groups.} + -format {`end`: Report path ends in one line with delay, required time and slack. `full`: Report path start and end points and the path. This is the default path type. `full_clock`: Report path start and end points, the path, and the source and target clock paths. `full_clock_expanded`: Report path start and end points, the path, and the source and target clock paths. If the clock is generated and propagated, the path from the clock source pin is also reported. `short`: Report only path start and end points. `summary`: Report only path ends with delay. `json`: Report in json format. `-fields` is ignored.} + -fields {List of capacitance|slew|input_pins|hierarchical_pins|net|fanout|src_attr|variation} + -no_line_splits {Do not split long lines into multiple lines.} + } proc_redirect report_checks { global sta_report_unconstrained_paths @@ -360,7 +436,33 @@ define_cmd_args "report_check_types" \ [-net net]\ [-max_count max_count]\ [-digits digits] [-no_line_splits]\ - [> filename] [>> filename]} + [> filename] [>> filename]} \ + -help {The `report_check_types` command reports the slack for each type of timing and design rule constraint. The keyword options allow a subset of the constraint types to be reported.} \ + -arg_help { + -scenes {Report checks for some scenes. The default value is all scenes.} + -violators {Report all violated timing and design rule constraints.} + -verbose {Use a verbose output format.} + -format {`slack_only`: Report the minimum slack for each timing check. `end`: Report the endpoint for each check.} + -fields {List of capacitance|slew|input_pins|hierarchical_pins|net|fanout|src_attr|variation} + -max_delay {Report setup and max delay path delay constraints.} + -min_delay {Report hold and min delay path delay constraints.} + -recovery {Report asynchronous recovery checks.} + -removal {Report asynchronous removal checks.} + -clock_gating_setup {Report gated clock enable setup checks.} + -clock_gating_hold {Report gated clock hold setup checks.} + -max_slew {Report max transition design rule checks.} + -max_skew {Report max skew design rule checks.} + -min_pulse_width {Report min pulse width design rule checks.} + -min_period {Report min period design rule checks.} + -min_slew {Report min slew design rule checks.} + -max_fanout {Report max fanout design rule checks.} + -min_fanout {Report min fanout design rule checks.} + -max_capacitance {Report max capacitance design rule checks.} + -min_capacitance {Report min capacitance design rule checks.} + -net {Report checks on this net.} + -max_count {Maximum number of checks to report.} + -no_line_splits {Do not split long lines into multiple lines.} + } proc_redirect report_check_types { variable float_inf @@ -533,11 +635,18 @@ proc_redirect report_check_types { ################################################################ -define_cmd_args "report_disabled_edges" {} +define_cmd_args "report_disabled_edges" {} \ + -help {The `report_disabled_edges` command reports disabled timing arcs along with the reason they are disabled. Each disabled timing arc is reported as the instance name along with the from and to ports of the arc. The disable reason is shown next. Arcs that are disabled with `set_disable_timing` are reported with constraint as the reason. Arcs that are disabled by constants are reported with constant as the reason along with the constant instance pin and value. Arcs that are disabled to break combinational feedback loops are reported with loop as the reason. + +``` +> report_disabled_edges +u1 A B constant B=0 +```} ################################################################ -define_cmd_args "report_tns" {[-min] [-max] [-digits digits]} +define_cmd_args "report_tns" {[-min] [-max] [-digits digits]} \ + -help {Report the total negative slack.} proc_redirect report_tns { global sta_report_default_digits @@ -562,7 +671,8 @@ proc_redirect report_tns { ################################################################ -define_cmd_args "report_wns" {[-min] [-max] [-digits digits]} +define_cmd_args "report_wns" {[-min] [-max] [-digits digits]} \ + -help {Report the worst negative slack. If the worst slack is positive, zero is reported.} proc_redirect report_wns { global sta_report_default_digits @@ -591,7 +701,8 @@ proc_redirect report_wns { ################################################# ############### -define_cmd_args "report_worst_slack" {[-min] [-max] [-digits digits]} +define_cmd_args "report_worst_slack" {[-min] [-max] [-digits digits]} \ + -help {Report the worst slack in the design.} proc_redirect report_worst_slack { global sta_report_default_digits @@ -738,7 +849,11 @@ proc parse_report_path_options { cmd args_var default_format ################################################################ -define_cmd_args "report_arrival" {[-scene scene] [-report_variance] [-digits digits] pin} +define_cmd_args "report_arrival" {[-scene scene] [-report_variance] [-digits digits] pin} \ + -help {The `report_arrival` command reports min/max rise/fall arrival times at a pin with respect to each clock that has a path to the pin.} \ + -arg_help { + pin {A pin or port.} + } proc report_arrival { args } { global sta_report_default_digits @@ -760,7 +875,11 @@ proc report_arrival { args } { ################################################################ -define_cmd_args "report_required" {[-scene scene] [-report_variance] [-digits digits] pin} +define_cmd_args "report_required" {[-scene scene] [-report_variance] [-digits digits] pin} \ + -help {The `report_required` command reports min/max rise/fall required times at a pin with respect to each clock.} \ + -arg_help { + pin {A pin or port.} + } proc report_required { args } { global sta_report_default_digits @@ -782,7 +901,11 @@ proc report_required { args } { ################################################################ -define_cmd_args "report_slack" {[-scene scene] [-report_variance] [-digits digits] pin} +define_cmd_args "report_slack" {[-scene scene] [-report_variance] [-digits digits] pin} \ + -help {The `report_slack` command reports min/max rise/fall slack at a pin with respect to each clock.} \ + -arg_help { + pin {A pin or port.} + } proc report_slack { args } { global sta_report_default_digits @@ -906,7 +1029,37 @@ proc worst_clock_skew { args } { define_cmd_args "write_timing_model" {[-scene scene] \ [-library_name lib_name]\ [-cell_name cell_name]\ - filename} + filename} \ + -help {The `write_timing_model` command constructs a liberty timing model for the current design and writes it to filename. cell_name defaults to the cell name of the top level block in the design. + +The SDC used to extract the block should include the clock definitions. If the block contains a clock network `set_propagated_clock` should be used so the clock delays are included in the timing model. The following SDC commands are ignored when building the timing model. + +``` +set_input_delay +set_output_delay +set_load +set_timing_derate +``` + +Using `set_input_transition` with the slew from the block context will be used will improve the match between the timing model and the block netlist. Paths defined on clocks that are defined on internal pins are ignored because the model has no way to include the clock definition. + +The resulting timing model can be used in a hierarchical timing flow as a replacement for the block to speed up timing analysis. This hierarchical timing methodology does not handle timing exceptions that originate or terminate inside the block. The timing model includes: + +``` +combinational paths between inputs and outputs +setup and hold timing constraints on inputs +clock to output timing paths +``` + +Resistance of long wires on inputs and outputs of the block cannot be modeled in Liberty. To reduce inaccuracies from wire resistance in technologies with resistive wires place buffers on inputs and ouputs. + +The extracted timing model setup/hold checks are scalar (no input slew dependence). Delay timing arcs are load dependent but do not include input slew dependency.} \ + -arg_help { + -library_name {The name to use for the liberty library. Defaults to cell_name.} + -cell_name {The name to use for the liberty cell. Defaults to the top level module name.} + -scene {The scene to use for extracting the model.} + filename {Filename for the liberty timing model.} + } proc write_timing_model { args } { parse_key_args "write_timing_model" args \ @@ -950,7 +1103,12 @@ proc parse_path_group_arg { group_names } { ################################################################ define_cmd_args "report_clock_min_period" \ - { [-clocks clocks] [-include_port_paths] } + { [-clocks clocks] [-include_port_paths] } \ + -help {Report the minimum period and maximum frequency for clocks. If the `-clocks` argument is not specified all clocks are reported. The minimum period is determined by examining the smallest slack paths between registers on the rising edges of the clock or between falling edges of the clock. Paths between different clocks, different clock edges of the same clock, level-sensitive latches, or paths constrained by `set_multicycle_path` or `set_max_delay` are not considered.} \ + -arg_help { + -clocks {The clocks to report.} + -include_port_paths {Include paths from input port and to output ports.} + } proc_redirect report_clock_min_period { parse_key_args "report_min_clock_period" args \ @@ -978,7 +1136,11 @@ proc_redirect report_clock_min_period { ################################################################ -define_cmd_args "set_disable_inferred_clock_gating" { objects } +define_cmd_args "set_disable_inferred_clock_gating" { objects } \ + -help {The `set_disable_inferred_clock_gating` command disables clock gating checks on a clock gating instance, clock gating pin, or clock gating enable pin.} \ + -arg_help { + objects {A list of clock gating instances, clock gating pins, or clock enable pins.} + } proc set_disable_inferred_clock_gating { objects } { set_disable_inferred_clock_gating_cmd $objects @@ -996,7 +1158,11 @@ proc set_disable_inferred_clock_gating_cmd { objects } { ################################################################ -define_cmd_args "unset_disable_inferred_clock_gating" { objects } +define_cmd_args "unset_disable_inferred_clock_gating" { objects } \ + -help {The `unset_disable_inferred_clock_gating` command removes a previous `set_disable_inferred_clock_gating` command.} \ + -arg_help { + objects {A list of clock gating instances, clock gating pins, or clock enable pins.} + } proc unset_disable_inferred_clock_gating { objects } { unset_disable_inferred_clock_gating_cmd $objects diff --git a/search/Sta.cc b/search/Sta.cc index ec8d7a8c1..7beb81a2a 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -2733,8 +2733,11 @@ Sta::updateSceneLiberty(Scene *scene, LibertyLibrary *lib = network_->findLiberty(lib_file); if (lib == nullptr) lib = network_->findLibertyFilename(lib_file); - if (lib) + if (lib) { LibertyLibrary::makeSceneMap(lib, scene, min_max, network_, report_); + for (const MinMax *min_max : min_max->range()) + scene->addLiberty(lib, min_max); + } else report_->warn(1555, "liberty name/filename {} not found.", lib_file); } diff --git a/spice/WriteSpice.cc b/spice/WriteSpice.cc index e04d89670..61b6dc329 100644 --- a/spice/WriteSpice.cc +++ b/spice/WriteSpice.cc @@ -106,7 +106,8 @@ WriteSpice::writeHeader(std::string &title, float time_step) { sta::print(spice_stream_, "* {}\n", title); - sta::print(spice_stream_, ".include \"{}\"\n", model_filename_); + if (!model_filename_.empty()) + sta::print(spice_stream_, ".include \"{}\"\n", model_filename_); std::filesystem::path subckt_filename = std::filesystem::path(subckt_filename_).filename(); sta::print(spice_stream_, ".include \"{}\"\n", subckt_filename.string()); diff --git a/spice/WriteSpice.tcl b/spice/WriteSpice.tcl index a44526624..1b5481392 100644 --- a/spice/WriteSpice.tcl +++ b/spice/WriteSpice.tcl @@ -30,7 +30,33 @@ define_cmd_args "write_path_spice" { -path_args path_args\ -model_file model_file\ -power power\ -ground ground\ - [-simulator hspice|ngspice|xyce]} + [-simulator hspice|ngspice|xyce]} \ + -help {The `write_path_spice` command writes a spice netlist for timing paths. Use path_args to specify `-from`/`-through`/`-to` as arguments to the `find_timing_paths` command. For each path, a spice netlist and the subckts referenced by the path are written in spice_directory. The spice netlist is written in path_.sp and subckt file is path_.subckt. + +The spice netlists used by the path are written to subckt_file, which spice_file .includes. The device models used by the spice subckt netlists in model_file are also .included in spice_file. Power and ground names are specified with the `-power` and `-ground` arguments. The spice netlist includes a piecewise linear voltage source at the input and .measure statement for each gate delay and pin slew. + +Example command: + +``` +write_path_spice -path_args {-from "in0" -to "out1" -unconstrained} \ + -spice_directory $result_dir \ + -lib_subckt_file "write_spice1.subckt" \ + -model_file "write_spice1.models" \ + -power VDD -ground VSS +``` + +When the simulator is hspice, .measure statements will be added to the spice netlist. + +When the simulator is Xyce, the .print statement selects the CSV format and writes the waveform data to a file name path_.csv so the results can be used by gnuplot.} \ + -arg_help { + -path_args {`-from`|`-through`|`-to` arguments as in `report_checks`.} + -spice_file {Directory and path prefix for spice output files.} + -lib_subckt_file {Cell transistor level subckts.} + -model_file {Transistor model definitions .included by spice_file.} + -power {Voltage supply name in voltage_map of the default liberty library.} + -ground {Ground supply name in voltage_map of the default liberty library.} + -simulator {Simulator that will read the spice netlist.} + } proc write_path_spice { args } { parse_key_args "write_path_spice" args \ @@ -69,7 +95,8 @@ proc write_path_spice { args } { sta_error 1926 "-model_file $model_file is not readable." } } else { - sta_error 1927 "No -model_file specified." + sta_warn 1927 "No -model_file specified." + set model_file "" } if { [info exists keys(-power)] } { diff --git a/tcl/CmdUtil.tcl b/tcl/CmdUtil.tcl index 80d9b3e07..952803096 100644 --- a/tcl/CmdUtil.tcl +++ b/tcl/CmdUtil.tcl @@ -30,11 +30,18 @@ namespace eval sta { # ################################################################ -define_cmd_args "help" {[pattern]} +define_cmd_args "help" {[-verbose] [pattern]} \ + -help {Print command usage. With a single match, print the description and options. Use `-verbose` to print full `help` for every match.} \ + -arg_help { + -verbose {Print full descriptions even when multiple commands match.} + } proc_redirect help { variable cmd_args + variable var_help + parse_key_args "help" args keys {} flags {-verbose} + set verbose [info exists flags(-verbose)] set arg_count [llength $args] if { $arg_count == 0 } { set pattern "*" @@ -43,13 +50,28 @@ proc_redirect help { } else { cmd_usage_error "help" } - set matches [array names cmd_args $pattern] - if { $matches != {} } { - foreach cmd [lsort $matches] { + + set cmd_matches [lsort [array names cmd_args $pattern]] + set var_matches {} + if { $pattern != "*" } { + set var_matches [lsort [array names var_help $pattern]] + } + set match_count [expr { [llength $cmd_matches] + [llength $var_matches] }] + if { $match_count == 0 } { + sta_warn 160 "no commands match '$pattern'." + return + } + + set full [expr { $verbose || $match_count == 1 }] + foreach cmd $cmd_matches { + if { $full } { + show_cmd_help $cmd + } else { show_cmd_args $cmd } - } else { - sta_warn 160 "no commands match '$pattern'." + } + foreach var $var_matches { + show_var_help $var $full } } @@ -83,6 +105,104 @@ proc show_cmd_args { cmd } { } } +proc show_cmd_help { cmd } { + variable cmd_args + + show_cmd_args $cmd + set desc [md_help_to_text [cmd_help_text $cmd]] + if { $desc != "" } { + report_wrapped $desc 80 2 + } + foreach opt [cmd_synopsis_options $cmd_args($cmd)] { + set opt_desc [md_help_to_text [cmd_arg_help_text $cmd $opt]] + if { $opt_desc != "" } { + report_opt_help $opt $opt_desc + } + } +} + +proc show_var_help { var full } { + set values [var_help_values $var] + if { $values != "" } { + report_line "$var $values" + } else { + report_line $var + } + if { $full } { + set desc [md_help_to_text [var_help_text $var]] + if { $desc != "" } { + report_wrapped $desc 80 2 + } + } +} + +proc report_opt_help { opt desc } { + set indent 2 + set hang 4 + set width 80 + set prefix "[string repeat " " $indent]$opt " + set col [string length $prefix] + set line $prefix + foreach word [split $desc] { + if { $word == "" } { + continue + } + set word_len [string length $word] + if { $col + $word_len + 1 > $width && $col > $hang } { + report_line [string trimright $line] + set line "[string repeat " " $hang]$word " + set col [expr { $hang + $word_len + 1 }] + } else { + append line "$word " + set col [expr { $col + $word_len + 1 }] + } + } + report_line [string trimright $line] +} + +proc report_wrapped { text width indent } { + set prefix [string repeat " " $indent] + foreach para [split $text "\n"] { + if { [string trim $para] == "" } { + report_line "" + continue + } + set line $prefix + set col $indent + foreach word [split $para] { + if { $word == "" } { + continue + } + set word_len [string length $word] + if { $col + $word_len + 1 > $width && $col > $indent } { + report_line [string trimright $line] + set line "$prefix$word " + set col [expr { $indent + $word_len + 1 }] + } else { + append line "$word " + set col [expr { $col + $word_len + 1 }] + } + } + report_line [string trimright $line] + } +} + +# Approximate Markdown as wrap-friendly plain text for the help command. +proc md_help_to_text { md } { + if { $md == "" } { + return "" + } + set text $md + # Fenced code blocks become indented lines. + set text [regsub -all {```[a-zA-Z0-9_]*\n} $text ""] + set text [string map {``` ""} $text] + # Inline code, bold, italics. + set text [regsub -all {`([^`]+)`} $text {\1}] + set text [regsub -all {\*\*([^*]+)\*\*} $text {\1}] + set text [regsub -all {\*([^*]+)\*} $text {\1}] + return [string trim $text] +} + # This is used in lieu of command completion to make sdc commands # like get_ports be abbreviated get_port. proc define_cmd_alias { alias cmd } { @@ -102,7 +222,12 @@ proc cmd_usage_error { cmd } { ################################################################ -define_cmd_args "with_output_to_variable" { var { cmds }} +define_cmd_args "with_output_to_variable" { var { cmds }} \ + -help {The `with_output_to_variable` command redirects the output of Tcl commands to a variable.} \ + -arg_help { + var {The name of a variable to save the output of commands to.} + commands {Tcl commands that the output will be redirected from.} + } # with_output_to_variable variable { command args... } proc with_output_to_variable { var_name args } { @@ -117,7 +242,19 @@ proc with_output_to_variable { var_name args } { ################################################################ -define_cmd_args "report_units" {} +define_cmd_args "report_units" {} \ + -help {Report the units used for command arguments and reporting. + +``` +report_units + time 1ns + capacitance 1pF + resistance 1kohm + voltage 1v + current 1A + power 1pW + distance 1um +```} proc report_units { args } { check_argc_eq0 "report_units" $args @@ -142,7 +279,36 @@ proc write_units_json { jsonfile } { define_cmd_args "set_cmd_units" \ {[-capacitance cap_unit] [-resistance res_unit] [-time time_unit]\ [-voltage voltage_unit] [-current current_unit] [-power power_unit]\ - [-distance distance_unit]} + [-distance distance_unit]} \ + -help {The `set_cmd_units` command is used to change the units used by the STA command interpreter when parsing commands and reporting results. The default units are the units specified in the first Liberty library file that is read. + +Units are specified as a scale factor followed by a unit name. The scale factors are as follows. + +``` +M 1E+6 +k 1E+3 +m 1E-3 +u 1E-6 +n 1E-9 +p 1E-12 +f 1E-15 +``` + +An example of the `set_units` command is shown below. + +``` +set_cmd_units -time ns -capacitance pF -current mA -voltage V + -resistance kOhm -distance um +```} \ + -arg_help { + -capacitance {`cap_unit`: The capacitance scale factor followed by 'f'.} + -resistance {`res_unit`: The resistance scale factor followed by 'ohm'.} + -time {`time_unit`: The time scale factor followed by 's'.} + -voltage {`voltage_unit`: The voltage scale factor followed by 'v'.} + -current {`current_unit`: The current scale factor followed by 'A'.} + -power {`power_unit`: The power scale factor followed by 'w'.} + -distance {`distance_unit`: The distance scale factor followed by 'm'.} + } proc set_cmd_units { args } { parse_key_args "set_cmd_units" args \ @@ -191,7 +357,12 @@ proc set_unit_values { unit key suffix key_var } { ################################################################ -define_cmd_args "delete_from_list" {list delete} +define_cmd_args "delete_from_list" {list delete} \ + -help {Remove objects from a list.} \ + -arg_help { + list {A list of objects.} + objects {A list of objects to delete from list.} + } proc delete_from_list { list delete } { delete_objects_from_list_cmd $list $delete @@ -250,7 +421,11 @@ proc set_cmd_namespace { namespc } { ################################################################ -define_cmd_args "report_object_full_names" {objects} +define_cmd_args "report_object_full_names" {objects} \ + -help {The `report_object_full_names` command prints the hierarchical name of each object, sorted by full name.} \ + -arg_help { + objects {A list of objects returned by a `get_*` command.} + } proc report_object_full_names { objects } { foreach obj [sort_by_full_name $objects] { @@ -258,7 +433,11 @@ proc report_object_full_names { objects } { } } -define_cmd_args "report_object_names" {objects} +define_cmd_args "report_object_names" {objects} \ + -help {The `report_object_names` command prints the name of each object, sorted by name.} \ + -arg_help { + objects {A list of objects returned by a `get_*` command.} + } proc report_object_names { objects } { foreach obj [sort_by_name $objects] { @@ -268,8 +447,16 @@ proc report_object_names { objects } { ################################################################ -define_cmd_args "get_name" {object} -define_cmd_args "get_full_name" {object} +define_cmd_args "get_name" {object} \ + -help {Return the name of object. Equivalent to [`get_property` object name].} \ + -arg_help { + object {A library, cell, port, instance, pin or timing arc object.} + } +define_cmd_args "get_full_name" {object} \ + -help {Return the name of object. Equivalent to [`get_property` object full_name].} \ + -arg_help { + object {A library, cell, port, instance, pin or timing arc object.} + } ################################################################ diff --git a/tcl/Exception.i b/tcl/Exception.i index 372d843e9..68c405ce5 100644 --- a/tcl/Exception.i +++ b/tcl/Exception.i @@ -22,6 +22,7 @@ // // This notice may not be removed or altered from any source distribution. +// Use SWIG_fail (not return) so %typemap(freearg) still runs after an exception. %exception { try { $action } catch (std::bad_alloc &) { @@ -33,11 +34,11 @@ Tcl_ResetResult(interp); Tcl_AppendResult(interp, "Error: ", excp.what(), nullptr); } - return TCL_ERROR; + SWIG_fail; } catch (std::exception &excp) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "Error: ", excp.what(), nullptr); - return TCL_ERROR; + SWIG_fail; } } diff --git a/tcl/Property.tcl b/tcl/Property.tcl index b0d30bd18..1c14df273 100644 --- a/tcl/Property.tcl +++ b/tcl/Property.tcl @@ -25,7 +25,33 @@ namespace eval sta { define_cmd_args "get_property" \ - {[-object_type library|liberty_library|cell|liberty_cell|instance|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} \ + -help {The `get_property` command returns a property of an object. Properties for each object type are shown below. + +| Object type | Properties | +| --- | --- | +| cell (SDC lib_cell) | `base_name`, `filename`, `full_name`, `library`, `name` | +| clock | `full_name`, `is_generated`, `is_propagated`, `is_virtual`, `name`, `period`, `sources` | +| edge | `delay_max_fall`, `delay_min_fall`, `delay_max_rise`, `delay_min_rise`, `full_name`, `from_pin`, `sense`, `to_pin` | +| instance (SDC cell) | `cell`, `full_name`, `is_buffer`, `is_clock_gate`, `is_hierarchical`, `is_inverter`, `is_macro`, `is_memory`, `liberty_cell`, `name`, `ref_name` | +| liberty_cell (SDC lib_cell) | `area`, `base_name`, `dont_use`, `filename`, `full_name`, `is_buffer`, `is_inverter`, `is_memory`, `library`, `name` | +| liberty_port (SDC lib_pin) | `capacitance`, `direction`, `drive_resistance`, `drive_resistance_max_fall`, `drive_resistance_max_rise`, `drive_resistance_min_fall`, `drive_resistance_min_rise`, `full_name`, `intrinsic_delay`, `intrinsic_delay_max_fall`, `intrinsic_delay_max_rise`, `intrinsic_delay_min_fall`, `intrinsic_delay_min_rise`, `is_register_clock`, `lib_cell`, `name` | +| library | `filename` (Liberty library only), `name`, `full_name` | +| mode | `name`, `full_name` | +| net | `full_name`, `name` | +| path (PathEnd) | `endpoint`, `endpoint_clock`, `endpoint_clock_pin`, `slack`, `startpoint`, `startpoint_clock`, `points` | +| pin | `activity`, `slew_max_fall`, `slew_max_rise`, `slew_min_fall`, `slew_min_rise`, `clocks`, `clock_domains`, `direction`, `full_name`, `is_hierarchical`, `is_port`, `is_register_clock`, `lib_pin_name`, `name`, `slack_max`, `slack_max_fall`, `slack_max_rise`, `slack_min`, `slack_min_fall`, `slack_min_rise` | +| point (PathRef) | `arrival`, `pin`, `required`, `slack` | +| port | `activity`, `slew_max_fall`, `slew_max_rise`, `slew_min_fall`, `slew_min_rise`, `direction`, `full_name`, `liberty_port`, `name`, `slack_max`, `slack_max_fall`, `slack_max_rise`, `slack_min`, `slack_min_fall`, `slack_min_rise` | +| scene | `name`, `full_name` | + +The pin `activity` property is a list of activity (transitions per second), duty cycle, and origin. Origin is one of `global` (`set_power_activity -global`), `input` (`set_power_activity -input`), `user` (`set_power_activity -input_ports`/`-pins`), `vcd` (`read_vcd`), `saif` (`read_saif`), `propagated`, `clock` (`create_clock`/`create_generated_clock`), or `constant` (Verilog tie high/low, `set_case_analysis`, `set_logic_one`/`zero`/`dc`).} \ + -arg_help { + -object_type {`object_type`: The type of object when it is specified as a name. +cell|pin|net|port|clock|library|library_cell|library_pin|timing_arc} + object {An object returned by a `get_*` command, or an object name. `-object_type` is required if object is a name.} + property {A property name.} + } proc get_property { args } { parse_key_args "get_property" args keys {-object_type} flags {-quiet} @@ -121,7 +147,13 @@ proc get_property_object_type { object_type object_name quiet } { } define_cmd_args "define_property" \ - {-object_type scene|mode|library|liberty_library|cell|liberty_cell|port|liberty_port|instance|pin|net|clock -type bool|float|string property} + {-object_type scene|mode|library|liberty_library|cell|liberty_cell|port|liberty_port|instance|pin|net|clock -type bool|float|string property} \ + -help {The `define_property` command defines a user property that can be set with `set_property` and read with `get_property`. User properties can also be used in `-filter` expressions.} \ + -arg_help { + -object_type {Object type the property applies to.} + -type {`bool`: Boolean value. `float`: Floating point value. `string`: String value.} + property {The property name.} + } proc define_property { args } { parse_key_args "define_property" args keys {-object_type -type} flags {} @@ -135,7 +167,13 @@ proc define_property { args } { define_property_cmd $keys(-object_type) [lindex $args 0] $keys(-type) } -define_cmd_args "set_property" {object property value} +define_cmd_args "set_property" {object property value} \ + -help {The `set_property` command sets a user property defined with `define_property` on an object. Use `get_property` to read the value.} \ + -arg_help { + object {An object returned by a `get_*` command.} + property {A property name defined with `define_property`.} + value {The property value.} + } proc set_property { args } { check_argc_eq3 "set_property" $args diff --git a/tcl/Sta.tcl b/tcl/Sta.tcl index cffd66737..66ab29710 100644 --- a/tcl/Sta.tcl +++ b/tcl/Sta.tcl @@ -30,10 +30,24 @@ namespace eval sta { # ################################################################ -define_cmd_args "define_scene" {name -mode mode_name\ - -liberty liberty_files \ - | -liberty_min liberty_min_files -liberty_max liberty_max_files\ - [-spef spef_file | -spef_min spef_min_file -spef_max spef_max_file]} +define_cmd_args "define_scene" {name [-mode mode_name]\ + [-liberty liberty_files | -liberty_min liberty_min_files -liberty_max liberty_max_files]\ + [-spef spef_file | -spef_min spef_min_file -spef_max spef_max_file]} \ + -help {The `define_scene` command defines a scene for a mode (SDC), liberty files and spef parasitics. Define scenes after reading Liberty libraries and SPEF parasitics. + +Liberty files are specified with the name of the Liberty library or the filename of the Liberty file. If a filename is used, it must be the same as the filename used to read the library with `read_liberty`. + +Use `get_scenes` to find defined scenes.} \ + -arg_help { + name {The name of the scene.} + -mode {The SDC mode to use. Defaults to the current mode.} + -liberty {Liberty library name or filename used with `read_liberty`.} + -liberty_min {Min-delay Liberty library name or filename.} + -liberty_max {Max-delay Liberty library name or filename.} + -spef {SPEF parasitics name from `read_spef -name`.} + -spef_min {Min-delay SPEF parasitics name.} + -spef_max {Max-delay SPEF parasitics name.} + } proc define_scene { args } { parse_key_args "define_scene" args \ @@ -84,7 +98,11 @@ proc define_scene { args } { } # deprecated 11/22/2025 -define_cmd_args "define_corners" { corner1 [corner2]... } +define_cmd_args "define_corners" { corner1 [corner2]... } \ + -help {The `define_corners` command is deprecated. Use `define_scene` instead. It is supported for compatibility with older scripts that define analysis corners before `read_liberty`, but should not be used with MCMM flows.} \ + -arg_help { + corner1 {Corner/scene name. Additional names may follow.} + } proc define_corners { args } { if { [get_libs -quiet *] != {} } { @@ -98,7 +116,11 @@ proc define_corners { args } { ################################################################ -define_cmd_args "set_scene" {scene_name} +define_cmd_args "set_scene" {scene_name} \ + -help {The `set_scene` command sets the scene used by subsequent commands. Use `get_scenes` to find defined scenes.} \ + -arg_help { + scene_name {The name of a scene defined with `define_scene`.} + } proc set_scene { args } { check_argc_eq1 "set_scene" $args @@ -112,7 +134,13 @@ proc set_scene { args } { ################################################################ -define_cmd_args "get_scenes" {[-modes mode_names] [-filter expr] scene_names} +define_cmd_args "get_scenes" {[-modes mode_names] [-filter expr] scene_names} \ + -help {The `get_scenes` command is used to find the scenes matching a pattern or that use an SDC mode.} \ + -arg_help { + -modes {Return scenes that use these SDC modes.} + -filter {A filter expression. See the section "Filter Expressions".} + scene_name {A scene name pattern.} + } proc get_scenes { args } { parse_key_args "get_scenes" args keys {-modes -filter} flags {} @@ -144,7 +172,12 @@ proc get_scenes { args } { ################################################################ -define_cmd_args "get_modes" {[-filter expr] [mode_name]} +define_cmd_args "get_modes" {[-filter expr] [mode_name]} \ + -help {The `get_modes` command finds SDC modes matching a pattern.} \ + -arg_help { + -filter {A filter expression. See the section "Filter Expressions".} + mode_name {A mode name pattern.} + } proc get_modes { args } { parse_key_args "get_modes" args keys {-filter} flags {} @@ -164,7 +197,8 @@ proc get_modes { args } { ################################################################ -define_cmd_args "set_mode" {mode_name} +define_cmd_args "set_mode" {mode_name} \ + -help {Set the mode for SDC commands in the Tcl interpreter. If mode `mode_name` does not exist, it is created. When modes are created the default mode is deleted.} proc set_mode { args } { check_argc_eq1 "set_mode" $args @@ -176,7 +210,17 @@ proc set_mode { args } { define_cmd_args "get_fanin" \ {-to sink_list [-flat] [-only_cells] [-startpoints_only]\ [-levels level_count] [-pin_levels pin_count]\ - [-trace_arcs timing|enabled|all]} + [-trace_arcs timing|enabled|all]} \ + -help {The `get_fanin` command returns traverses the design from sink_list pins, ports or nets backwards and return the fanin pins or instances.} \ + -arg_help { + -to {`sink_list`: List of pins, ports, or nets to find the fanin of. For nets, the fanin of driver pins on the nets are returned.} + -flat {With `-flat` pins in the fanin at any hierarchy level are returned. Without `-flat` only pins at the same hierarchy level as the sinks are returned.} + -only_cells {Return the instances connected to the pins in the fanin.} + -startpoints_only {Only return pins that are startpoints.} + -levels {`level_count`: Only return pins within level_count instance traversals.} + -pin_levels {`pin_count`: Only return pins within pin_count pin traversals.} + -trace_arcs {`timing`: Only trace through timing arcs that are not disabled. `enabled`: Only trace through timing arcs that are not disabled. `all`: Trace through all arcs, including disabled ones.} + } proc get_fanin { args } { parse_key_args "get_fanin" args \ @@ -240,7 +284,17 @@ proc get_fanin { args } { define_cmd_args "get_fanout" \ {-from source_list [-flat] [-only_cells] [-endpoints_only]\ [-levels level_count] [-pin_levels pin_count]\ - [-trace_arcs timing|enabled|all]} + [-trace_arcs timing|enabled|all]} \ + -help {The `get_fanout` command returns traverses the design from source_list pins, ports or nets backwards and return the fanout pins or instances.} \ + -arg_help { + -from {`source_list`: List of pins, ports, or nets to find the fanout of. For nets, the fanout of load pins on the nets are returned.} + -flat {With `-flat` pins in the fanin at any hierarchy level are returned. Without `-flat` only pins at the same hierarchy level as the sinks are returned.} + -only_cells {Return the instances connected to the pins in the fanout.} + -endpoints_only {Only return pins that are endpoints.} + -levels {`level_count`: Only return pins within level_count instance traversals.} + -pin_levels {`pin_count`: Only return pins within pin_count pin traversals.} + -trace_arcs {`timing`: Only trace through timing arcs that are not disabled. `enabled`: Only trace through timing arcs that are not disabled. `all`: Trace through all arcs, including disabled ones.} + } proc get_fanout { args } { parse_key_args "get_fanout" args \ @@ -296,7 +350,16 @@ proc get_fanout { args } { ################################################################ define_cmd_args "get_timing_edges" \ - {[-from from_pin] [-to to_pin] [-of_objects objects] [-filter expr]} + {[-from from_pin] [-to to_pin] [-of_objects objects] [-filter expr]} \ + -help {The `get_timing_edges` command returns a list of timing edges (arcs) to, from or between pins. The result can be passed to `get_property` or `set_disable_timing`.} \ + -arg_help { + -from {`from_pin`: A list of pins.} + -to {`to_pin`: A list of pins.} + -of_objects {A list of instances or library cells. The `-from` and `-to` options cannot be used with `-of_objects`.} + -filter {A filter expression of the form + "property==value" +where property is a property supported by the `get_property` command. See the section "Filter Expressions" for additional forms.} + } proc get_timing_edges { args } { return [get_timing_edges_cmd "get_timing_edges" $args] @@ -418,7 +481,11 @@ proc get_timing_arcs_to { to_pin_arg } { ################################################################ -define_cmd_args "report_clock_properties" {[clocks]} +define_cmd_args "report_clock_properties" {[clocks]} \ + -help {The `report_clock_properties` command reports the period and rise/fall edge times for each clock that has been defined.} \ + -arg_help { + clock_names {List of clock names to report.} + } proc_redirect report_clock_properties { check_argc_eq0or1 "report_clock_properties" $args diff --git a/tcl/StaTclTypes.i b/tcl/StaTclTypes.i index a89054fac..d19844b50 100644 --- a/tcl/StaTclTypes.i +++ b/tcl/StaTclTypes.i @@ -325,6 +325,10 @@ using namespace sta; $1 = tclListSeqPtr($input, SWIGTYPE_p_Cell, interp); } +%typemap(freearg) CellSeq* { + delete $1; +} + %typemap(out) CellSeq { seqTclList($1, SWIGTYPE_p_Cell, interp); } @@ -333,6 +337,10 @@ using namespace sta; $1 = tclListSeqPtr($input, SWIGTYPE_p_LibertyCell, interp); } +%typemap(freearg) LibertyCellSeq* { + delete $1; +} + %typemap(out) LibertyCellSeq * { seqPtrTclList($1, SWIGTYPE_p_LibertyCell, interp); } @@ -345,6 +353,10 @@ using namespace sta; $1 = tclListSeqPtr($input, SWIGTYPE_p_LibertyPort, interp); } +%typemap(freearg) LibertyPortSeq* { + delete $1; +} + %typemap(out) LibertyPortSeq { seqTclList($1, SWIGTYPE_p_LibertyPort, interp); } @@ -368,6 +380,10 @@ using namespace sta; $1 = tclListSeqPtr($input, SWIGTYPE_p_Port, interp); } +%typemap(freearg) PortSeq* { + delete $1; +} + %typemap(out) PortSeq { seqTclList($1, SWIGTYPE_p_Port, interp); } @@ -541,6 +557,10 @@ using namespace sta; $1 = tclListSeqPtr($input, SWIGTYPE_p_Instance, interp); } +%typemap(freearg) InstanceSeq* { + delete $1; +} + %typemap(in) InstanceSeq { $1 = tclListSeq($input, SWIGTYPE_p_Instance, interp); } @@ -573,6 +593,10 @@ using namespace sta; $1 = tclListSeqPtr($input, SWIGTYPE_p_LibertyLibrary, interp); } +%typemap(freearg) LibertyLibrarySeq* { + delete $1; +} + %typemap(out) LibertyLibrarySeq { seqTclList($1, SWIGTYPE_p_LibertyLibrary, interp); } @@ -599,6 +623,10 @@ using namespace sta; $1 = tclListSeqPtr($input, SWIGTYPE_p_Net, interp); } +%typemap(freearg) NetSeq* { + delete $1; +} + %typemap(out) NetSeq* { seqPtrTclList($1, SWIGTYPE_p_Net, interp); } @@ -644,6 +672,10 @@ using namespace sta; $1 = tclListSeqPtr($input, SWIGTYPE_p_Clock, interp); } +%typemap(freearg) ClockSeq* { + delete $1; +} + %typemap(out) ClockSeq* { seqPtrTclList($1, SWIGTYPE_p_Clock, interp); } @@ -661,6 +693,10 @@ using namespace sta; $1 = tclListSeqPtr($input, SWIGTYPE_p_Pin, interp); } +%typemap(freearg) PinSeq* { + delete $1; +} + %typemap(in) PinSet { Network *network = Sta::sta()->ensureLinked(); $1 = tclListNetworkSet1($input, SWIGTYPE_p_Pin, interp, network); @@ -1078,6 +1114,10 @@ using namespace sta; $1 = tclListSeqPtr($input, SWIGTYPE_p_Edge, interp); } +%typemap(freearg) EdgeSeq* { + delete $1; +} + %typemap(out) EdgeSeq { seqTclList($1, SWIGTYPE_p_Edge, interp); } @@ -1121,6 +1161,10 @@ using namespace sta; $1 = tclListSeqPtr($input, SWIGTYPE_p_PathEnd, interp); } +%typemap(freearg) PathEndSeq* { + delete $1; +} + %typemap(out) PathEndSeq* { Tcl_Obj *list = Tcl_NewListObj(0, nullptr); const PathEndSeq *path_ends = $1; @@ -1222,6 +1266,10 @@ using namespace sta; $1 = tclListSeqPtr($input, SWIGTYPE_p_Mode, interp); } +%typemap(freearg) ModeSeq* { + delete $1; +} + %typemap(out) ModeSeq { seqTclList($1, SWIGTYPE_p_Mode, interp); } @@ -1259,6 +1307,10 @@ using namespace sta; $1 = tclListSeqPtr($input, SWIGTYPE_p_Scene, interp); } +%typemap(freearg) SceneSeq* { + delete $1; +} + %typemap(out) SceneSeq { seqTclList($1, SWIGTYPE_p_Scene, interp); } diff --git a/tcl/Util.tcl b/tcl/Util.tcl index 15443529b..72b8f369b 100644 --- a/tcl/Util.tcl +++ b/tcl/Util.tcl @@ -172,10 +172,19 @@ proc parse_redirect_args { arg_var } { ################################################################ -proc define_cmd_args { cmd arglist } { +proc define_cmd_args { cmd arglist args } { variable cmd_args + variable cmd_help + variable cmd_arg_help set cmd_args($cmd) $arglist + parse_key_args "define_cmd_args" args keys {-help -arg_help} flags {} + if { [info exists keys(-help)] } { + set cmd_help($cmd) $keys(-help) + } + if { [info exists keys(-arg_help)] } { + set cmd_arg_help($cmd) $keys(-arg_help) + } namespace export $cmd } @@ -185,6 +194,168 @@ proc define_hidden_cmd_args { cmd arglist } { namespace export $cmd } +# Shared option descriptions used when a command has no -arg_help entry +# for that option. Per-command -arg_help always wins. +proc define_common_arg_help { help_dict } { + variable common_arg_help + + foreach {opt text} $help_dict { + dict set common_arg_help $opt $text + } +} + +proc define_var_help { var values help } { + variable var_values + variable var_help + + set var_values($var) $values + set var_help($var) $help +} + +proc cmd_help_text { cmd } { + variable cmd_help + + if { [info exists cmd_help($cmd)] } { + return $cmd_help($cmd) + } + return "" +} + +proc cmd_arg_help_lookup { help_dict opt } { + if { $help_dict == {} } { + return "" + } + if { [dict exists $help_dict $opt] } { + return [dict get $help_dict $opt] + } + dict for {key text} $help_dict { + if { [lsearch -exact [split $key "|"] $opt] >= 0 } { + return $text + } + } + return "" +} + +# Longest name in a |-separated option group (-e|-echo -> -echo). +proc cmd_opt_group_canonical { alts } { + set best "" + foreach alt $alts { + if { [string length $alt] > [string length $best] } { + set best $alt + } + } + return $best +} + +# True when shorter names are prefixes of the longest (-thr of -through). +proc cmd_opt_group_is_aliases { alts } { + set canon [cmd_opt_group_canonical $alts] + foreach alt $alts { + if { $alt == $canon } { + continue + } + if { ![string equal -length [string length $alt] $alt $canon] } { + return 0 + } + } + return 1 +} + +proc cmd_arg_help_group_canonical { arglist opt } { + foreach match [regexp -all -inline -- \ + {-[-a-zA-Z0-9_]+(?:\|-[-a-zA-Z0-9_]+)+} $arglist] { + set alts [split $match "|"] + if { [lsearch -exact $alts $opt] >= 0 \ + && [cmd_opt_group_is_aliases $alts] } { + return [cmd_opt_group_canonical $alts] + } + } + return $opt +} + +proc cmd_arg_help_text { cmd opt } { + variable cmd_arg_help + variable common_arg_help + variable cmd_args + + set cmd_dict {} + if { [info exists cmd_arg_help($cmd)] } { + set cmd_dict $cmd_arg_help($cmd) + } + set text [cmd_arg_help_lookup $cmd_dict $opt] + if { $text != "" } { + return $text + } + if { [info exists cmd_args($cmd)] } { + set canon [cmd_arg_help_group_canonical $cmd_args($cmd) $opt] + if { $canon != $opt } { + set text [cmd_arg_help_lookup $cmd_dict $canon] + if { $text != "" } { + return $text + } + } + } + if { [info exists common_arg_help] } { + set text [cmd_arg_help_lookup $common_arg_help $opt] + if { $text != "" } { + return $text + } + if { [info exists cmd_args($cmd)] } { + set canon [cmd_arg_help_group_canonical $cmd_args($cmd) $opt] + if { $canon != $opt } { + return [cmd_arg_help_lookup $common_arg_help $canon] + } + } + } + return "" +} + +proc cmd_synopsis_options { arglist } { + set grouped {} + set opts {} + foreach match [regexp -all -inline -- \ + {-[-a-zA-Z0-9_]+(?:\|-[-a-zA-Z0-9_]+)+} $arglist] { + set alts [split $match "|"] + if { ![cmd_opt_group_is_aliases $alts] } { + continue + } + foreach alt $alts { + lappend grouped $alt + } + set canon [cmd_opt_group_canonical $alts] + if { [lsearch -exact $opts $canon] < 0 } { + lappend opts $canon + } + } + foreach match [regexp -all -inline -- {-[a-zA-Z][a-zA-Z0-9_]*} $arglist] { + if { [lsearch -exact $grouped $match] >= 0 } { + continue + } + if { [lsearch -exact $opts $match] < 0 } { + lappend opts $match + } + } + return $opts +} + +proc var_help_text { var } { + variable var_help + + if { [info exists var_help($var)] } { + return $var_help($var) + } + return "" +} + +proc var_help_values { var } { + variable var_values + + if { [info exists var_values($var)] } { + return $var_values($var) + } + return "" +} + # "Optional Upvar" # If $other_var is not empty, the upvar is executed. # Otherwise, $my_var is set to empty. @@ -243,7 +414,11 @@ proc sta_warn_error { msg_id warn_error msg } { } } -define_cmd_args "suppress_msg" msg_ids +define_cmd_args "suppress_msg" msg_ids \ + -help {The `suppress_msg` command suppresses specified error/warning messages by ID. The list of message IDs can be found in `doc/Messages.md`.} \ + -arg_help { + msg_ids {A list of error/warning message IDs to suppress.} + } proc suppress_msg { args } { foreach msg_id $args { @@ -252,7 +427,11 @@ proc suppress_msg { args } { } } -define_cmd_args "unsuppress_msg" msg_ids +define_cmd_args "unsuppress_msg" msg_ids \ + -help {The `unsuppress_msg` command removes suppressions for the specified error/warning messages by ID. The list of message IDs can be found in `doc/Messages.md`.} \ + -arg_help { + msg_ids {A list of error/warning message IDs to unsuppress.} + } proc unsuppress_msg { args } { foreach msg_id $args { @@ -262,8 +441,10 @@ proc unsuppress_msg { args } { } # Defined by StaTcl.i -define_cmd_args "elapsed_run_time" {} -define_cmd_args "user_run_time" {} +define_cmd_args "elapsed_run_time" {} \ + -help {Returns the total clock run time in seconds as a float.} +define_cmd_args "user_run_time" {} \ + -help {Returns the total user cpu run time in seconds as a float.} # Write run time statistics to filename. proc write_stats { filename } { @@ -276,14 +457,19 @@ proc write_stats { filename } { ################################################################ # Begin/end logging all output to a file. -define_cmd_args "log_begin" { filename } +define_cmd_args "log_begin" { filename } \ + -help {The `log_begin` command copies all subsequent command output to a file until `log_end` is called.} \ + -arg_help { + filename {The log file to write.} + } proc log_begin { filename } { log_begin_cmd [file nativename $filename] } # Defined by StaTcl.i -define_cmd_args "log_end" {} +define_cmd_args "log_end" {} \ + -help {The `log_end` command stops copying command output to a file started with `log_begin`.} # set_debug is NOT in the global namespace # because it isn't intended for nosy users. @@ -377,7 +563,17 @@ proc check_percent { cmd_arg arg } { set ::sta_continue_on_error 0 define_cmd_args "include" \ - {[-e|-echo] [-v|-verbose] filename [> filename] [>> filename]} + {[-e|-echo] [-v|-verbose] filename [> filename] [>> filename]} \ + -help {Read STA/SDC/Tcl commands from filename. + +The `include` command stops and reports any errors encountered while reading a file unless `sta_continue_on_error` is 1.} \ + -arg_help { + -echo|-e {Print each command before evaluating it.} + -verbose|-v {Print each command before evaluating it as well as the result it returns.} + filename {The name of the file containing commands to read.} + > {Redirect command output to log_filename.} + >> {Redirect command output and append log_filename.} + } # Tcl "source" command analog to support -echo and -verbose return values. proc_redirect include { @@ -478,6 +674,34 @@ proc include_file { filename echo verbose } { } } +define_common_arg_help { + -rise {Restrict the command to rising transitions.} + -fall {Restrict the command to falling transitions.} + -min {Apply to minimum (hold) analysis.} + -max {Apply to maximum (setup) analysis.} + -setup {Apply to setup checks.} + -hold {Apply to hold checks.} + -digits {Number of digits to print after the decimal point.} + -nocase {Case-insensitive matching. Only valid with `-regexp`.} + -quiet {Do not report an error if no objects match.} + -regexp {Match patterns as regular expressions.} + -comment {Comment string saved with the constraint.} + -rise_from {Restrict `-from` to rising transitions.} + -fall_from {Restrict `-from` to falling transitions.} + -rise_through {Restrict `-through` to rising transitions.} + -fall_through {Restrict `-through` to falling transitions.} + -rise_to {Restrict `-to` to rising transitions.} + -fall_to {Restrict `-to` to falling transitions.} + -all {Apply to all matching objects.} + -early {Apply to early (min path) values.} + -late {Apply to late (max path) values.} + -scene {Restrict the command to one scene.} + -scenes {Restrict the command to one or more scenes.} + -report_variance {Include delay distribution variance in the report.} + -report_annotated {Report objects that are annotated.} + -no_line_splits {Do not split long lines into multiple lines.} +} + # sta namespace end } diff --git a/test/liberty_retain.lib b/test/liberty_retain.lib new file mode 100644 index 000000000..4c525eb90 --- /dev/null +++ b/test/liberty_retain.lib @@ -0,0 +1,96 @@ +library (liberty_retain) { + delay_model : "table_lookup"; + capacitive_load_unit (1,pF); + leakage_power_unit : "1pW"; + current_unit : "1A"; + pulling_resistance_unit : "1kohm"; + time_unit : "1ns"; + voltage_unit : "1v"; + library_features : "report_delay_calculation"; + input_threshold_pct_rise : 50; + input_threshold_pct_fall : 50; + output_threshold_pct_rise : 50; + output_threshold_pct_fall : 50; + slew_lower_threshold_pct_rise : 30; + slew_lower_threshold_pct_fall : 30; + slew_upper_threshold_pct_rise : 70; + slew_upper_threshold_pct_fall : 70; + slew_derate_from_library : 1.0; + nom_process : 1.0; + nom_temperature : 25.0; + nom_voltage : 1.0; + + cell (buf_retain) { + pin (A) { + capacitance : 0.001; + direction : "input"; + } + pin (Y) { + function : "A"; + direction : "output"; + max_capacitance : 0.1; + timing () { + related_pin : "A"; + timing_sense : "positive_unate"; + cell_rise (scalar) { + values ("4.0"); + } + cell_fall (scalar) { + values ("5.0"); + } + rise_transition (scalar) { + values ("0.4"); + } + fall_transition (scalar) { + values ("0.5"); + } + retaining_rise (scalar) { + values ("1.0"); + } + retaining_fall (scalar) { + values ("1.2"); + } + retain_rise_slew (scalar) { + values ("0.1"); + } + retain_fall_slew (scalar) { + values ("0.15"); + } + } + } + } + + cell (buf_retain_no_slew) { + pin (A) { + capacitance : 0.001; + direction : "input"; + } + pin (Y) { + function : "A"; + direction : "output"; + max_capacitance : 0.1; + timing () { + related_pin : "A"; + timing_sense : "positive_unate"; + cell_rise (scalar) { + values ("4.0"); + } + cell_fall (scalar) { + values ("5.0"); + } + rise_transition (scalar) { + values ("0.4"); + } + fall_transition (scalar) { + values ("0.5"); + } + retaining_rise (scalar) { + values ("1.0"); + } + retaining_fall (scalar) { + values ("1.2"); + } + } + } + } +} diff --git a/test/liberty_retain.ok b/test/liberty_retain.ok new file mode 100644 index 000000000..798970760 --- /dev/null +++ b/test/liberty_retain.ok @@ -0,0 +1,154 @@ +Startpoint: in1 (input port clocked by clk) +Endpoint: out1 (output port clocked by clk) +Path Group: clk +Path Type: max + + Slew Delay Time Description +---------------------------------------------------------------------- + 0.0000 0.0000 0.0000 clock clk (rise edge) + 0.0000 0.0000 clock network delay (ideal) + 0.0000 0.0000 v input external delay + 0.0000 0.0000 0.0000 v in1 (in) + 0.5000 5.0000 5.0000 v u1/Y (buf_retain) + 0.5000 0.0000 5.0000 v out1 (out) + 5.0000 data arrival time + + 0.0000 10.0000 10.0000 clock clk (rise edge) + 0.0000 10.0000 clock network delay (ideal) + 0.0000 10.0000 clock reconvergence pessimism + 0.0000 10.0000 output external delay + 10.0000 data required time +---------------------------------------------------------------------- + 10.0000 data required time + -5.0000 data arrival time +---------------------------------------------------------------------- + 5.0000 slack (MET) + + +Startpoint: in1 (input port clocked by clk) +Endpoint: out1 (output port clocked by clk) +Path Group: clk +Path Type: min + + Slew Delay Time Description +---------------------------------------------------------------------- + 0.0000 0.0000 0.0000 clock clk (rise edge) + 0.0000 0.0000 clock network delay (ideal) + 0.0000 0.0000 ^ input external delay + 0.0000 0.0000 0.0000 ^ in1 (in) + 0.1000 1.0000 1.0000 ^ u1/Y (buf_retain) + 0.1000 0.0000 1.0000 ^ out1 (out) + 1.0000 data arrival time + + 0.0000 0.0000 0.0000 clock clk (rise edge) + 0.0000 0.0000 clock network delay (ideal) + 0.0000 0.0000 clock reconvergence pessimism + 0.0000 0.0000 output external delay + 0.0000 data required time +---------------------------------------------------------------------- + 0.0000 data required time + -1.0000 data arrival time +---------------------------------------------------------------------- + 1.0000 slack (MET) + + +max dcalc retain slew +Library: liberty_retain +Cell: buf_retain +Arc sense: positive_unate +Arc type: combinational +A ^ -> Y ^ +Table value constant = 4.0000 +Delay = 4.0000 + +Table value constant = 0.4000 +Slew = 0.4000 +Driver waveform slew = 0.4000 + +............................................. + +A v -> Y v +Table value constant = 5.0000 +Delay = 5.0000 + +Table value constant = 0.5000 +Slew = 0.5000 +Driver waveform slew = 0.5000 + +............................................. + +min dcalc retain slew +Library: liberty_retain +Cell: buf_retain +Arc sense: positive_unate +Arc type: combinational +A ^ -> Y ^ +Table value constant = 1.0000 +Delay = 1.0000 + +Table value constant = 0.1000 +Slew = 0.1000 +Driver waveform slew = 0.1000 + +............................................. + +A v -> Y v +Table value constant = 1.2000 +Delay = 1.2000 + +Table value constant = 0.1500 +Slew = 0.1500 +Driver waveform slew = 0.1500 + +............................................. + +max dcalc parent slew fallback +Library: liberty_retain +Cell: buf_retain_no_slew +Arc sense: positive_unate +Arc type: combinational +A ^ -> Y ^ +Table value constant = 4.0000 +Delay = 4.0000 + +Table value constant = 0.4000 +Slew = 0.4000 +Driver waveform slew = 0.4000 + +............................................. + +A v -> Y v +Table value constant = 5.0000 +Delay = 5.0000 + +Table value constant = 0.5000 +Slew = 0.5000 +Driver waveform slew = 0.5000 + +............................................. + +min dcalc parent slew fallback +Library: liberty_retain +Cell: buf_retain_no_slew +Arc sense: positive_unate +Arc type: combinational +A ^ -> Y ^ +Table value constant = 1.0000 +Delay = 1.0000 + +Table value constant = 0.4000 +Slew = 0.4000 +Driver waveform slew = 0.4000 + +............................................. + +A v -> Y v +Table value constant = 1.2000 +Delay = 1.2000 + +Table value constant = 0.5000 +Slew = 0.5000 +Driver waveform slew = 0.5000 + +............................................. + diff --git a/test/liberty_retain.tcl b/test/liberty_retain.tcl new file mode 100644 index 000000000..e2c613768 --- /dev/null +++ b/test/liberty_retain.tcl @@ -0,0 +1,27 @@ +# Liberty retaining_rise/fall and retain_rise_slew/retain_fall_slew. +# Retain tables are the min (contamination) delay and slew. + +read_liberty liberty_retain.lib +read_verilog liberty_retain.v +link_design top + +create_clock -name clk -period 10 +set_input_delay -clock clk 0 {in1 in2} +set_output_delay -clock clk 0 {out1 out2} +set_input_transition 0 {in1 in2} +set_load 0 {out1 out2} + +report_checks -path_delay max -to out1 -digits 4 -fields {slew} \ + -group_path_count 1 +report_checks -path_delay min -to out1 -digits 4 -fields {slew} \ + -group_path_count 1 + +puts "max dcalc retain slew" +report_dcalc -from u1/A -to u1/Y -max -digits 4 +puts "min dcalc retain slew" +report_dcalc -from u1/A -to u1/Y -min -digits 4 + +puts "max dcalc parent slew fallback" +report_dcalc -from u2/A -to u2/Y -max -digits 4 +puts "min dcalc parent slew fallback" +report_dcalc -from u2/A -to u2/Y -min -digits 4 diff --git a/test/liberty_retain.v b/test/liberty_retain.v new file mode 100644 index 000000000..499e82f09 --- /dev/null +++ b/test/liberty_retain.v @@ -0,0 +1,7 @@ +module top (in1, in2, out1, out2); + input in1, in2; + output out1, out2; + + buf_retain u1 (.A(in1), .Y(out1)); + buf_retain_no_slew u2 (.A(in2), .Y(out2)); +endmodule diff --git a/test/non_seq_timing.lib b/test/non_seq_timing.lib new file mode 100644 index 000000000..06d13846f --- /dev/null +++ b/test/non_seq_timing.lib @@ -0,0 +1,73 @@ +library(non_seq_timing) { + delay_model : table_lookup; + time_unit : "1ns"; + capacitive_load_unit (1, pf); + input_threshold_pct_rise : 50; + input_threshold_pct_fall : 50; + output_threshold_pct_rise : 50; + output_threshold_pct_fall : 50; + slew_lower_threshold_pct_rise : 20; + slew_lower_threshold_pct_fall : 20; + slew_upper_threshold_pct_rise : 80; + slew_upper_threshold_pct_fall : 80; + + + cell(CKMUX) { + pin(CLK1) { direction : input; } + pin(CLK2) { direction : input; } + pin(CLKSEL) { + direction : input; + timing() { + related_pin : "CLK1"; + timing_type : non_seq_setup_rising; + rise_constraint(scalar) { values ("0.050"); } + fall_constraint(scalar) { values ("0.050"); } + } + timing() { + related_pin : "CLK1"; + timing_type : non_seq_hold_rising; + rise_constraint(scalar) { values ("0.020"); } + fall_constraint(scalar) { values ("0.020"); } + } + timing() { + related_pin : "CLK2"; + timing_type : non_seq_setup_rising; + rise_constraint(scalar) { values ("0.050"); } + fall_constraint(scalar) { values ("0.050"); } + } + timing() { + related_pin : "CLK2"; + timing_type : non_seq_hold_rising; + rise_constraint(scalar) { values ("0.020"); } + fall_constraint(scalar) { values ("0.020"); } + } + } + pin(CLKOUT) { + direction : output; + function : "(!CLKSEL & CLK1) | (CLKSEL & CLK2)"; + timing() { + related_pin : "CLK1"; + when : "!CLKSEL"; + cell_rise(scalar) { values ("0.030"); } + cell_fall(scalar) { values ("0.030"); } + rise_transition(scalar) { values ("0.020"); } + fall_transition(scalar) { values ("0.020"); } + } + timing() { + related_pin : "CLK2"; + when : "CLKSEL"; + cell_rise(scalar) { values ("0.030"); } + cell_fall(scalar) { values ("0.030"); } + rise_transition(scalar) { values ("0.020"); } + fall_transition(scalar) { values ("0.020"); } + } + timing() { + related_pin : "CLKSEL"; + cell_rise(scalar) { values ("0.025"); } + cell_fall(scalar) { values ("0.025"); } + rise_transition(scalar) { values ("0.020"); } + fall_transition(scalar) { values ("0.020"); } + } + } + } +} diff --git a/test/non_seq_timing.ok b/test/non_seq_timing.ok new file mode 100644 index 000000000..df1adb17c --- /dev/null +++ b/test/non_seq_timing.ok @@ -0,0 +1,27 @@ +Startpoint: r1 (rising edge-triggered flip-flop clocked by clk) +Endpoint: ckmux (rising edge-triggered flip-flop clocked by clk) +Path Group: clk +Path Type: max + + Delay Time Description +--------------------------------------------------------- + 0.00 0.00 clock clk (rise edge) + 0.00 0.00 clock network delay (ideal) + 0.00 0.00 ^ r1/CLK (DFFHQx4_ASAP7_75t_R) + 0.06 0.06 ^ r1/Q (DFFHQx4_ASAP7_75t_R) + 0.00 0.06 ^ ckmux/CLKSEL (CKMUX) + 0.06 data arrival time + + 10.00 10.00 clock clk (rise edge) + 0.00 10.00 clock network delay (ideal) + 0.00 10.00 clock reconvergence pessimism + 10.00 ^ ckmux/CLK1 (CKMUX) + -0.05 9.95 library non-sequential setup time + 9.95 data required time +--------------------------------------------------------- + 9.95 data required time + -0.06 data arrival time +--------------------------------------------------------- + 9.89 slack (MET) + + diff --git a/test/non_seq_timing.tcl b/test/non_seq_timing.tcl new file mode 100644 index 000000000..db47b7ab6 --- /dev/null +++ b/test/non_seq_timing.tcl @@ -0,0 +1,9 @@ +read_liberty non_seq_timing.lib +read_liberty asap7_seq.lib.gz + +read_verilog non_seq_timing.v +link_design test + +create_clock -name clk -period 10 [get_ports *clk*] + +report_checks diff --git a/test/non_seq_timing.v b/test/non_seq_timing.v new file mode 100644 index 000000000..0e18f9d01 --- /dev/null +++ b/test/non_seq_timing.v @@ -0,0 +1,23 @@ +module test ( + input clk1, + input clk2, + input clk3, + input test_en, + output out +); + + wire sel; + DFFHQx4_ASAP7_75t_R r1 ( + .CLK(clk1), + .D(test_en), + .Q(sel) + ); + + CKMUX ckmux ( + .CLK1 (clk2), + .CLK2 (clk3), + .CLKSEL(sel), + .CLKOUT(out) + ); + +endmodule diff --git a/test/regression_vars.tcl b/test/regression_vars.tcl index ec03cdc31..47064d068 100644 --- a/test/regression_vars.tcl +++ b/test/regression_vars.tcl @@ -156,8 +156,10 @@ record_public_tests { liberty_ccsn liberty_float_as_str liberty_latch3 + liberty_retain make_concrete_parasitics_leak max_power_area + non_seq_timing package_require path_group_names power_json @@ -176,9 +178,17 @@ record_public_tests { set_path_margin6 slash_port_test suppress_msg + swig_seq_double_free + swig_seq_leak user_properties vcd_begin_end_time + verilog_assign_alias_loop verilog_attribute + verilog_bus_port_connect + verilog_port_bundle_find_pin + verilog_port_bundle_ordered + verilog_port_concat + verilog_unsized_constant verilog_well_supplies verilog_specify verilog_write_escape diff --git a/test/swig_seq_double_free.ok b/test/swig_seq_double_free.ok new file mode 100644 index 000000000..db5cb4e36 --- /dev/null +++ b/test/swig_seq_double_free.ok @@ -0,0 +1,66 @@ +[get_cells -filter liberty_cell==BUFx2_ASAP7_75t_R *] +u1 +[get_pins -filter direction==input r1/*] +r1/CLK +r1/D +[get_ports -filter direction==output *] +out +[get_nets -filter name=~*q *] +r1q +r2q +[get_clocks -filter is_virtual *] +vclk +[get_lib_cells -filter is_buffer *] +asap7_small/BUFx2_ASAP7_75t_R +[get_lib_pins -filter direction==output BUFx2_ASAP7_75t_R/*] +Y +[get_libs -filter name==asap7_small *] +asap7_small +[get_timing_edges -of_objects u1 -filter {from_pin =~ *}] +1 +[get_fanin -to out] +out +r3/CLK +r3/Q +[get_fanout -from in1] +in1 +r1/D +[get_fanin -only_cells -to r3/D] +r1 +r2 +r3 +u1 +u2 +report_path_ends +module top (in1, + in2, + clk1, + clk2, + clk3, + out); + input in1; + input in2; + input clk1; + input clk2; + input clk3; + output out; + + wire r1q; + wire r2q; + wire u1z; + wire u2z; + + DFFHQx4_ASAP7_75t_R r1 (.Q(r1q), + .CLK(clk1), + .D(in1)); + DFFHQx4_ASAP7_75t_R r2 (.Q(r2q), + .CLK(clk2), + .D(in2)); + DFFHQx4_ASAP7_75t_R r3 (.Q(out), + .CLK(clk3), + .D(u2z)); + AND2x2_ASAP7_75t_R u2 (.Y(u2z), + .A(r1q), + .B(u1z)); +endmodule +false_path diff --git a/test/swig_seq_double_free.tcl b/test/swig_seq_double_free.tcl new file mode 100644 index 000000000..9661099d1 --- /dev/null +++ b/test/swig_seq_double_free.tcl @@ -0,0 +1,56 @@ +# SWIG Seq* double-free if %typemap(freearg) and C++ both delete. +# Successful get_* -filter, get_fanin/fanout, write_verilog -remove_cells, +# and report_path_ends all allocate a Seq in the in typemap. +# Run under -fsanitize=address or ./regression -valgrind. +source helpers.tcl +read_liberty asap7_small.lib.gz +read_verilog reg1_asap7.v +link_design top +create_clock -name clk -period 500 {clk1 clk2 clk3} +create_clock -name vclk -period 1000 +set_input_delay -clock clk 0 {in1 in2} + +puts {[get_cells -filter liberty_cell==BUFx2_ASAP7_75t_R *]} +report_object_full_names [get_cells -filter liberty_cell==BUFx2_ASAP7_75t_R *] +puts {[get_pins -filter direction==input r1/*]} +report_object_full_names [get_pins -filter direction==input r1/*] +puts {[get_ports -filter direction==output *]} +report_object_full_names [get_ports -filter direction==output *] +puts {[get_nets -filter name=~*q *]} +report_object_full_names [get_nets -filter name=~*q *] +puts {[get_clocks -filter is_virtual *]} +report_object_full_names [get_clocks -filter is_virtual *] +puts {[get_lib_cells -filter is_buffer *]} +report_object_full_names [get_lib_cells -filter is_buffer *] +puts {[get_lib_pins -filter direction==output BUFx2_ASAP7_75t_R/*]} +report_object_full_names [get_lib_pins -filter direction==output BUFx2_ASAP7_75t_R/*] +puts {[get_libs -filter name==asap7_small *]} +report_object_full_names [get_libs -filter name==asap7_small *] + +puts {[get_timing_edges -of_objects u1 -filter {from_pin =~ *}]} +puts [llength [get_timing_edges -of_objects u1 -filter {from_pin =~ *}]] + +puts {[get_fanin -to out]} +report_object_full_names [get_fanin -to out] +puts {[get_fanout -from in1]} +report_object_full_names [get_fanout -from in1] +puts {[get_fanin -only_cells -to r3/D]} +report_object_full_names [get_fanin -only_cells -to r3/D] + +# PathEndSeq* input to report_path_ends. +with_output_to_variable ignored { + sta::report_path_ends [find_timing_paths -group_path_count 1] +} +puts report_path_ends + +# CellSeq* input to write_verilog_cmd. +set verilog_file [make_result_file "swig_seq_double_free.v"] +write_verilog -remove_cells BUFx2_ASAP7_75t_R $verilog_file +report_file $verilog_file + +# ExceptionThruSeq* is stored by set_false_path; freearg would use-after-free. +set_false_path -through u1 +with_output_to_variable ignored { + report_checks -format end -group_path_count 1 +} +puts false_path diff --git a/test/swig_seq_leak.ok b/test/swig_seq_leak.ok new file mode 100644 index 000000000..c1240f0f7 --- /dev/null +++ b/test/swig_seq_leak.ok @@ -0,0 +1,22 @@ +sta::filter_insts {name ~= *r1*} [get_cells *] +Error: 2600 -filter parsing failed at '~= *r1*'. +[get_cells -filter {name ~= *r1*} *] +Error: 2600 -filter parsing failed at '~= *r1*'. +[get_pins -filter {name ~= *CLK*} *] +Error: 2600 -filter parsing failed at '~= *CLK*'. +[get_ports -filter {name ~= clk*} *] +Error: 2600 -filter parsing failed at '~= clk*'. +[get_nets -filter {name ~= *q*} *] +Error: 2600 -filter parsing failed at '~= *q*'. +[get_clocks -filter {name ~= clk*} *] +Error: 2600 -filter parsing failed at '~= clk*'. +[get_lib_cells -filter {name ~= BUF*} *] +Error: 2600 -filter parsing failed at '~= BUF*'. +[get_lib_pins -filter {name ~= A} BUFx2_ASAP7_75t_R/*] +Error: 2600 -filter parsing failed at '~= A'. +[get_libs -filter {name ~= asap*} *] +Error: 2600 -filter parsing failed at '~= asap*'. +[get_timing_edges -of_objects u1 -filter {from_pin ~= *}] +Error: 2600 -filter parsing failed at '~= *'. +sta::filter_path_ends {name ~= x} [find_timing_paths] +Error: 2600 -filter parsing failed at '~= x'. diff --git a/test/swig_seq_leak.tcl b/test/swig_seq_leak.tcl new file mode 100644 index 000000000..ca169eabd --- /dev/null +++ b/test/swig_seq_leak.tcl @@ -0,0 +1,47 @@ +# SWIG Seq* leak if %exception returns past %typemap(freearg). +# tclListSeqPtr allocates a non-empty Seq, then FilterExpr throws. +# Empty Tcl lists do not allocate (tclListSeqPtr returns nullptr). +# Run under -fsanitize=address or ./regression -valgrind. +read_liberty asap7_small.lib.gz +read_verilog reg1_asap7.v +link_design top +create_clock -name clk -period 500 {clk1 clk2 clk3} +create_clock -name vclk -period 1000 +set_input_delay -clock clk 0 {in1 in2} + +# Direct wrapper that leaked in get_filter valgrind (filter_insts). +puts {sta::filter_insts {name ~= *r1*} [get_cells *]} +catch {sta::filter_insts {name ~= *r1*} [get_cells *]} result +puts $result + +puts {[get_cells -filter {name ~= *r1*} *]} +catch {get_cells -filter {name ~= *r1*} *} result +puts $result +puts {[get_pins -filter {name ~= *CLK*} *]} +catch {get_pins -filter {name ~= *CLK*} *} result +puts $result +puts {[get_ports -filter {name ~= clk*} *]} +catch {get_ports -filter {name ~= clk*} *} result +puts $result +puts {[get_nets -filter {name ~= *q*} *]} +catch {get_nets -filter {name ~= *q*} *} result +puts $result +puts {[get_clocks -filter {name ~= clk*} *]} +catch {get_clocks -filter {name ~= clk*} *} result +puts $result +puts {[get_lib_cells -filter {name ~= BUF*} *]} +catch {get_lib_cells -filter {name ~= BUF*} *} result +puts $result +puts {[get_lib_pins -filter {name ~= A} BUFx2_ASAP7_75t_R/*]} +catch {get_lib_pins -filter {name ~= A} BUFx2_ASAP7_75t_R/*} result +puts $result +puts {[get_libs -filter {name ~= asap*} *]} +catch {get_libs -filter {name ~= asap*} *} result +puts $result +puts {[get_timing_edges -of_objects u1 -filter {from_pin ~= *}]} +catch {get_timing_edges -of_objects u1 -filter {from_pin ~= *}} result +puts $result + +puts {sta::filter_path_ends {name ~= x} [find_timing_paths]} +catch {sta::filter_path_ends {name ~= x} [find_timing_paths]} result +puts $result diff --git a/test/verilog_assign_alias_loop.ok b/test/verilog_assign_alias_loop.ok new file mode 100644 index 000000000..b0944d67c --- /dev/null +++ b/test/verilog_assign_alias_loop.ok @@ -0,0 +1,4 @@ +a +p +q +y diff --git a/test/verilog_assign_alias_loop.tcl b/test/verilog_assign_alias_loop.tcl new file mode 100644 index 000000000..9e7b48f9c --- /dev/null +++ b/test/verilog_assign_alias_loop.tcl @@ -0,0 +1,6 @@ +# Continuous assigns that alias two nets in both directions. +# Nothing is reported; the test is that link_design terminates. +read_liberty ../examples/nangate45_typ.lib.gz +read_verilog verilog_assign_alias_loop.v +link_design top +report_object_full_names [get_nets *] diff --git a/test/verilog_assign_alias_loop.v b/test/verilog_assign_alias_loop.v new file mode 100644 index 000000000..719427ab6 --- /dev/null +++ b/test/verilog_assign_alias_loop.v @@ -0,0 +1,15 @@ +// Two continuous assigns aliasing p and q in both directions. The first +// merges q into p; on the second both sides resolve to the same net, so +// mergeInto is called with net == this. Reachable from real netlists after +// buffer removal or ECO rewiring, where one pass adds an alias and a later +// pass adds the reverse. +module top (a, y); + input a; + output y; + wire p; + wire q; + BUF_X1 g0 (.A(a), .Z(p)); + assign q = p; + assign p = q; + INV_X1 g1 (.A(q), .ZN(y)); +endmodule diff --git a/test/verilog_bus_port_connect.ok b/test/verilog_bus_port_connect.ok new file mode 100644 index 000000000..380130370 --- /dev/null +++ b/test/verilog_bus_port_connect.ok @@ -0,0 +1 @@ +Warning 2728: port b has no pin to connect. diff --git a/test/verilog_bus_port_connect.tcl b/test/verilog_bus_port_connect.tcl new file mode 100644 index 000000000..9553d8e78 --- /dev/null +++ b/test/verilog_bus_port_connect.tcl @@ -0,0 +1,5 @@ +# connect_pin to a bus port, which has no pin. +read_liberty ../examples/nangate45_typ.lib.gz +read_verilog verilog_bus_port_connect.v +link_design top +connect_pin {a[0]} u/b diff --git a/test/verilog_bus_port_connect.v b/test/verilog_bus_port_connect.v new file mode 100644 index 000000000..96714c447 --- /dev/null +++ b/test/verilog_bus_port_connect.v @@ -0,0 +1,13 @@ +// A hierarchical instance with a bus port. A bus port has members and no pin +// index, so connecting a net to the bus port itself has no pin to make. +module top (a, y); + input [1:0] a; + output y; + sub u (.b(a), .r(y)); +endmodule + +module sub (b, r); + input [1:0] b; + output r; + INV_X1 g (.A(b[0]), .ZN(r)); +endmodule diff --git a/test/verilog_port_bundle_find_pin.ok b/test/verilog_port_bundle_find_pin.ok new file mode 100644 index 000000000..7951defec --- /dev/null +++ b/test/verilog_port_bundle_find_pin.ok @@ -0,0 +1 @@ +NULL diff --git a/test/verilog_port_bundle_find_pin.tcl b/test/verilog_port_bundle_find_pin.tcl new file mode 100644 index 000000000..6622067ae --- /dev/null +++ b/test/verilog_port_bundle_find_pin.tcl @@ -0,0 +1,5 @@ +# find_pin on a bundle port, which has no pin. +read_liberty ../examples/nangate45_typ.lib.gz +read_verilog verilog_port_bundle_find_pin.v +link_design top +puts [[get_cells u] find_pin px] diff --git a/test/verilog_port_bundle_find_pin.v b/test/verilog_port_bundle_find_pin.v new file mode 100644 index 000000000..5aa304ab3 --- /dev/null +++ b/test/verilog_port_bundle_find_pin.v @@ -0,0 +1,15 @@ +// An explicit named header port (IEEE 1364-2005 A.1.4) reached by a *named* +// connection links, because the lookup is by name and finds the member port. +// The bundle port px is still in the cell port list with no pin index, so +// looking a pin up by that name must not index pins_[-1]. +module top (a, y); + input a; + output y; + sub u (.px(a), .py(y)); +endmodule + +module sub (.px(m), .py(r)); + input m; + output r; + INV_X1 g (.A(m), .ZN(r)); +endmodule diff --git a/test/verilog_port_bundle_ordered.ok b/test/verilog_port_bundle_ordered.ok new file mode 100644 index 000000000..b634fb70c --- /dev/null +++ b/test/verilog_port_bundle_ordered.ok @@ -0,0 +1 @@ +Warning 2723: verilog_port_bundle_ordered.v line 9, instance u port px port expression cannot be connected. diff --git a/test/verilog_port_bundle_ordered.tcl b/test/verilog_port_bundle_ordered.tcl new file mode 100644 index 000000000..05b07cd2e --- /dev/null +++ b/test/verilog_port_bundle_ordered.tcl @@ -0,0 +1,4 @@ +# Explicit named module header port reached by an ordered connection list. +read_liberty ../examples/nangate45_typ.lib.gz +read_verilog verilog_port_bundle_ordered.v +link_design top diff --git a/test/verilog_port_bundle_ordered.v b/test/verilog_port_bundle_ordered.v new file mode 100644 index 000000000..3fc66a367 --- /dev/null +++ b/test/verilog_port_bundle_ordered.v @@ -0,0 +1,16 @@ +// An explicit named header port (IEEE 1364-2005 A.1.4, +// port ::= . port_identifier ( [ port_expression ] )) reached by an ordered +// connection list. The header entry .px(m) is modelled as a bundle port px +// plus a member port m; a bundle port gets no pin index, and the ordered +// binding walks the port list, so slot 1 lands on the bundle. +module top (a, y); + input a; + output y; + sub u (a, y); +endmodule + +module sub (.px(m), .py(r)); + input m; + output r; + INV_X1 g (.A(m), .ZN(r)); +endmodule diff --git a/test/verilog_port_concat.ok b/test/verilog_port_concat.ok new file mode 100644 index 000000000..24249bb92 --- /dev/null +++ b/test/verilog_port_concat.ok @@ -0,0 +1,3 @@ +Warning 2721: verilog_port_concat.v line 6, module top port expression without a port identifier is not supported. +Warning 197: verilog_port_concat.v line 6, module top declared signal a is not in the port list. +Warning 2722: verilog_port_concat.v line 6, module top port a not found. diff --git a/test/verilog_port_concat.tcl b/test/verilog_port_concat.tcl new file mode 100644 index 000000000..2eb4458a2 --- /dev/null +++ b/test/verilog_port_concat.tcl @@ -0,0 +1,4 @@ +# Concatenation port expression in the module header. +read_liberty ../examples/nangate45_typ.lib.gz +read_verilog verilog_port_concat.v +link_design top diff --git a/test/verilog_port_concat.v b/test/verilog_port_concat.v new file mode 100644 index 000000000..af4e4d0c3 --- /dev/null +++ b/test/verilog_port_concat.v @@ -0,0 +1,10 @@ +// A concatenation port_expression in the top module header, which IEEE +// 1364-2005 A.1.4 allows (port_expression ::= port_reference | +// { port_reference {, port_reference} }; the LRM's own example is +// module complex_ports ({c,d}, .e(f))). No Port is made for the unnamed +// slot, so the port lookup in VerilogReader::linkNetwork finds nothing. +module top ({a}, z); + input a; + output z; + INV_X1 g (.A(a), .ZN(z)); +endmodule diff --git a/test/verilog_unsized_constant.ok b/test/verilog_unsized_constant.ok new file mode 100644 index 000000000..e459030b0 --- /dev/null +++ b/test/verilog_unsized_constant.ok @@ -0,0 +1 @@ +Warning 2724: verilog_unsized_constant.v line 8, unsized constant 'b0 not supported. diff --git a/test/verilog_unsized_constant.tcl b/test/verilog_unsized_constant.tcl new file mode 100644 index 000000000..eff75fdc6 --- /dev/null +++ b/test/verilog_unsized_constant.tcl @@ -0,0 +1,4 @@ +# Unsized constant in a port connection. +read_liberty ../examples/nangate45_typ.lib.gz +read_verilog verilog_unsized_constant.v +link_design top diff --git a/test/verilog_unsized_constant.v b/test/verilog_unsized_constant.v new file mode 100644 index 000000000..6d5c02e62 --- /dev/null +++ b/test/verilog_unsized_constant.v @@ -0,0 +1,9 @@ +// An unsized literal in a port connection. IEEE 1364-2005 3.5.1 makes the +// size of a number optional, so 'b0 is a legal number. The size field is the +// empty string, which reaches the unguarded conversion in +// VerilogNetConstant::parseConstant. +module top (a, y); + input a; + output y; + OR2_X1 g (.A1(a), .A2('b0), .ZN(y)); +endmodule diff --git a/test/write_path_spice_arc_sense.models.spice b/test/write_path_spice_arc_sense.models.spice deleted file mode 100644 index 655d398d5..000000000 --- a/test/write_path_spice_arc_sense.models.spice +++ /dev/null @@ -1,6 +0,0 @@ -* Placeholder SPICE model file for the write_path_spice_arc_sense regression. -* -* write_path_spice requires a -model_file and emits it as a ".include" line in -* the generated deck, but does not read its contents. The regression only -* diffs the written deck, so no transistor models are needed here. Supply the -* real SKY130 sky130_fd_pr models if you want to simulate the deck in ngspice. diff --git a/test/write_path_spice_arc_sense.ok b/test/write_path_spice_arc_sense.ok index dbbe1e7d6..520c5ad57 100644 --- a/test/write_path_spice_arc_sense.ok +++ b/test/write_path_spice_arc_sense.ok @@ -1,6 +1,6 @@ Warning 1171: write_path_spice_arc_sense.lib.gz line 23, default_fanout_load is 0.0. +Warning 1927: write_path_spice_arc_sense.tcl line 18, No -model_file specified. * Path from a v to x ^ -.include "write_path_spice_arc_sense.models.spice" .include "write_path_spice_arc_sense.sp_1.subckt" .tran 1e-13 3.33e-09 diff --git a/test/write_path_spice_arc_sense.cells.spice b/test/write_path_spice_arc_sense.subckt similarity index 100% rename from test/write_path_spice_arc_sense.cells.spice rename to test/write_path_spice_arc_sense.subckt diff --git a/test/write_path_spice_arc_sense.tcl b/test/write_path_spice_arc_sense.tcl index f3ea8d967..ab3b33f7f 100644 --- a/test/write_path_spice_arc_sense.tcl +++ b/test/write_path_spice_arc_sense.tcl @@ -13,8 +13,7 @@ set_output_delay -clock vclk 0 [all_outputs] set spice_file [make_result_file "write_path_spice_arc_sense.sp"] write_path_spice -path_args {-path_delay max -fall_from [get_ports a] -rise_to [get_ports x]} \ -spice_file $spice_file \ - -lib_subckt_file write_path_spice_arc_sense.cells.spice \ - -model_file write_path_spice_arc_sense.models.spice \ + -lib_subckt_file write_path_spice_arc_sense.subckt \ -power VPWR -ground VGND \ -simulator ngspice -report_file ${spice_file}_1.sp +report_file_filter ${spice_file}_1.sp [file dirname $result_dir]/ diff --git a/verilog/Verilog.i b/verilog/Verilog.i index 75ecef335..fd4a49e43 100644 --- a/verilog/Verilog.i +++ b/verilog/Verilog.i @@ -44,7 +44,6 @@ write_verilog_cmd(const char *filename, // to see the sta internal names. Network *network = Sta::sta()->network(); writeVerilog(filename, include_pwr_gnd, remove_cells, network); - delete remove_cells; } %} // inline diff --git a/verilog/Verilog.tcl b/verilog/Verilog.tcl index 216d7c3e1..bd9c29886 100644 --- a/verilog/Verilog.tcl +++ b/verilog/Verilog.tcl @@ -25,14 +25,33 @@ namespace eval sta { # Defined by SWIG interface Verilog.i. -define_cmd_args "read_verilog" {filename} +define_cmd_args "read_verilog" {filename} \ + -help {The `read_verilog` command reads a gate level verilog netlist. After all verilog netlist and Liberty libraries are read the design must be linked with the `link_design` command. + +Verilog 2001 module port declaratations are supported. An example is shown below. + +``` +module top (input in1, in2, clk1, clk2, clk3, + output out); +``` + +Files compressed with gzip are automatically uncompressed.} \ + -arg_help { + filename {The name of the verilog file to read.} + } proc_redirect read_verilog { read_verilog_cmd [file nativename [lindex $args 0]] } define_cmd_args "write_verilog" {[-include_pwr_gnd]\ - [-remove_cells cells] filename} + [-remove_cells cells] filename} \ + -help {The `write_verilog` command writes a Verilog netlist to filename. Use `-sort` to sort the instances so the results are reproducible across operating systems. Use `-remove_cells` to remove instances of lib_cells from the netlist.} \ + -arg_help { + -include_pwr_gnd {Include power and ground pins on instances.} + -remove_cells {`lib_cells`: Liberty cells to remove from the Verilog netlist. Use `get_lib_cells`, a list of cells names, or a cell name with wildcards.} + filename {Filename for the liberty library.} + } proc write_verilog { args } { # -sort deprecated 12/12/2025 diff --git a/verilog/VerilogReader.cc b/verilog/VerilogReader.cc index f3a0899d5..ce099176b 100644 --- a/verilog/VerilogReader.cc +++ b/verilog/VerilogReader.cc @@ -228,19 +228,23 @@ VerilogReader::makeCellPorts(Cell *cell, { StringSet port_names; for (VerilogNet *mod_port : *ports) { - const std::string &port_name = mod_port->name(); - if (!port_names.contains(port_name)) { - port_names.insert(port_name); - if (mod_port->isNamed()) { - if (mod_port->isNamedPortRef()) - makeNamedPortRefCellPorts(cell, module, mod_port, port_names); - else - makeCellPort(cell, module, mod_port->name()); - } + // A port expression without a port identifier (IEEE 1364-2005 A.1.4) + // makes no port. They all have the same empty name, so check before + // the repeated port name check below. + if (!mod_port->isNamed()) + warn(2721, module->filename(), module->line(), + "module {} port expression without a port identifier is not supported.", + module->name()); + else if (!port_names.contains(mod_port->name())) { + port_names.insert(mod_port->name()); + if (mod_port->isNamedPortRef()) + makeNamedPortRefCellPorts(cell, module, mod_port, port_names); + else + makeCellPort(cell, module, mod_port->name()); } else warn(165, module->filename(), module->line(), - "module {} repeated port name {}.", module->name(), port_name); + "module {} repeated port name {}.", module->name(), mod_port->name()); } checkModuleDcls(module, port_names); } @@ -1169,7 +1173,20 @@ VerilogNetConstant::parseConstant(std::string_view constant, std::string csize(constant.substr(0, csize_end)); // Read the constant size. - size_t size = std::stol(csize); + // IEEE 1364-2005 3.5.1 makes the size optional; the width comes from the + // context, which is not known here, so use one bit. + size_t size = 1; + if (csize.empty()) + reader->warn(2724, reader->filename(), line, + "unsized constant {} not supported.", constant); + else { + auto [size_value, valid] = stringLong(csize); + if (valid && size_value > 0) + size = size_value; + else + reader->warn(2725, reader->filename(), line, + "constant {} size is not supported.", constant); + } value_ = new VerilogConstantValue(size); // Read the constant base. @@ -1468,11 +1485,17 @@ VerilogReader::linkNetwork(std::string_view top_cell_name, while (net_name_iter->hasNext()) { const std::string &net_name = net_name_iter->next(); Port *port = network_->findPort(top_cell, net_name); - Net *net = bindings.ensureNetBinding(net_name, top_instance, network_); - // Guard against repeated port name. - if (network_->findPin(top_instance, port) == nullptr) { - Pin *pin = network_->makePin(top_instance, port, nullptr); - network_->makeTerm(pin, net); + if (port == nullptr) + // No port was made for this module port list entry. + linkWarn(2722, module->filename(), module->line(), + "module {} port {} not found.", module->name(), net_name); + else { + Net *net = bindings.ensureNetBinding(net_name, top_instance, network_); + // Guard against repeated port name. + if (network_->findPin(top_instance, port) == nullptr) { + Pin *pin = network_->makePin(top_instance, port, nullptr); + network_->makeTerm(pin, net); + } } } delete net_name_iter; @@ -1657,7 +1680,15 @@ VerilogReader::makeOrderedInstPins(Cell *cell, while (pin_iter != mod_pins->end() && port_iter->hasNext()) { VerilogNet *net = *pin_iter++; Port *port = port_iter->next(); - if (network_->size(port) != net->size(parent_module)) { + // A bundle port from an explicit named module port (IEEE 1364-2005 A.1.4) + // has no pin index, so it cannot be connected. + if (network_->isBundle(port)) { + std::string inst_vname = instanceVerilogName(mod_inst->instanceName()); + linkError(2723, parent_module->filename(), mod_inst->line(), + "instance {} port {} port expression cannot be connected.", + inst_vname, network_->name(port)); + } + else if (network_->size(port) != net->size(parent_module)) { std::string inst_vname = instanceVerilogName(mod_inst->instanceName()); linkWarn(202, parent_module->filename(), mod_inst->line(), "instance {} port {} size {} does not match net size {}.", @@ -1720,7 +1751,7 @@ VerilogReader::makeInstPin(Instance *inst, // Pin should already exist by prior makePin, then connect to parent // net if present and create a term for the child-side net. Pin *pin = network_->findPin(inst, port); - if (net) { + if (net && pin) { network_->connect(inst, port, net); std::string port_name = network_->name(port); Net *child_net = bindings->ensureNetBinding(port_name, inst, network_);