Merge remote-tracking branch 'parallax/master'

Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
This commit is contained in:
Matt Liberty 2024-10-02 17:09:40 +00:00
commit fb88fe8532
55 changed files with 38998 additions and 923 deletions

View File

@ -200,6 +200,7 @@ set(STA_SOURCE
power/Power.cc
power/ReadVcdActivities.cc
power/SaifReader.cc
power/Vcd.cc
power/VcdReader.cc
@ -308,6 +309,15 @@ bison_target(SdfParser ${STA_HOME}/sdf/SdfParse.yy ${CMAKE_CURRENT_BINARY_DIR}/S
add_flex_bison_dependency(SdfLex SdfParser)
# Saif scan/parse.
flex_target(SaifLex ${STA_HOME}/power/SaifLex.ll ${CMAKE_CURRENT_BINARY_DIR}/SaifLex.cc
COMPILE_FLAGS --prefix=SaifLex_
)
bison_target(SaifParser ${STA_HOME}/power/SaifParse.yy ${CMAKE_CURRENT_BINARY_DIR}/SaifParse.cc
COMPILE_FLAGS --name-prefix=SaifParse_
)
add_flex_bison_dependency(SaifLex SaifParser)
################################################################
set(STA_TCL_INIT ${CMAKE_CURRENT_BINARY_DIR}/StaTclInitVar.cc)
@ -513,6 +523,9 @@ target_sources(OpenSTA
${FLEX_VerilogLex_OUTPUTS}
${BISON_VerilogParser_OUTPUTS}
${FLEX_SaifLex_OUTPUTS}
${BISON_SaifParser_OUTPUTS}
)
target_link_libraries(OpenSTA

View File

@ -130,34 +130,24 @@ The Zlib library is an optional. If CMake finds libz, OpenSTA can
read Liberty, Verilog, SDF, SPF, and SPEF files compressed with gzip.
CUDD is a binary decision diageram (BDD) package that is used to
improve conditional timing arc handling. OpenSTA does not require it
to be installed, but it improves constant propagation, power activity propagation
and spice netlist generation if it is installed.
improve conditional timing arc handling, constant propagation, power
activity propagation and spice netlist generation.
CUDD is available
[here](https://www.davidkebo.com/source/cudd_versions/cudd-3.0.0.tar.gz)
or [here](https://sourceforge.net/projects/cudd-mirror/).
[here](https://github.com/davidkebo/cudd/blob/main/cudd_versions/cudd-3.0.0.tar.gz).
Use the CUDD_DIR option to set the install directory of the CUDD
library if it is not in one of the normal system install directories.
Unpack and build CUDD.
```
cmake -DCUDD_DIR=$HOME/stax/cudd-3.0.0 .."
```
When building CUDD you may use the `--prefix ` option to `configure` to
install in a location other than the default (`/usr/local/lib`).
```
cd $HOME/cudd-3.0.0
mkdir $HOME/cudd
./configure --prefix $HOME/cudd
tar xvfz cudd-3.0.0.tar.gz
cd cudd-3.0.0
./configure
make
make install
cd <opensta>/build
cmake .. -DUSE_CUDD=ON -DCUDD_DIR=$HOME/cudd
```
You can use the "configure --prefix" option and "make install" to install CUDD
in a different directory.
### Installing with CMake
Use the following commands to checkout the git repository and build the
@ -168,7 +158,7 @@ git clone https://github.com/parallaxsw/OpenSTA.git
cd OpenSTA
mkdir build
cd build
cmake ..
cmake -DCUDD_DIR=<CUDD_INSTALL_DIR> ,.
make
```
The default build type is release to compile optimized code.
@ -182,7 +172,7 @@ CMAKE_BUILD_TYPE DEBUG|RELEASE
CMAKE_CXX_FLAGS - additional compiler flags
TCL_LIBRARY - path to tcl library
TCL_HEADER - path to tcl.h
CUDD - path to cudd installation
CUDD_DIR - path to cudd installation
ZLIB_ROOT - path to zlib
CMAKE_INSTALL_PREFIX
```
@ -191,11 +181,7 @@ If `TCL_LIBRARY` is specified the CMake script will attempt to locate
the header from the library path.
The default install directory is `/usr/local`.
To install in a different directory with CMake use:
```
cmake .. -DCMAKE_INSTALL_PREFIX=<prefix_path>
```
To install in a different directory with CMake use the CMAKE_INSTALL_PREFIX option.
If you make changes to `CMakeLists.txt` you may need to clean out
existing CMake cached variable values by deleting all of the

View File

@ -3,7 +3,7 @@ OpenSTA Timing Analyzer Release Notes
This file summarizes user visible changes for each release.
Release 2.6.0 2024/07/??
Release 2.6.0 2024/07/22
-------------------------
The version of c++ used by OpenSTA is now 17.
@ -21,6 +21,15 @@ 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
Release 2.5.0 2024/01/17
-------------------------

View File

@ -1,4 +1,5 @@
Naming conventions
------------------
directory - lowercase (directory)
filename - corresponding class name without prefix (Filename)
@ -105,32 +106,26 @@ pair if the lookup fails. Use map::find or sta::Map::findKey instead.
Avoid nested classes/enums because SWIG has trouble with them.
................................................................
Warning
get_<object> not found
sdf timing arc not found
disabling timing arcs to break loops
virtual clock with no sources (no pins)
invalid endpoint for constrained paths
sdf DESIGN does not match top level cell name
set_input_delay on clk port (deprecation warning)
link cannot resolve reference (module/cell not found)
Regression Tests
................
Errors
cannot open file
file syntax error
cmd illegal command option combinations
cmd extra positional args
cmd unknown keyword option
cmd unknown
sdf pin not found
Tests are run with the tcl script test/regression:
................................................................
Swig notes
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)
C null pointers (zero) turn into "NULL" values in TCL.
Tests log files and results are in test/results. The result/test.log
is compared to test.ok to determine if a test passes.
TCL "NULL" strings turn into NULL (zero) pointers in C.
Test scripts are written in tcl and live in the /test directory.
Compress large liberty, verilog, and spef, files and use existing
libraries to prevent repository bloat.
# TCL lexpr-funcall
eval exec $prog $args
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/<test>.log to test/<test>.okfile.

Binary file not shown.

Binary file not shown.

View File

@ -4,13 +4,14 @@ Warning: 0000 duplicated
Warning: 0000 duplicated
Warning: 0000 duplicated
Warning: 0000 duplicated
0000 LibertyReader.cc:2150 statetable input port %s not found.
0000 LibertyReader.cc:3997 table row must have 3 groups separated by ':'.
0000 LibertyReader.cc:4002 table row has %zu input values but %zu are required.
0000 LibertyReader.cc:4009 table row has %zu current values but %zu are required.
0000 LibertyReader.cc:4016 table row has %zu next values but %zu are required.
0000 LibertyReader.cc:4062 table input value '%s' not recognized.
0000 LibertyReader.cc:4081 table internal value '%s' not recognized.
Warning: 304 duplicated
0000 LibertyReader.cc:2151 statetable input port %s not found.
0000 LibertyReader.cc:4008 table row must have 3 groups separated by ':'.
0000 LibertyReader.cc:4013 table row has %zu input values but %zu are required.
0000 LibertyReader.cc:4020 table row has %zu current values but %zu are required.
0000 LibertyReader.cc:4027 table row has %zu next values but %zu are required.
0000 LibertyReader.cc:4073 table input value '%s' not recognized.
0000 LibertyReader.cc:4092 table internal value '%s' not recognized.
0100 CmdArgs.tcl:108 unsupported object type $object_type.
0101 CmdArgs.tcl:166 object '$obj' not found.
0102 CmdArgs.tcl:414 $corner_arg is not the name of process corner.
@ -104,12 +105,22 @@ Warning: 0000 duplicated
0302 Power.tcl:242 duty should be 0.0 to 1.0
0303 Power.tcl:257 activity cannot be set on clock ports.
0304 Power.tcl:40 No liberty libraries have been read.
0304 Power.tcl:286 read_power_activities is deprecated. Use read_vcd.
0320 Property.tcl:32 $cmd object is null.
0321 Property.tcl:37 $cmd $type_key must be specified with object name argument.
0322 Property.tcl:77 get_property unsupported object type $object_type.
0323 Property.tcl:80 get_property $object is not an object.
0324 Property.tcl:107 $object_type not supported.
0325 Property.tcl:110 $object_type '$object_name' not found.
0326 Sdc.tcl:494 object '$pattern' is not an instance.
0327 Sdc.tcl:542 object '$pattern' is not an clock.
0328 Sdc.tcl:606 object '$pattern' is not a liberty cell.
0329 Sdc.tcl:678 object '$pattern' is not a liberty pin.
0330 Sdc.tcl:757 object '$pattern' is not a liberty library.
0331 Sdc.tcl:856 object '$pattern' is not a net.
0332 Sdc.tcl:936 object '$pattern' is not a pin.
0333 Sdc.tcl:993 object '$pattern' is not a port.
0334 Sdc.tcl:2848 object '$pattern' is not a liberty cell.
0340 Sdc.tcl:73 cannot open '$filename'.
0341 Sdc.tcl:128 incomplete command at end of file.
0342 Sdc.tcl:212 hierarchy separator must be one of '$sdc_dividers'.
@ -118,139 +129,139 @@ Warning: 0000 duplicated
0345 Sdc.tcl:281 $unit scale [format %.0e $scale] does not match library scale [format %.0e $unit_scale].
0346 Sdc.tcl:358 only one of -cells, -data_pins, -clock_pins, -async_pins, -output_pins are suppported.
0347 Sdc.tcl:401 current_design for other than top cell not supported.
0348 Sdc.tcl:467 patterns argument not supported with -of_objects.
0349 Sdc.tcl:500 instance '$pattern' not found.
0350 Sdc.tcl:432 unsupported $object_type -filter expression.
0351 Sdc.tcl:533 clock '$pattern' not found.
0352 Sdc.tcl:562 positional arguments not supported with -of_objects.
0353 Sdc.tcl:589 library '$lib_name' not found.
0354 Sdc.tcl:601 cell '$cell_pattern' not found.
0355 Sdc.tcl:651 library/cell/port '$pattern' not found.
0356 Sdc.tcl:671 port '$port_pattern' not found.
0357 Sdc.tcl:676 library '$lib_name' not found.
0358 Sdc.tcl:689 -nocase ignored without -regexp.
0359 Sdc.tcl:715 library '$pattern' not found.
0360 Sdc.tcl:781 patterns argument not supported with -of_objects.
0361 Sdc.tcl:805 net '$pattern' not found.
0362 Sdc.tcl:837 patterns argument not supported with -of_objects.
0363 Sdc.tcl:874 pin '$pattern' not found.
0365 Sdc.tcl:904 patterns argument not supported with -of_objects.
0366 Sdc.tcl:918 port '$pattern' not found.
0368 Sdc.tcl:957 -add requires -name.
0369 Sdc.tcl:962 -name or port_pin_list must be specified.
0370 Sdc.tcl:970 missing -period argument.
0371 Sdc.tcl:976 -waveform edge_list must have an even number of edge times.
0372 Sdc.tcl:985 non-increasing clock -waveform edge times.
0373 Sdc.tcl:988 -waveform time greater than two periods.
0374 Sdc.tcl:1046 empty ports/pins/nets argument.
0375 Sdc.tcl:1054 -add requires -name.
0376 Sdc.tcl:1059 name or port_pin_list must be specified.
0377 Sdc.tcl:1066 missing -source argument.
0378 Sdc.tcl:1081 -master_clock argument empty.
0379 Sdc.tcl:1084 -add requireds -master_clock.
0380 Sdc.tcl:1088 -multiply_by and -divide_by options are exclusive.
0381 Sdc.tcl:1092 -divide_by is not an integer greater than one.
0382 Sdc.tcl:1095 -combinational implies -divide_by 1.
0383 Sdc.tcl:1100 -multiply_by is not an integer greater than one.
0384 Sdc.tcl:1106 -duty_cycle is not a float between 0 and 100.
0385 Sdc.tcl:1112 -edges only supported for three edges.
0386 Sdc.tcl:1118 edges times are not monotonically increasing.
0387 Sdc.tcl:1127 -edge_shift length does not match -edges length.
0388 Sdc.tcl:1133 missing -multiply_by, -divide_by, -combinational or -edges argument.
0389 Sdc.tcl:1141 cannot specify -invert without -multiply_by, -divide_by or -combinational.
0390 Sdc.tcl:1147 -duty_cycle requires -multiply_by value.
0391 Sdc.tcl:1207 group_path command failed.
0392 Sdc.tcl:1214 positional arguments not supported.
0393 Sdc.tcl:1218 -from, -through or -to required.
0394 Sdc.tcl:1224 -name and -default are mutually exclusive.
0395 Sdc.tcl:1226 -name or -default option is required.
0396 Sdc.tcl:1267 cannot specify both -high and -low.
0397 Sdc.tcl:1275 missing -setup or -hold argument.
0398 Sdc.tcl:1289 -high and -low only permitted for pins and instances.
0399 Sdc.tcl:1296 -high and -low only permitted for pins and instances.
0400 Sdc.tcl:1339 one of -logically_exclusive, -physically_exclusive or -asynchronous is required.
0401 Sdc.tcl:1342 the keywords -logically_exclusive, -physically_exclusive and -asynchronous are mutually exclusive.
0402 Sdc.tcl:1361 unknown keyword argument $arg.
0403 Sdc.tcl:1363 extra positional argument $arg.
0404 Sdc.tcl:1392 the -all and -name options are mutually exclusive.
0405 Sdc.tcl:1395 either -all or -name options must be specified.
0406 Sdc.tcl:1403 one of -logically_exclusive, -physically_exclusive or -asynchronous is required.
0407 Sdc.tcl:1406 the keywords -logically_exclusive, -physically_exclusive and -asynchronous are mutually exclusive.
0408 Sdc.tcl:1456 -clock ignored for clock objects.
0409 Sdc.tcl:1470 -source '[get_full_name $pin]' is not a clock pin.
0410 Sdc.tcl:1477 -early/-late is only allowed with -source.
0411 Sdc.tcl:1506 -clock ignored for clock objects.
0412 Sdc.tcl:1518 -source '[$pin path_name]' is not a clock pin.
0413 Sdc.tcl:1546 set_sense -type data not supported.
0414 Sdc.tcl:1550 set_sense -type clock|data
0415 Sdc.tcl:1561 set_clock_sense is deprecated as of SDC 2.1. Use set_sense -type clock.
0416 Sdc.tcl:1573 -pulse argument not supported.
0417 Sdc.tcl:1582 -positive, -negative, -stop_propagation and -pulse are mutually exclusive.
0418 Sdc.tcl:1595 hierarchical pin '[get_full_name $pin]' not supported.
0419 Sdc.tcl:1619 transition time can not be specified for virtual clocks.
0420 Sdc.tcl:1652 missing uncertainty value.
0421 Sdc.tcl:1700 -from/-to must be used together.
0422 Sdc.tcl:1720 -rise, -fall options not allowed for single clock uncertainty.
0423 Sdc.tcl:1786 -from/-to must be used together.
0424 Sdc.tcl:1806 -rise, -fall options not allowed for single clock uncertainty.
0425 Sdc.tcl:1847 missing -from, -rise_from or -fall_from argument.
0426 Sdc.tcl:1859 missing -to, -rise_to or -fall_to argument.
0427 Sdc.tcl:1907 missing -from, -rise_from or -fall_from argument.
0428 Sdc.tcl:1919 missing -to, -rise_to or -fall_to argument.
0429 Sdc.tcl:1961 -from/-to keywords ignored for lib_pin, port and pin arguments.
0430 Sdc.tcl:1991 -from/-to hierarchical instance not supported.
0431 Sdc.tcl:2023 pin '[get_full_name $inst]${hierarchy_separator}${port_name}' not found.
0432 Sdc.tcl:2080 pin '[get_name $cell]${hierarchy_separator}${port_name}' not found.
0434 Sdc.tcl:2114 -from/-to keywords ignored for lib_pin, port and pin arguments.
0435 Sdc.tcl:2166 -from/-to hierarchical instance not supported.
0436 Sdc.tcl:2220 '$args' ignored.
0437 Sdc.tcl:2224 -from, -through or -to required.
0438 Sdc.tcl:2303 -source_latency_included ignored with -reference_pin.
0439 Sdc.tcl:2306 -network_latency_included ignored with -reference_pin.
0440 Sdc.tcl:2325 $cmd not allowed on [pin_direction $pin] port '[get_full_name $pin]'.
0441 Sdc.tcl:2327 $cmd relative to a clock defined on the same port/pin not allowed.
0442 Sdc.tcl:2375 missing delay argument.
0443 Sdc.tcl:2381 '$args' ignored.
0444 Sdc.tcl:2506 missing path multiplier argument.
0445 Sdc.tcl:2511 '$args' ignored.
0446 Sdc.tcl:2518 cannot use -start with -end.
0447 Sdc.tcl:2568 $cmd command failed.
0448 Sdc.tcl:2575 positional arguments not supported.
0449 Sdc.tcl:2579 -from, -through or -to required.
0450 Sdc.tcl:2646 virtual clock [get_name $clk] can not be propagated.
0451 Sdc.tcl:2688 value must be 0, zero, 1, one, rise, rising, fall, or falling.
0452 Sdc.tcl:2757 cell '$lib_name:$cell_name' not found.
0453 Sdc.tcl:2763 '$cell_name' not found.
0454 Sdc.tcl:2767 missing -lib_cell argument.
0455 Sdc.tcl:2775 port '$to_port_name' not found.
0456 Sdc.tcl:2787 -pin argument required for cells with multiple outputs.
0457 Sdc.tcl:2802 port '$from_port_name' not found.
0458 Sdc.tcl:2820 -multiply_by ignored.
0459 Sdc.tcl:2823 -dont_scale ignored.
0460 Sdc.tcl:2826 -no_design_rule ignored.
0461 Sdc.tcl:2849 set_fanout_load not supported.
0462 Sdc.tcl:2873 -clock not supported.
0463 Sdc.tcl:2876 -clock_fall not supported.
0464 Sdc.tcl:2926 -pin_load not allowed for net objects.
0465 Sdc.tcl:2929 -wire_load not allowed for net objects.
0466 Sdc.tcl:2932 -rise/-fall not allowed for net objects.
0467 Sdc.tcl:3019 port '[get_name $port]' is not an input.
0468 Sdc.tcl:3065 -data_path, -clock_path, -rise, -fall ignored for ports and designs.
0469 Sdc.tcl:3136 derating factor greater than 2.0.
0470 Sdc.tcl:3173 -cell_delay and -cell_check flags ignored for net objects.
0471 Sdc.tcl:3243 no valid objects specified for $key.
0472 Sdc.tcl:3276 no valid objects specified for $key
0473 Sdc.tcl:3325 no valid objects specified for $key.
0474 Sdc.tcl:3393 operating condition '$op_cond_name' not found.
0475 Sdc.tcl:3411 operating condition '$op_cond_name' not found.
0476 Sdc.tcl:3425 -analysis_type must be single, bc_wc or on_chip_variation.
0477 Sdc.tcl:3437 set_wire_load_min_block_size not supported.
0478 Sdc.tcl:3450 mode must be top, enclosed or segmented.
0479 Sdc.tcl:3465 no wire load model specified.
0480 Sdc.tcl:3487 wire load model '$model_name' not found.
0481 Sdc.tcl:3526 wire load selection group '$selection_name' not found.
0482 Sdc.tcl:3614 define_corners must be called before read_liberty.
0500 Sdc.tcl:3687 no default operating conditions found.
0348 Sdc.tcl:468 patterns argument not supported with -of_objects.
0349 Sdc.tcl:507 instance '$pattern' not found.
0350 Sdc.tcl:429 unsupported $object_type -filter expression.
0351 Sdc.tcl:551 clock '$pattern' not found.
0352 Sdc.tcl:581 positional arguments not supported with -of_objects.
0353 Sdc.tcl:618 library '$lib_name' not found.
0354 Sdc.tcl:630 cell '$cell_pattern' not found.
0355 Sdc.tcl:691 library/cell/port '$pattern' not found.
0356 Sdc.tcl:711 port '$port_pattern' not found.
0357 Sdc.tcl:716 library '$lib_name' not found.
0358 Sdc.tcl:730 -nocase ignored without -regexp.
0359 Sdc.tcl:766 library '$pattern' not found.
0360 Sdc.tcl:837 patterns argument not supported with -of_objects.
0361 Sdc.tcl:867 net '$pattern' not found.
0362 Sdc.tcl:900 patterns argument not supported with -of_objects.
0363 Sdc.tcl:947 pin '$pattern' not found.
0365 Sdc.tcl:982 patterns argument not supported with -of_objects.
0366 Sdc.tcl:1002 port '$pattern' not found.
0368 Sdc.tcl:1042 -add requires -name.
0369 Sdc.tcl:1047 -name or port_pin_list must be specified.
0370 Sdc.tcl:1055 missing -period argument.
0371 Sdc.tcl:1061 -waveform edge_list must have an even number of edge times.
0372 Sdc.tcl:1070 non-increasing clock -waveform edge times.
0373 Sdc.tcl:1073 -waveform time greater than two periods.
0374 Sdc.tcl:1131 empty ports/pins/nets argument.
0375 Sdc.tcl:1139 -add requires -name.
0376 Sdc.tcl:1144 name or port_pin_list must be specified.
0377 Sdc.tcl:1151 missing -source argument.
0378 Sdc.tcl:1166 -master_clock argument empty.
0379 Sdc.tcl:1169 -add requireds -master_clock.
0380 Sdc.tcl:1173 -multiply_by and -divide_by options are exclusive.
0381 Sdc.tcl:1177 -divide_by is not an integer greater than one.
0382 Sdc.tcl:1180 -combinational implies -divide_by 1.
0383 Sdc.tcl:1185 -multiply_by is not an integer greater than one.
0384 Sdc.tcl:1191 -duty_cycle is not a float between 0 and 100.
0385 Sdc.tcl:1197 -edges only supported for three edges.
0386 Sdc.tcl:1203 edges times are not monotonically increasing.
0387 Sdc.tcl:1212 -edge_shift length does not match -edges length.
0388 Sdc.tcl:1218 missing -multiply_by, -divide_by, -combinational or -edges argument.
0389 Sdc.tcl:1226 cannot specify -invert without -multiply_by, -divide_by or -combinational.
0390 Sdc.tcl:1232 -duty_cycle requires -multiply_by value.
0391 Sdc.tcl:1292 group_path command failed.
0392 Sdc.tcl:1299 positional arguments not supported.
0393 Sdc.tcl:1303 -from, -through or -to required.
0394 Sdc.tcl:1309 -name and -default are mutually exclusive.
0395 Sdc.tcl:1311 -name or -default option is required.
0396 Sdc.tcl:1352 cannot specify both -high and -low.
0397 Sdc.tcl:1360 missing -setup or -hold argument.
0398 Sdc.tcl:1374 -high and -low only permitted for pins and instances.
0399 Sdc.tcl:1381 -high and -low only permitted for pins and instances.
0400 Sdc.tcl:1424 one of -logically_exclusive, -physically_exclusive or -asynchronous is required.
0401 Sdc.tcl:1427 the keywords -logically_exclusive, -physically_exclusive and -asynchronous are mutually exclusive.
0402 Sdc.tcl:1446 unknown keyword argument $arg.
0403 Sdc.tcl:1448 extra positional argument $arg.
0404 Sdc.tcl:1477 the -all and -name options are mutually exclusive.
0405 Sdc.tcl:1480 either -all or -name options must be specified.
0406 Sdc.tcl:1488 one of -logically_exclusive, -physically_exclusive or -asynchronous is required.
0407 Sdc.tcl:1491 the keywords -logically_exclusive, -physically_exclusive and -asynchronous are mutually exclusive.
0408 Sdc.tcl:1541 -clock ignored for clock objects.
0409 Sdc.tcl:1555 -source '[get_full_name $pin]' is not a clock pin.
0410 Sdc.tcl:1562 -early/-late is only allowed with -source.
0411 Sdc.tcl:1591 -clock ignored for clock objects.
0412 Sdc.tcl:1603 -source '[$pin path_name]' is not a clock pin.
0413 Sdc.tcl:1631 set_sense -type data not supported.
0414 Sdc.tcl:1635 set_sense -type clock|data
0415 Sdc.tcl:1646 set_clock_sense is deprecated as of SDC 2.1. Use set_sense -type clock.
0416 Sdc.tcl:1658 -pulse argument not supported.
0417 Sdc.tcl:1667 -positive, -negative, -stop_propagation and -pulse are mutually exclusive.
0418 Sdc.tcl:1680 hierarchical pin '[get_full_name $pin]' not supported.
0419 Sdc.tcl:1704 transition time can not be specified for virtual clocks.
0420 Sdc.tcl:1737 missing uncertainty value.
0421 Sdc.tcl:1785 -from/-to must be used together.
0422 Sdc.tcl:1805 -rise, -fall options not allowed for single clock uncertainty.
0423 Sdc.tcl:1871 -from/-to must be used together.
0424 Sdc.tcl:1891 -rise, -fall options not allowed for single clock uncertainty.
0425 Sdc.tcl:1932 missing -from, -rise_from or -fall_from argument.
0426 Sdc.tcl:1944 missing -to, -rise_to or -fall_to argument.
0427 Sdc.tcl:1992 missing -from, -rise_from or -fall_from argument.
0428 Sdc.tcl:2004 missing -to, -rise_to or -fall_to argument.
0429 Sdc.tcl:2046 -from/-to keywords ignored for lib_pin, port and pin arguments.
0430 Sdc.tcl:2076 -from/-to hierarchical instance not supported.
0431 Sdc.tcl:2108 pin '[get_full_name $inst]${hierarchy_separator}${port_name}' not found.
0432 Sdc.tcl:2165 pin '[get_name $cell]${hierarchy_separator}${port_name}' not found.
0434 Sdc.tcl:2199 -from/-to keywords ignored for lib_pin, port and pin arguments.
0435 Sdc.tcl:2251 -from/-to hierarchical instance not supported.
0436 Sdc.tcl:2305 '$args' ignored.
0437 Sdc.tcl:2309 -from, -through or -to required.
0438 Sdc.tcl:2388 -source_latency_included ignored with -reference_pin.
0439 Sdc.tcl:2391 -network_latency_included ignored with -reference_pin.
0440 Sdc.tcl:2410 $cmd not allowed on [pin_direction $pin] port '[get_full_name $pin]'.
0441 Sdc.tcl:2412 $cmd relative to a clock defined on the same port/pin not allowed.
0442 Sdc.tcl:2460 missing delay argument.
0443 Sdc.tcl:2466 '$args' ignored.
0444 Sdc.tcl:2591 missing path multiplier argument.
0445 Sdc.tcl:2596 '$args' ignored.
0446 Sdc.tcl:2603 cannot use -start with -end.
0447 Sdc.tcl:2653 $cmd command failed.
0448 Sdc.tcl:2660 positional arguments not supported.
0449 Sdc.tcl:2664 -from, -through or -to required.
0450 Sdc.tcl:2731 virtual clock [get_name $clk] can not be propagated.
0451 Sdc.tcl:2773 value must be 0, zero, 1, one, rise, rising, fall, or falling.
0452 Sdc.tcl:2842 cell '$lib_name:$cell_name' not found.
0453 Sdc.tcl:2855 '$cell_name' not found.
0454 Sdc.tcl:2859 missing -lib_cell argument.
0455 Sdc.tcl:2867 port '$to_port_name' not found.
0456 Sdc.tcl:2879 -pin argument required for cells with multiple outputs.
0457 Sdc.tcl:2894 port '$from_port_name' not found.
0458 Sdc.tcl:2912 -multiply_by ignored.
0459 Sdc.tcl:2915 -dont_scale ignored.
0460 Sdc.tcl:2918 -no_design_rule ignored.
0461 Sdc.tcl:2941 set_fanout_load not supported.
0462 Sdc.tcl:2965 -clock not supported.
0463 Sdc.tcl:2968 -clock_fall not supported.
0464 Sdc.tcl:3018 -pin_load not allowed for net objects.
0465 Sdc.tcl:3021 -wire_load not allowed for net objects.
0466 Sdc.tcl:3024 -rise/-fall not allowed for net objects.
0467 Sdc.tcl:3111 port '[get_name $port]' is not an input.
0468 Sdc.tcl:3157 -data_path, -clock_path, -rise, -fall ignored for ports and designs.
0469 Sdc.tcl:3228 derating factor greater than 2.0.
0470 Sdc.tcl:3265 -cell_delay and -cell_check flags ignored for net objects.
0471 Sdc.tcl:3335 no valid objects specified for $key.
0472 Sdc.tcl:3368 no valid objects specified for $key
0473 Sdc.tcl:3417 no valid objects specified for $key.
0474 Sdc.tcl:3485 operating condition '$op_cond_name' not found.
0475 Sdc.tcl:3503 operating condition '$op_cond_name' not found.
0476 Sdc.tcl:3517 -analysis_type must be single, bc_wc or on_chip_variation.
0477 Sdc.tcl:3529 set_wire_load_min_block_size not supported.
0478 Sdc.tcl:3542 mode must be top, enclosed or segmented.
0479 Sdc.tcl:3557 no wire load model specified.
0480 Sdc.tcl:3579 wire load model '$model_name' not found.
0481 Sdc.tcl:3618 wire load selection group '$selection_name' not found.
0482 Sdc.tcl:3706 define_corners must be called before read_liberty.
0500 Sdc.tcl:3779 no default operating conditions found.
0501 Sdc.tcl:259 incorrect unit suffix '$arg_suffix'.
0510 Search.tcl:136 $cmd -path_delay must be min, min_rise, min_fall, max, max_rise, max_fall or min_max.
0511 Search.tcl:146 $cmd command failed.
@ -284,7 +295,7 @@ Warning: 0000 duplicated
0574 Util.tcl:305 $cmd_arg '$arg' is not a positive integer.
0575 Util.tcl:311 $cmd_arg '$arg' is not an integer greater than or equal to one.
0576 Util.tcl:317 $cmd_arg '$arg' is not between 0 and 100.
0577 Sdc.tcl:3617 define_corners must define at least one corner.
0577 Sdc.tcl:3709 define_corners must define at least one corner.
0590 Variables.tcl:37 sta_report_default_digits must be a positive integer.
0591 Variables.tcl:62 sta_crpr_mode must be pin or transition.
0592 Variables.tcl:179 $var_name value must be 0 or 1.
@ -302,180 +313,180 @@ Warning: 0000 duplicated
1041 DmpCeff.cc:1536 cell %s delay model not supported on SPF parasitics by DMP delay calculator
1060 Genclks.cc:275 no master clock found for generated clock %s.
1062 Genclks.cc:939 generated clock %s source pin %s missing paths from master clock %s.
1100 Power.cc:555 unknown cudd constant
1110 Liberty.cc:762 cell %s/%s port %s not found in cell %s/%s.
1111 Liberty.cc:788 cell %s/%s %s -> %s timing group %s not found in cell %s/%s.
1112 Liberty.cc:807 Liberty cell %s/%s for corner %s/%s not found.
1113 Liberty.cc:1818 cell %s/%s %s -> %s latch enable %s_edge is inconsistent with %s -> %s setup_%s check.
1114 Liberty.cc:1759 cell %s/%s %s -> %s latch enable %s_edge is inconsistent with latch group enable function positive sense.
1115 Liberty.cc:1767 cell %s/%s %s -> %s latch enable %s_edge is inconsistent with latch group enable function negative sense.
1116 Liberty.cc:361 unsupported slew degradation table axes
1117 Liberty.cc:377 unsupported slew degradation table axes
1118 Liberty.cc:382 unsupported slew degradation table order
1119 Liberty.cc:412 unsupported slew degradation table axes
1120 Liberty.cc:1970 library missing vdd
1121 Liberty.cc:1385 timing arc count mismatch
1100 Power.cc:556 unknown cudd constant
1110 Liberty.cc:763 cell %s/%s port %s not found in cell %s/%s.
1111 Liberty.cc:789 cell %s/%s %s -> %s timing group %s not found in cell %s/%s.
1112 Liberty.cc:808 Liberty cell %s/%s for corner %s/%s not found.
1113 Liberty.cc:1822 cell %s/%s %s -> %s latch enable %s_edge is inconsistent with %s -> %s setup_%s check.
1114 Liberty.cc:1763 cell %s/%s %s -> %s latch enable %s_edge is inconsistent with latch group enable function positive sense.
1115 Liberty.cc:1771 cell %s/%s %s -> %s latch enable %s_edge is inconsistent with latch group enable function negative sense.
1116 Liberty.cc:362 unsupported slew degradation table axes
1117 Liberty.cc:378 unsupported slew degradation table axes
1118 Liberty.cc:383 unsupported slew degradation table order
1119 Liberty.cc:413 unsupported slew degradation table axes
1120 Liberty.cc:1977 library missing vdd
1121 Liberty.cc:1389 timing arc count mismatch
1125 LibertyParser.cc:310 valueIterator called for LibertySimpleAttribute
1126 LibertyParser.cc:390 LibertyStringAttrValue called for float value
1127 LibertyParser.cc:420 LibertyStringAttrValue called for float value
1130 LibertyExpr.cc:82 %s references unknown port %s.
1131 LibertyExpr.cc:175 %s %s.
1140 LibertyReader.cc:616 library %s already exists.
1141 LibertyReader.cc:650 library missing name.
1142 LibertyReader.cc:676 default_wire_load %s not found.
1143 LibertyReader.cc:687 default_wire_selection %s not found.
1144 LibertyReader.cc:699 default_operating_condition %s not found.
1145 LibertyReader.cc:709 input_threshold_pct_%s not found.
1146 LibertyReader.cc:713 output_threshold_pct_%s not found.
1147 LibertyReader.cc:717 slew_lower_threshold_pct_%s not found.
1148 LibertyReader.cc:721 slew_upper_threshold_pct_%s not found.
1149 LibertyReader.cc:726 Library %s is missing one or more thresholds.
1150 LibertyReader.cc:805 unknown unit multiplier %s.
1151 LibertyReader.cc:828 unknown unit scale %c.
1152 LibertyReader.cc:831 unknown unit suffix %s.
1153 LibertyReader.cc:834 unknown unit suffix %s.
1154 LibertyReader.cc:859 capacitive_load_units are not ff or pf.
1155 LibertyReader.cc:862 capacitive_load_units are not a string.
1156 LibertyReader.cc:865 capacitive_load_units missing suffix.
1157 LibertyReader.cc:868 capacitive_load_units scale is not a float.
1158 LibertyReader.cc:871 capacitive_load_units missing scale and suffix.
1159 LibertyReader.cc:874 capacitive_load_unit missing values suffix.
1160 LibertyReader.cc:892 delay_model %s not supported.
1161 LibertyReader.cc:896 delay_model %s not supported.
1162 LibertyReader.cc:900 delay_model %s not supported.
1163 LibertyReader.cc:905 delay_model %s not supported.
1140 LibertyReader.cc:617 library %s already exists.
1141 LibertyReader.cc:651 library missing name.
1142 LibertyReader.cc:677 default_wire_load %s not found.
1143 LibertyReader.cc:688 default_wire_selection %s not found.
1144 LibertyReader.cc:700 default_operating_condition %s not found.
1145 LibertyReader.cc:710 input_threshold_pct_%s not found.
1146 LibertyReader.cc:714 output_threshold_pct_%s not found.
1147 LibertyReader.cc:718 slew_lower_threshold_pct_%s not found.
1148 LibertyReader.cc:722 slew_upper_threshold_pct_%s not found.
1149 LibertyReader.cc:727 Library %s is missing one or more thresholds.
1150 LibertyReader.cc:806 unknown unit multiplier %s.
1151 LibertyReader.cc:829 unknown unit scale %c.
1152 LibertyReader.cc:832 unknown unit suffix %s.
1153 LibertyReader.cc:835 unknown unit suffix %s.
1154 LibertyReader.cc:860 capacitive_load_units are not ff or pf.
1155 LibertyReader.cc:863 capacitive_load_units are not a string.
1156 LibertyReader.cc:866 capacitive_load_units missing suffix.
1157 LibertyReader.cc:869 capacitive_load_units scale is not a float.
1158 LibertyReader.cc:872 capacitive_load_units missing scale and suffix.
1159 LibertyReader.cc:875 capacitive_load_unit missing values suffix.
1160 LibertyReader.cc:893 delay_model %s not supported.
1161 LibertyReader.cc:897 delay_model %s not supported.
1162 LibertyReader.cc:901 delay_model %s not supported.
1163 LibertyReader.cc:906 delay_model %s not supported.
.
1164 LibertyReader.cc:908 unknown delay_model %s
1164 LibertyReader.cc:909 unknown delay_model %s
.
1165 LibertyReader.cc:927 unknown bus_naming_style format.
1166 LibertyReader.cc:948 voltage_map voltage is not a float.
1167 LibertyReader.cc:951 voltage_map missing voltage.
1168 LibertyReader.cc:954 voltage_map supply name is not a string.
1169 LibertyReader.cc:957 voltage_map missing supply name and voltage.
1170 LibertyReader.cc:960 voltage_map missing values suffix.
1171 LibertyReader.cc:1045 default_max_transition is 0.0.
1172 LibertyReader.cc:1060 default_max_fanout is 0.0.
1173 LibertyReader.cc:1150 default_fanout_load is 0.0.
1174 LibertyReader.cc:1178 default_wire_load_mode %s not found.
1175 LibertyReader.cc:1349 table template missing name.
1176 LibertyReader.cc:1394 missing variable_%d attribute.
1177 LibertyReader.cc:1470 missing table index values.
1178 LibertyReader.cc:1476 non-increasing table index values.
1179 LibertyReader.cc:1508 bus type %s missing bit_from.
1180 LibertyReader.cc:1510 bus type %s missing bit_to.
1181 LibertyReader.cc:1514 type missing name.
1182 LibertyReader.cc:1541 scaling_factors do not have a name.
1183 LibertyReader.cc:1710 operating_conditions missing name.
1184 LibertyReader.cc:1781 wire_load missing name.
1185 LibertyReader.cc:1824 fanout_length is missing length and fanout.
1186 LibertyReader.cc:1839 wire_load_selection missing name.
1187 LibertyReader.cc:1870 wireload %s not found.
1189 LibertyReader.cc:1877 wire_load_from_area min not a float.
1190 LibertyReader.cc:1880 wire_load_from_area max not a float.
1191 LibertyReader.cc:1883 wire_load_from_area missing parameters.
1192 LibertyReader.cc:1886 wire_load_from_area missing parameters.
1193 LibertyReader.cc:1905 cell missing name.
1194 LibertyReader.cc:1929 cell %s ocv_derate_group %s not found.
1195 LibertyReader.cc:1962 port %s function size does not match port size.
1196 LibertyReader.cc:2059 %s %s bus width mismatch.
1197 LibertyReader.cc:2070 %s %s bus width mismatch.
1198 LibertyReader.cc:2080 clear
1199 LibertyReader.cc:2090 preset
1200 LibertyReader.cc:2126 latch enable function is non-unate for port %s.
1201 LibertyReader.cc:2131 latch enable function is unknown for port %s.
1202 LibertyReader.cc:2232 operating conditions %s not found.
1203 LibertyReader.cc:2235 scaled_cell missing operating condition.
1204 LibertyReader.cc:2238 scaled_cell cell %s has not been defined.
1205 LibertyReader.cc:2241 scaled_cell missing name.
1206 LibertyReader.cc:2267 scaled_cell %s, %s port functions do not match cell port functions.
1207 LibertyReader.cc:2272 scaled_cell ports do not match cell ports.
1208 LibertyReader.cc:2274 scaled_cell %s, %s timing does not match cell timing.
1209 LibertyReader.cc:2293 combinational timing to an input port.
1210 LibertyReader.cc:2388 missing %s_transition.
1211 LibertyReader.cc:2390 missing cell_%s.
1212 LibertyReader.cc:2411 timing group from output port.
1213 LibertyReader.cc:2421 timing group from output port.
1214 LibertyReader.cc:2431 timing group from output port.
1215 LibertyReader.cc:2466 timing group from output port.
1217 LibertyReader.cc:2476 timing group from output port.
1218 LibertyReader.cc:2577 receiver_capacitance group not in timing or pin group.
1219 LibertyReader.cc:2595 unsupported model axis.
1220 LibertyReader.cc:2623 output_current_%s group not in timing group.
1221 LibertyReader.cc:2665 output current waveform %.2e %.2e not found.
1222 LibertyReader.cc:2686 unsupported model axis.
1223 LibertyReader.cc:2728 vector index_1 and index_2 must have exactly one value.
1224 LibertyReader.cc:2730 vector reference_time not found.
1225 LibertyReader.cc:2763 normalized_driver_waveform variable_2 must be normalized_voltage
1226 LibertyReader.cc:2766 normalized_driver_waveform variable_1 must be input_net_transition
1228 LibertyReader.cc:2988 level_shifter_type must be HL, LH, or HL_LH
1229 LibertyReader.cc:3024 switch_cell_type must be coarse_grain or fine_grain
1230 LibertyReader.cc:3048 scaling_factors %s not found.
1231 LibertyReader.cc:3089 pin name is not a string.
1232 LibertyReader.cc:3106 pin name is not a string.
1233 LibertyReader.cc:3120 pin name is not a string.
1234 LibertyReader.cc:3198 bus %s bus_type not found.
1235 LibertyReader.cc:3250 bus_type %s not found.
1236 LibertyReader.cc:3253 bus_type is not a string.
1237 LibertyReader.cc:3271 bundle %s member not found.
1238 LibertyReader.cc:3294 member is not a string.
1239 LibertyReader.cc:3301 members attribute is missing values.
1240 LibertyReader.cc:3352 unknown port direction.
1241 LibertyReader.cc:3599 max_transition is 0.0.
1242 LibertyReader.cc:3705 pulse_latch unknown pulse type.
1243 LibertyReader.cc:4123 timing group missing related_pin/related_bus_pin.
1244 LibertyReader.cc:4222 unknown timing_type %s.
1245 LibertyReader.cc:4242 unknown timing_sense %s.
1246 LibertyReader.cc:4282 mode value is not a string.
1247 LibertyReader.cc:4285 missing mode value.
1248 LibertyReader.cc:4288 mode name is not a string.
1249 LibertyReader.cc:4291 mode missing values.
1250 LibertyReader.cc:4294 mode missing mode name and value.
1251 LibertyReader.cc:4370 unsupported model axis.
1252 LibertyReader.cc:4397 unsupported model axis.
1253 LibertyReader.cc:4426 unsupported model axis.
1254 LibertyReader.cc:4461 unsupported model axis.
1255 LibertyReader.cc:4477 %s group not in timing group.
1256 LibertyReader.cc:4516 table template %s not found.
1257 LibertyReader.cc:4600 %s is missing values.
1258 LibertyReader.cc:4623 %s is not a list of floats.
1259 LibertyReader.cc:4625 table row has %u columns but axis has %d.
1260 LibertyReader.cc:4635 table has %u rows but axis has %d.
1261 LibertyReader.cc:4686 lut output is not a string.
1262 LibertyReader.cc:4703 cell %s test_cell redefinition.
1263 LibertyReader.cc:4728 mode definition missing name.
1264 LibertyReader.cc:4745 mode value missing name.
1265 LibertyReader.cc:4759 when attribute inside table model.
1266 LibertyReader.cc:4808 %s attribute is not a string.
1267 LibertyReader.cc:4811 %s is not a simple attribute.
1268 LibertyReader.cc:4831 %s attribute is not an integer.
1269 LibertyReader.cc:4834 %s is not a simple attribute.
1270 LibertyReader.cc:4847 %s is not a simple attribute.
1271 LibertyReader.cc:4873 %s value %s is not a float.
1272 LibertyReader.cc:4902 %s missing values.
1273 LibertyReader.cc:4906 %s missing values.
1274 LibertyReader.cc:4909 %s is not a complex attribute.
1275 LibertyReader.cc:4935 %s is not a float.
1276 LibertyReader.cc:4958 %s is missing values.
1277 LibertyReader.cc:4961 %s has more than one string.
1278 LibertyReader.cc:4970 %s is missing values.
1279 LibertyReader.cc:4995 %s attribute is not boolean.
1280 LibertyReader.cc:4998 %s attribute is not boolean.
1281 LibertyReader.cc:5001 %s is not a simple attribute.
1282 LibertyReader.cc:5017 attribute %s value %s not recognized.
1283 LibertyReader.cc:5048 unknown early/late value.
1284 LibertyReader.cc:5268 OCV derate group named %s not found.
1285 LibertyReader.cc:5284 ocv_derate missing name.
1286 LibertyReader.cc:5337 unknown rise/fall.
1287 LibertyReader.cc:5357 unknown derate type.
1288 LibertyReader.cc:5389 unsupported model axis.
1289 LibertyReader.cc:5421 unsupported model axis.
1290 LibertyReader.cc:5453 unsupported model axis.
1291 LibertyReader.cc:5524 unknown pg_type.
1292 LibertyReader.cc:5938 port %s subscript out of range.
1293 LibertyReader.cc:5942 port range %s of non-bus port %s.
1294 LibertyReader.cc:5956 port %s not found.
1295 LibertyReader.cc:6026 port %s not found.
1297 LibertyReader.cc:1436 axis type %s not supported.
1165 LibertyReader.cc:928 unknown bus_naming_style format.
1166 LibertyReader.cc:949 voltage_map voltage is not a float.
1167 LibertyReader.cc:952 voltage_map missing voltage.
1168 LibertyReader.cc:955 voltage_map supply name is not a string.
1169 LibertyReader.cc:958 voltage_map missing supply name and voltage.
1170 LibertyReader.cc:961 voltage_map missing values suffix.
1171 LibertyReader.cc:1046 default_max_transition is 0.0.
1172 LibertyReader.cc:1061 default_max_fanout is 0.0.
1173 LibertyReader.cc:1151 default_fanout_load is 0.0.
1174 LibertyReader.cc:1179 default_wire_load_mode %s not found.
1175 LibertyReader.cc:1350 table template missing name.
1176 LibertyReader.cc:1395 missing variable_%d attribute.
1177 LibertyReader.cc:1471 missing table index values.
1178 LibertyReader.cc:1477 non-increasing table index values.
1179 LibertyReader.cc:1509 bus type %s missing bit_from.
1180 LibertyReader.cc:1511 bus type %s missing bit_to.
1181 LibertyReader.cc:1515 type missing name.
1182 LibertyReader.cc:1542 scaling_factors do not have a name.
1183 LibertyReader.cc:1711 operating_conditions missing name.
1184 LibertyReader.cc:1782 wire_load missing name.
1185 LibertyReader.cc:1825 fanout_length is missing length and fanout.
1186 LibertyReader.cc:1840 wire_load_selection missing name.
1187 LibertyReader.cc:1871 wireload %s not found.
1189 LibertyReader.cc:1878 wire_load_from_area min not a float.
1190 LibertyReader.cc:1881 wire_load_from_area max not a float.
1191 LibertyReader.cc:1884 wire_load_from_area missing parameters.
1192 LibertyReader.cc:1887 wire_load_from_area missing parameters.
1193 LibertyReader.cc:1906 cell missing name.
1194 LibertyReader.cc:1930 cell %s ocv_derate_group %s not found.
1195 LibertyReader.cc:1963 port %s function size does not match port size.
1196 LibertyReader.cc:2060 %s %s bus width mismatch.
1197 LibertyReader.cc:2071 %s %s bus width mismatch.
1198 LibertyReader.cc:2081 clear
1199 LibertyReader.cc:2091 preset
1200 LibertyReader.cc:2127 latch enable function is non-unate for port %s.
1201 LibertyReader.cc:2132 latch enable function is unknown for port %s.
1202 LibertyReader.cc:2233 operating conditions %s not found.
1203 LibertyReader.cc:2236 scaled_cell missing operating condition.
1204 LibertyReader.cc:2239 scaled_cell cell %s has not been defined.
1205 LibertyReader.cc:2242 scaled_cell missing name.
1206 LibertyReader.cc:2268 scaled_cell %s, %s port functions do not match cell port functions.
1207 LibertyReader.cc:2273 scaled_cell ports do not match cell ports.
1208 LibertyReader.cc:2275 scaled_cell %s, %s timing does not match cell timing.
1209 LibertyReader.cc:2294 combinational timing to an input port.
1210 LibertyReader.cc:2389 missing %s_transition.
1211 LibertyReader.cc:2391 missing cell_%s.
1212 LibertyReader.cc:2412 timing group from output port.
1213 LibertyReader.cc:2422 timing group from output port.
1214 LibertyReader.cc:2432 timing group from output port.
1215 LibertyReader.cc:2467 timing group from output port.
1217 LibertyReader.cc:2477 timing group from output port.
1218 LibertyReader.cc:2578 receiver_capacitance group not in timing or pin group.
1219 LibertyReader.cc:2596 unsupported model axis.
1220 LibertyReader.cc:2624 output_current_%s group not in timing group.
1221 LibertyReader.cc:2666 output current waveform %.2e %.2e not found.
1222 LibertyReader.cc:2687 unsupported model axis.
1223 LibertyReader.cc:2729 vector index_1 and index_2 must have exactly one value.
1224 LibertyReader.cc:2731 vector reference_time not found.
1225 LibertyReader.cc:2764 normalized_driver_waveform variable_2 must be normalized_voltage
1226 LibertyReader.cc:2767 normalized_driver_waveform variable_1 must be input_net_transition
1228 LibertyReader.cc:2989 level_shifter_type must be HL, LH, or HL_LH
1229 LibertyReader.cc:3025 switch_cell_type must be coarse_grain or fine_grain
1230 LibertyReader.cc:3049 scaling_factors %s not found.
1231 LibertyReader.cc:3100 pin name is not a string.
1232 LibertyReader.cc:3117 pin name is not a string.
1233 LibertyReader.cc:3131 pin name is not a string.
1234 LibertyReader.cc:3209 bus %s bus_type not found.
1235 LibertyReader.cc:3261 bus_type %s not found.
1236 LibertyReader.cc:3264 bus_type is not a string.
1237 LibertyReader.cc:3282 bundle %s member not found.
1238 LibertyReader.cc:3305 member is not a string.
1239 LibertyReader.cc:3312 members attribute is missing values.
1240 LibertyReader.cc:3363 unknown port direction.
1241 LibertyReader.cc:3610 max_transition is 0.0.
1242 LibertyReader.cc:3716 pulse_latch unknown pulse type.
1243 LibertyReader.cc:4134 timing group missing related_pin/related_bus_pin.
1244 LibertyReader.cc:4233 unknown timing_type %s.
1245 LibertyReader.cc:4253 unknown timing_sense %s.
1246 LibertyReader.cc:4293 mode value is not a string.
1247 LibertyReader.cc:4296 missing mode value.
1248 LibertyReader.cc:4299 mode name is not a string.
1249 LibertyReader.cc:4302 mode missing values.
1250 LibertyReader.cc:4305 mode missing mode name and value.
1251 LibertyReader.cc:4381 unsupported model axis.
1252 LibertyReader.cc:4408 unsupported model axis.
1253 LibertyReader.cc:4437 unsupported model axis.
1254 LibertyReader.cc:4472 unsupported model axis.
1255 LibertyReader.cc:4488 %s group not in timing group.
1256 LibertyReader.cc:4527 table template %s not found.
1257 LibertyReader.cc:4611 %s is missing values.
1258 LibertyReader.cc:4634 %s is not a list of floats.
1259 LibertyReader.cc:4636 table row has %u columns but axis has %d.
1260 LibertyReader.cc:4646 table has %u rows but axis has %d.
1261 LibertyReader.cc:4697 lut output is not a string.
1262 LibertyReader.cc:4714 cell %s test_cell redefinition.
1263 LibertyReader.cc:4739 mode definition missing name.
1264 LibertyReader.cc:4756 mode value missing name.
1265 LibertyReader.cc:4770 when attribute inside table model.
1266 LibertyReader.cc:4819 %s attribute is not a string.
1267 LibertyReader.cc:4822 %s is not a simple attribute.
1268 LibertyReader.cc:4842 %s attribute is not an integer.
1269 LibertyReader.cc:4845 %s is not a simple attribute.
1270 LibertyReader.cc:4858 %s is not a simple attribute.
1271 LibertyReader.cc:4884 %s value %s is not a float.
1272 LibertyReader.cc:4913 %s missing values.
1273 LibertyReader.cc:4917 %s missing values.
1274 LibertyReader.cc:4920 %s is not a complex attribute.
1275 LibertyReader.cc:4946 %s is not a float.
1276 LibertyReader.cc:4969 %s is missing values.
1277 LibertyReader.cc:4972 %s has more than one string.
1278 LibertyReader.cc:4981 %s is missing values.
1279 LibertyReader.cc:5006 %s attribute is not boolean.
1280 LibertyReader.cc:5009 %s attribute is not boolean.
1281 LibertyReader.cc:5012 %s is not a simple attribute.
1282 LibertyReader.cc:5028 attribute %s value %s not recognized.
1283 LibertyReader.cc:5059 unknown early/late value.
1284 LibertyReader.cc:5279 OCV derate group named %s not found.
1285 LibertyReader.cc:5295 ocv_derate missing name.
1286 LibertyReader.cc:5348 unknown rise/fall.
1287 LibertyReader.cc:5368 unknown derate type.
1288 LibertyReader.cc:5400 unsupported model axis.
1289 LibertyReader.cc:5432 unsupported model axis.
1290 LibertyReader.cc:5464 unsupported model axis.
1291 LibertyReader.cc:5535 unknown pg_type.
1292 LibertyReader.cc:5949 port %s subscript out of range.
1293 LibertyReader.cc:5953 port range %s of non-bus port %s.
1294 LibertyReader.cc:5967 port %s not found.
1295 LibertyReader.cc:6037 port %s not found.
1297 LibertyReader.cc:1437 axis type %s not supported.
1330 LibertyWriter.cc:300 %s/%s bundled ports not supported.
1331 LibertyWriter.cc:448 %s/%s/%s timing model not supported.
1332 LibertyWriter.cc:468 3 axis table models not supported.
@ -490,23 +501,23 @@ Warning: 0000 duplicated
1401 PathVertex.cc:250 missing arrivals.
1402 PathVertex.cc:279 missing requireds.
1422 PathVertexRep.cc:153 missing arrivals.
1450 ReadVcdActivities.cc:108 VCD max time is zero.
1451 ReadVcdActivities.cc:175 problem parsing bus %s.
1452 ReadVcdActivities.cc:251 clock %s vcd period %s differs from SDC clock period %s
1450 ReadVcdActivities.cc:107 VCD max time is zero.
1451 ReadVcdActivities.cc:174 problem parsing bus %s.
1452 ReadVcdActivities.cc:250 clock %s vcd period %s differs from SDC clock period %s
1521 Sim.cc:511 propagated logic value %c differs from constraint value of %c on pin %s.
1525 SpefParse.yy:805 %d is not positive.
1526 SpefParse.yy:814 %.4f is not positive.
1527 SpefParse.yy:820 %.4f is not positive.
1550 Sta.cc:2007 '%s' is not a valid start point.
1551 Sta.cc:2080 '%s' is not a valid endpoint.
1552 Sta.cc:2083 '%s' is not a valid endpoint.
1553 Sta.cc:2399 maximum corner count exceeded
1554 Sta.cc:2004 '%s' is not a valid start point.
1550 Sta.cc:2005 '%s' is not a valid start point.
1551 Sta.cc:2078 '%s' is not a valid endpoint.
1552 Sta.cc:2081 '%s' is not a valid endpoint.
1553 Sta.cc:2397 maximum corner count exceeded
1554 Sta.cc:2002 '%s' is not a valid start point.
1570 Search.i:54 no network has been linked.
1571 Search.i:68 network does not support edits.
1574 Search.i:1117 POCV support requires compilation with SSTA=1.
1575 Search.i:526 unknown report path field %s
1576 Search.i:538 unknown report path field %s
1574 Search.i:1118 POCV support requires compilation with SSTA=1.
1575 Search.i:527 unknown report path field %s
1576 Search.i:539 unknown report path field %s
1600 WritePathSpice.cc:165 No liberty libraries found,
1602 WriteSpice.cc:458 Liberty pg_port %s/%s missing voltage_name attribute,
1603 WriteSpice.cc:428 %s pg_port %s not found,

37024
examples/gcd_sky130hd.saif Normal file

File diff suppressed because it is too large Load Diff

View File

@ -8,5 +8,5 @@ read_spef gcd_sky130hd.spef
# Generate vcd file
# iverilog -o gcd_tb gcd_tb.v
# vvp gcd_tb
read_power_activities -scope gcd_tb/gcd1 -vcd gcd_sky130hd.vcd
read_vcd -scope gcd_tb/gcd1 gcd_sky130hd.vcd
report_power

View File

@ -40,7 +40,7 @@ public:
size_t size() const { return paths_.size(); }
// path(0) is the startpoint.
// path(size()-1) is the endpoint.
PathRef *path(size_t index);
const PathRef *path(size_t index) const;
TimingArc *prevArc(size_t index);
// Returns the path start point.
// Register/Latch Q pin

View File

@ -26,6 +26,7 @@ enum class PwrActivityOrigin
input,
user,
vcd,
saif,
propagated,
clock,
constant,

View File

@ -905,9 +905,9 @@ public:
// Previous path end is used to detect path group changes
// so headers are reported by group.
void reportPathEnd(PathEnd *end,
PathEnd *prev_end);
PathEnd *prev_end,
bool last);
void reportPathEnd(PathEnd *end);
void reportPathEnds(PathEndSeq *ends);
ReportPath *reportPath() { return report_path_; }
void reportPath(Path *path);

View File

@ -169,6 +169,11 @@ void
stringPrint(string &str,
const char *fmt,
...) __attribute__((format (printf, 2, 3)));
// Formated append to std::string.
void
stringAppend(string &str,
const char *fmt,
...) __attribute__((format (printf, 2, 3)));
// Print to a temporary string.
char *

View File

@ -60,7 +60,7 @@ BUS_LEFT [\[<]
BUS_RIGHT [\]>]
BUS_SUB {BUS_LEFT}{DIGIT}+{BUS_RIGHT}
BUS_RANGE {BUS_LEFT}{DIGIT}+:{DIGIT}+{BUS_RIGHT}
PIN_NAME ({ALPHA}|_)({ALPHA}|{DIGIT}|_)*
PIN_NAME ({ALPHA}|_)({ALPHA}|{DIGIT}|_)*!?
BUS_NAME {PIN_NAME}({BUS_SUB}|{BUS_RANGE})
BUS_NAME2 {PIN_NAME}{BUS_SUB}({BUS_SUB}|{BUS_RANGE})
MIXED_NAME {BUS_NAME}_{PIN_NAME}

View File

@ -3072,7 +3072,7 @@ LibertyReader::visitCellFootprint(LibertyAttr *attr)
if (cell_) {
const char *footprint = getAttrString(attr);
if (footprint)
cell_->setFootprint(stringCopy(footprint));
cell_->setFootprint(footprint);
}
}

View File

@ -664,6 +664,11 @@ SdcNetwork::findPort(const Cell *cell,
port = network_->findPort(cell, escaped2.c_str());
}
}
else {
// Try escaping brackets foo\[0\].bar
string escaped = escapeBrackets(name, this);
port = network_->findPort(cell, escaped.c_str());
}
}
return port;
}
@ -694,6 +699,12 @@ SdcNetwork::findPortsMatching(const Cell *cell,
matches = network_->findPortsMatching(cell, &escaped_pattern2);
}
}
else {
// Try escaping brackets foo\[0\].bar
string escaped = escapeBrackets(pattern->pattern(), this);
PatternMatch escaped_pattern(escaped.c_str(), pattern);
matches = network_->findPortsMatching(cell, &escaped_pattern);
}
}
return matches;
}
@ -897,6 +908,11 @@ SdcNetwork::findPin(const Instance *instance,
pin = network_->findPin(instance, escaped2.c_str());
}
}
else {
// Try escaping port brackets foo\[0\].bar
string escaped = escapeBrackets(port_name, this);
pin = network_->findPin(instance, escaped.c_str());
}
}
return pin;
}

View File

@ -77,6 +77,7 @@ static EnumNameMap<PwrActivityOrigin> pwr_activity_origin_map =
{PwrActivityOrigin::input, "input"},
{PwrActivityOrigin::user, "user"},
{PwrActivityOrigin::vcd, "vcd"},
{PwrActivityOrigin::saif, "saif"},
{PwrActivityOrigin::propagated, "propagated"},
{PwrActivityOrigin::clock, "clock"},
{PwrActivityOrigin::constant, "constant"},

View File

@ -21,6 +21,7 @@
#include "power/Power.hh"
#include "power/VcdReader.hh"
#include "power/ReadVcdActivities.hh"
#include "power/SaifReader.hh"
using namespace sta;
@ -103,9 +104,11 @@ set_power_pin_activity(const Pin *pin,
return power->setUserActivity(pin, activity, duty, PwrActivityOrigin::user);
}
////////////////////////////////////////////////////////////////
void
read_vcd_activities(const char *filename,
const char *scope)
read_vcd_file(const char *filename,
const char *scope)
{
Sta *sta = Sta::sta();
cmdLinkedNetwork();
@ -128,4 +131,15 @@ report_vcd_var_values(const char *filename,
reportVcdVarValues(filename, var_name, sta);
}
////////////////////////////////////////////////////////////////
bool
read_saif_file(const char *filename,
const char *scope)
{
Sta *sta = Sta::sta();
cmdLinkedNetwork();
return readSaif(filename, scope, sta);
}
%} // inline

View File

@ -283,7 +283,41 @@ proc read_power_activities { args } {
if { [info exists keys(-scope)] } {
set scope $keys(-scope)
}
read_vcd_activities $filename $scope
sta_warn 304 "read_power_activities is deprecated. Use read_vcd."
read_vcd_file $filename $scope
}
################################################################
define_cmd_args "read_vcd" { [-scope scope] filename }
proc read_vcd { args } {
parse_key_args "read_vcd" args \
keys {-scope} flags {}
check_argc_eq1 "read_vcd" $args
set filename [file nativename [lindex $args 0]]
set scope ""
if { [info exists keys(-scope)] } {
set scope $keys(-scope)
}
read_vcd_file $filename $scope
}
################################################################
define_cmd_args "read_saif" { [-scope scope] filename }
proc read_saif { args } {
parse_key_args "read_saif" args keys {-scope} flags {}
check_argc_eq1 "read_saif" $args
set filename [file nativename [lindex $args 0]]
set scope ""
if { [info exists keys(-scope)] } {
set scope $keys(-scope)
}
read_saif_file $filename $scope
}
################################################################

View File

@ -17,6 +17,7 @@
#include "ReadVcdActivities.hh"
#include <inttypes.h>
#include <set>
#include "VcdReader.hh"
#include "Debug.hh"
@ -33,8 +34,6 @@ using std::abs;
using std::min;
using std::to_string;
typedef Set<const Pin*> ConstPinSet;
class ReadVcdActivities : public StaState
{
public:
@ -66,7 +65,7 @@ private:
double clk_period_;
Sta *sta_;
Power *power_;
ConstPinSet annotated_pins_;
std::set<const Pin*> annotated_pins_;
static constexpr double sim_clk_period_tolerance_ = .1;
};

134
power/SaifLex.ll Normal file
View File

@ -0,0 +1,134 @@
%{
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2024, Parallax Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <cstdint>
#include "util/FlexDisableRegister.hh"
#include "StringUtil.hh"
#include "power/SaifReaderPvt.hh"
#include "SaifParse.hh"
#define YY_NO_INPUT
static std::string saif_token;
void
saifFlushBuffer()
{
YY_FLUSH_BUFFER;
}
%}
/* %option debug */
%option noyywrap
%option nounput
%option never-interactive
%x COMMENT
%x QUOTE
%x COND_EXPR
ID ([A-Za-z_])([A-Za-z0-9_$\[\]\\.])*
HCHAR "."|"/"
BLANK [ \n\t\r\b]
EOL \r?\n
%%
"/*" { BEGIN COMMENT; }
<COMMENT>{
"*/" { BEGIN INITIAL; }
.
{EOL} { sta::saif_reader->incrLine(); }
<<EOF>> {
SaifParse_error("unterminated comment");
BEGIN(INITIAL);
yyterminate();
}
}
"\"" { BEGIN QUOTE; saif_token.erase(); }
<QUOTE>{
"\\". { saif_token += yytext[1]; }
"\"" {
BEGIN INITIAL;
SaifParse_lval.string = sta::stringCopy(saif_token.c_str());
return QSTRING;
}
. { saif_token += yytext[0]; }
<<EOF>> {
SaifParse_error("unterminated quoted string");
BEGIN(INITIAL);
yyterminate();
}
}
"//"[^\n]*{EOL} { sta::saif_reader->incrLine(); }
[0-9]+ {
SaifParse_lval.uint = atoll(yytext);
return UINT;
}
":"|"{"|"}"|"["|"]"|","|"*"|";"|"="|"-"|"+"|"|"|"("|")"|{HCHAR} {
return ((int) yytext[0]);
}
SAIFILE { return SAIFILE; }
SAIFVERSION { return SAIFVERSION; }
DIRECTION { return DIRECTION; }
DESIGN { return DESIGN; }
DATE { return DATE; }
VENDOR { return VENDOR; }
PROGRAM_NAME { return PROGRAM_NAME; }
VERSION { return VERSION; }
DIVIDER { return DIVIDER; }
TIMESCALE { return TIMESCALE; }
DURATION { return DURATION; }
INSTANCE { return INSTANCE; }
NET { return NET; }
PORT { return PORT; }
T0 { return T0; }
T1 { return T1; }
TX { return TX; }
TZ { return TZ; }
TB { return TB; }
TC { return TC; }
IG { return IG; }
{ID} {
SaifParse_lval.string = sta::stringCopy(yytext);
return ID;
}
{EOL} { sta::saif_reader->incrLine(); }
{BLANK} { /* Ignore blanks. */ }
/* Send out of bound characters to parser. */
. { return ((int) yytext[0]); }
%%

159
power/SaifParse.yy Normal file
View File

@ -0,0 +1,159 @@
%{
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2024, Parallax Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <cctype>
#include "StringUtil.hh"
#include "power/SaifReaderPvt.hh"
int SaifLex_lex();
#define SaifParse_lex SaifLex_lex
// use yacc generated parser errors
#define YYERROR_VERBOSE
#define YYDEBUG 1
%}
// expected shift/reduce conflicts
%expect 2
%union {
char character;
const char *string;
uint64_t uint;
sta::SaifState state;
sta::SaifStateDurations state_durations;
}
%token SAIFILE SAIFVERSION DIRECTION DESIGN DATE VENDOR PROGRAM_NAME VERSION
%token DIVIDER TIMESCALE DURATION
%token INSTANCE NET PORT
%token T0 T1 TX TZ TB TC IG
%token QSTRING ID FNUMBER DNUMBER UINT
%type <uint> UINT
%type <string> QSTRING ID
%type <character> hchar
%type <state> state
%type <state_durations> state_durations
%start file
%{
%}
%%
file:
'(' SAIFILE header instance ')' {}
;
header:
header_stmt
| header header_stmt
;
header_stmt:
'(' SAIFVERSION QSTRING ')' { sta::stringDelete($3); }
| '(' DIRECTION QSTRING ')' { sta::stringDelete($3); }
| '(' DESIGN QSTRING ')' { sta::stringDelete($3); }
| '(' DESIGN ')' { }
| '(' DATE QSTRING ')' { sta::stringDelete($3); }
| '(' VENDOR QSTRING ')' { sta::stringDelete($3); }
| '(' PROGRAM_NAME QSTRING ')' { sta::stringDelete($3); }
| '(' VERSION QSTRING ')' { sta::stringDelete($3); }
| '(' DIVIDER hchar ')' { sta::saif_reader->setDivider($3); }
| '(' TIMESCALE UINT ID ')' { sta::saif_reader->setTimescale($3, $4); }
| '(' DURATION UINT ')' { sta::saif_reader->setDuration($3); }
;
hchar:
'/'
{ $$ = '/'; }
| '.'
{ $$ = '.'; }
;
instance:
'(' INSTANCE ID
{ sta::saif_reader->instancePush($3); }
instance_contents ')'
{ sta::saif_reader->instancePop(); }
| '(' INSTANCE QSTRING ID
{ sta::saif_reader->instancePush($3); }
instance_contents ')'
{ sta::saif_reader->instancePop(); }
;
instance_contents:
/* empty */
| instance_content
| instance_contents instance_content
;
instance_content:
'(' PORT ports ')'
| '(' NET nets ')'
| instance
;
nets:
net
| nets net
;
net:
'(' ID state_durations ')'
{ sta::saif_reader->setNetDurations($2, $3); }
;
ports:
port
| ports port
;
port:
'(' ID state_durations ')'
;
state_durations:
'(' state UINT ')'
{ $$[static_cast<int>($2)] = $3; }
| state_durations '(' state UINT ')'
{ $$[static_cast<int>($3)] = $4; }
;
state:
T0
{ $$ = sta::SaifState::T0; }
| T1
{ $$ = sta::SaifState::T1; }
| TX
{ $$ = sta::SaifState::TX; }
| TZ
{ $$ = sta::SaifState::TZ; }
| TB
{ $$ = sta::SaifState::TB; }
| TC
{ $$ = sta::SaifState::TC; }
| IG
{ $$ = sta::SaifState::IG; }
;
%%

290
power/SaifReader.cc Normal file
View File

@ -0,0 +1,290 @@
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2024, Parallax Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include "power/SaifReader.hh"
#include <algorithm>
#include "Error.hh"
#include "Debug.hh"
#include "Report.hh"
#include "Network.hh"
#include "Sdc.hh"
#include "Power.hh"
#include "power/SaifReaderPvt.hh"
#include "Sta.hh"
extern int
SaifParse_parse();
extern int SaifParse_debug;
namespace sta {
using std::min;
SaifReader *saif_reader = nullptr;
bool
readSaif(const char *filename,
const char *scope,
Sta *sta)
{
SaifReader reader(filename, scope, sta);
saif_reader = &reader;
bool success = reader.read();
saif_reader = nullptr;
return success;
}
SaifReader::SaifReader(const char *filename,
const char *scope,
Sta *sta) :
StaState(sta),
filename_(filename),
scope_(scope),
stream_(nullptr),
line_(1),
divider_('/'),
escape_('\\'),
timescale_(1.0E-9F), // default units of ns
duration_(0.0),
clk_period_(0.0),
in_scope_level_(0),
power_(sta->power())
{
}
SaifReader::~SaifReader()
{
}
bool
SaifReader::read()
{
// Use zlib to uncompress gzip'd files automagically.
stream_ = gzopen(filename_, "rb");
if (stream_) {
clk_period_ = INF;
for (Clock *clk : *sdc_->clocks())
clk_period_ = min(static_cast<double>(clk->period()), clk_period_);
saif_scope_.clear();
in_scope_level_ = 0;
annotated_pins_.clear();
//::SaifParse_debug = 1;
// yyparse returns 0 on success.
bool success = (::SaifParse_parse() == 0);
gzclose(stream_);
return success;
}
else
throw FileNotReadable(filename_);
}
void
SaifReader::setDivider(char divider)
{
divider_ = divider;
}
void
SaifReader::setTimescale(uint64_t multiplier,
const char *units)
{
if (multiplier == 1
|| multiplier == 10
|| multiplier == 100) {
if (stringEq(units, "us"))
timescale_ = multiplier * 1E-6;
else if (stringEq(units, "ns"))
timescale_ = multiplier * 1E-9;
else if (stringEq(units, "ps"))
timescale_ = multiplier * 1E-12;
else if (stringEq(units, "fs"))
timescale_ = multiplier * 1E-15;
else
saifError(180, "TIMESCALE units not us, ns, or ps.");
}
else
saifError(181, "TIMESCALE multiplier not 1, 10, or 100.");
stringDelete(units);
}
void
SaifReader::setDuration(uint64_t duration)
{
duration_ = duration;
}
void
SaifReader::instancePush(const char *instance_name)
{
if (in_scope_level_ == 0) {
// Check for a match to the annotation scope.
saif_scope_.push_back(instance_name);
string saif_scope;
bool first = true;
for (string &inst : saif_scope_) {
if (!first)
saif_scope += network_->pathDivider();
saif_scope += inst;
first = false;
}
if (stringEq(saif_scope.c_str(), scope_))
in_scope_level_ = saif_scope_.size();
}
else {
// Inside annotation scope.
Instance *parent = path_.empty() ? network_->topInstance() : path_.back();
Instance *child = network_->findChild(parent, instance_name);
path_.push_back(child);
}
stringDelete(instance_name);
}
void
SaifReader::instancePop()
{
if (in_scope_level_ == 0)
saif_scope_.pop_back();
if (!path_.empty())
path_.pop_back();
if (saif_scope_.size() < in_scope_level_)
in_scope_level_ = 0;
}
void
SaifReader::setNetDurations(const char *net_name,
SaifStateDurations &durations)
{
if (in_scope_level_ > 0) {
Instance *parent = path_.empty() ? network_->topInstance() : path_.back();
if (parent) {
const char *net_name1 = unescaped(net_name);
const Pin *pin = sdc_network_->findPin(parent, net_name1);
if (pin) {
double t1 = durations[static_cast<int>(SaifState::T1)];
float duty = t1 / duration_;
double tc = durations[static_cast<int>(SaifState::TC)];
float activity = tc / (duration_ * timescale_ / clk_period_);
debugPrint(debug_, "read_saif", 2,
"%s duty %.0f / %llu = %.2f tc %.0f activity %.2f",
sdc_network_->pathName(pin),
t1,
duration_,
duty,
tc,
activity);
power_->setUserActivity(pin, activity, duty, PwrActivityOrigin::saif);
annotated_pins_.insert(pin);
}
}
}
}
const char *
SaifReader::unescaped(const char *token)
{
char *unescaped = new char[strlen(token) + 1];
char *u = unescaped;
size_t token_length = strlen(token);
for (size_t i = 0; i < token_length; i++) {
char ch = token[i];
if (ch == escape_) {
char next_ch = token[i + 1];
*u++ = next_ch;
i++;
}
else
// Just the normal noises.
*u++ = ch;
}
*u = '\0';
debugPrint(debug_, "saif_name", 1, "token %s -> %s", token, unescaped);
return unescaped;
}
void
SaifReader::incrLine()
{
line_++;
}
void
SaifReader::getChars(char *buf,
size_t &result,
size_t max_size)
{
char *status = gzgets(stream_, buf, max_size);
if (status == Z_NULL)
result = 0; // YY_nullptr
else
result = strlen(buf);
}
void
SaifReader::getChars(char *buf,
int &result,
size_t max_size)
{
char *status = gzgets(stream_, buf, max_size);
if (status == Z_NULL)
result = 0; // YY_nullptr
else
result = strlen(buf);
}
void
SaifReader::notSupported(const char *feature)
{
saifError(193, "%s not supported.", feature);
}
void
SaifReader::saifWarn(int id,
const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
report_->vfileWarn(id, filename_, line_, fmt, args);
va_end(args);
}
void
SaifReader::saifError(int id,
const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
report_->vfileError(id, filename_, line_, fmt, args);
va_end(args);
}
} // namespace
// Global namespace
void saifFlushBuffer();
int
SaifParse_error(const char *msg)
{
saifFlushBuffer();
sta::saif_reader->saifError(196, "%s.\n", msg);
return 0;
}

28
power/SaifReader.hh Normal file
View File

@ -0,0 +1,28 @@
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2024, 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/>.
#pragma once
namespace sta {
class Sta;
bool
readSaif(const char *filename,
const char *scope,
Sta *sta);
} // namespace

108
power/SaifReaderPvt.hh Normal file
View File

@ -0,0 +1,108 @@
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2024, 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/>.
#pragma once
#include <cstdint>
#include <vector>
#include <string>
#include <set>
#include "Zlib.hh"
#include "NetworkClass.hh"
#include "StaState.hh"
// Header for SaifReader.cc to communicate with SaifLex.cc, SaifParse.cc
// global namespace
#define YY_INPUT(buf,result,max_size) \
sta::saif_reader->getChars(buf, result, max_size)
int
SaifParse_error(const char *msg);
namespace sta {
class Sta;
class Power;
using std::vector;
using std::string;
enum class SaifState { T0, T1, TX, TZ, TB, TC, IG };
typedef std::array<uint64_t, static_cast<int>(SaifState::IG)+1> SaifStateDurations;
class SaifReader : public StaState
{
public:
SaifReader(const char *filename,
const char *scope,
Sta *sta);
~SaifReader();
bool read();
void setDivider(char divider);
void setTimescale(uint64_t multiplier,
const char *units);
void setDuration(uint64_t duration);
void instancePush(const char *instance_name);
void instancePop();
void setNetDurations(const char *net_name,
SaifStateDurations &durations);
// flex YY_INPUT yy_n_chars arg changed definition from int to size_t,
// so provide both forms.
void getChars(char *buf,
size_t &result,
size_t max_size);
void getChars(char *buf,
int &result,
size_t max_size);
void incrLine();
const char *filename() { return filename_; }
int line() { return line_; }
void saifWarn(int id,
const char *fmt, ...);
void saifError(int id,
const char *fmt,
...);
void notSupported(const char *feature);
private:
const char *unescaped(const char *token);
const char *filename_;
const char *scope_; // Divider delimited scope to begin annotation.
gzFile stream_;
int line_;
char divider_;
char escape_;
double timescale_;
int64_t duration_;
double clk_period_;
vector<string> saif_scope_; // Scope during parsing.
size_t in_scope_level_;
vector<Instance*> path_; // Path within scope.
std::set<const Pin*> annotated_pins_;
Power *power_;
};
extern SaifReader *saif_reader;
} // namespace

View File

@ -1,4 +1,3 @@
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2024, Parallax Software, Inc.
//

View File

@ -452,7 +452,11 @@ proc get_cells { args } {
set hierarchical [info exists flags(-hierarchical)]
set quiet [info exists flags(-quiet)]
# Copy backslashes that will be removed by foreach.
set patterns [string map {\\ \\\\} [lindex $args 0]]
if { $args == {} } {
set patterns "*"
} else {
set patterns [string map {\\ \\\\} [lindex $args 0]]
}
set divider $hierarchy_separator
if [info exists keys(-hsc)] {
set divider $keys(-hsc)
@ -483,20 +487,27 @@ proc get_cells { args } {
$pin_iter finish
}
} else {
check_argc_eq1 "get_cells" $args
check_argc_eq0or1 "get_cells" $args
foreach pattern $patterns {
if { $divider != $hierarchy_separator } {
regsub $divider $pattern $hierarchy_separator pattern
}
if { $hierarchical } {
set matches [find_instances_hier_matching $pattern $regexp $nocase]
if { [is_object $pattern] } {
if { [object_type $pattern] != "Instance" } {
sta_error 326 "object '$pattern' is not an instance."
}
set insts [concat $insts $pattern]
} else {
set matches [find_instances_matching $pattern $regexp $nocase]
if { $divider != $hierarchy_separator } {
regsub $divider $pattern $hierarchy_separator pattern
}
if { $hierarchical } {
set matches [find_instances_hier_matching $pattern $regexp $nocase]
} else {
set matches [find_instances_matching $pattern $regexp $nocase]
}
if { $matches == {} && !$quiet} {
sta_warn 349 "instance '$pattern' not found."
}
set insts [concat $insts $matches]
}
if { $matches == {} && !$quiet} {
sta_warn 349 "instance '$pattern' not found."
}
set insts [concat $insts $matches]
}
}
if [info exists keys(-filter)] {
@ -507,27 +518,38 @@ 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]}
define_cmd_alias "get_clock" "get_clocks"
proc get_clocks { args } {
parse_key_args "get_clocks" args keys {-filter} flags {-regexp -nocase -quiet}
check_argc_eq1 "get_clocks" $args
check_argc_eq0or1 "get_clocks" $args
check_nocase_flag flags
# Copy backslashes that will be removed by foreach.
set patterns [string map {\\ \\\\} [lindex $args 0]]
if { $args == {} } {
set patterns "*"
} else {
set patterns [string map {\\ \\\\} [lindex $args 0]]
}
set regexp [info exists flags(-regexp)]
set nocase [info exists flags(-nocase)]
set clocks {}
foreach pattern $patterns {
set matches [find_clocks_matching $pattern $regexp $nocase]
if { $matches != {} } {
set clocks [concat $clocks $matches]
if { [is_object $pattern] } {
if { [object_type $pattern] != "Clock" } {
sta_error 327 "object '$pattern' is not an clock."
}
set clocks [concat $clocks $pattern]
} else {
if {![info exists flags(-quiet)]} {
sta_warn 351 "clock '$pattern' not found."
set matches [find_clocks_matching $pattern $regexp $nocase]
if { $matches != {} } {
set clocks [concat $clocks $matches]
} else {
if {![info exists flags(-quiet)]} {
sta_warn 351 "clock '$pattern' not found."
}
}
}
}
@ -563,9 +585,13 @@ proc get_lib_cells { args } {
lappend cells [$inst liberty_cell]
}
} else {
check_argc_eq1 "get_lib_cells" $args
check_argc_eq0or1 "get_lib_cells" $args
# Copy backslashes that will be removed by foreach.
set patterns [string map {\\ \\\\} [lindex $args 0]]
if { $args == {} } {
set patterns "*"
} else {
set patterns [string map {\\ \\\\} [lindex $args 0]]
}
# Parse library_name/pattern.
set divider $hierarchy_separator
if [info exists keys(-hsc)] {
@ -575,27 +601,34 @@ proc get_lib_cells { args } {
set cell_regexp [cell_regexp_hsc $divider]
set quiet [info exists flags(-quiet)]
foreach pattern $patterns {
if { ![regexp $cell_regexp $pattern ignore lib_name cell_pattern]} {
set lib_name "*"
set cell_pattern $pattern
}
# Allow wildcards in the library name (incompatible).
set libs [get_libs -quiet $lib_name]
if { $libs == {} } {
if {!$quiet} {
sta_warn 353 "library '$lib_name' not found."
if { [is_object $pattern] } {
if { [object_type $pattern] != "LibertyCell" } {
sta_error 328 "object '$pattern' is not a liberty cell."
}
set cells [concat $cells $pattern]
} else {
foreach lib $libs {
set matches [$lib find_liberty_cells_matching $cell_pattern \
$regexp $nocase]
if {$matches != {}} {
set cells [concat $cells $matches]
}
if { ![regexp $cell_regexp $pattern ignore lib_name cell_pattern]} {
set lib_name "*"
set cell_pattern $pattern
}
if { $cells == {} } {
# Allow wildcards in the library name (incompatible).
set libs [get_libs -quiet $lib_name]
if { $libs == {} } {
if {!$quiet} {
sta_warn 354 "cell '$cell_pattern' not found."
sta_warn 353 "library '$lib_name' not found."
}
} else {
foreach lib $libs {
set matches [$lib find_liberty_cells_matching $cell_pattern \
$regexp $nocase]
if {$matches != {}} {
set cells [concat $cells $matches]
}
}
if { $cells == {} } {
if {!$quiet} {
sta_warn 354 "cell '$cell_pattern' not found."
}
}
}
}
@ -610,7 +643,7 @@ proc get_lib_cells { args } {
################################################################
define_cmd_args "get_lib_pins" \
{[-hsc separator] [-regexp] [-nocase] [-quiet] [-filter expr] patterns}
{[-hsc separator] [-regexp] [-nocase] [-quiet] [-filter expr] [patterns]}
define_cmd_alias "get_lib_pin" "get_lib_pins"
@ -618,14 +651,18 @@ define_cmd_alias "get_lib_pin" "get_lib_pins"
proc get_lib_pins { args } {
global hierarchy_separator
parse_key_args "get_lib_pins" args keys {-hsc -filter} flags {-regexp -nocase -quiet}
check_argc_eq1 "get_lib_pins" $args
check_argc_eq0or1 "get_lib_pins" $args
check_nocase_flag flags
set regexp [info exists flags(-regexp)]
set nocase [info exists flags(-nocase)]
set quiet [info exists flags(-quiet)]
# Copy backslashes that will be removed by foreach.
set patterns [string map {\\ \\\\} [lindex $args 0]]
if { $args == {} } {
set patterns "*/*"
} else {
set patterns [string map {\\ \\\\} [lindex $args 0]]
}
# Parse library_name/cell_name/pattern.
set divider $hierarchy_separator
if [info exists keys(-hsc)] {
@ -636,41 +673,48 @@ proc get_lib_pins { args } {
set port_regexp2 [cell_regexp_hsc $divider]
set ports {}
foreach pattern $patterns {
# match library/cell/port
set libs {}
if { [regexp $port_regexp1 $pattern ignore lib_name cell_name port_pattern] } {
set libs [get_libs -quiet $lib_name]
# match cell/port
} elseif { [regexp $port_regexp2 $pattern ignore cell_name port_pattern] } {
set libs [get_libs *]
} else {
if { !$quiet } {
sta_warn 355 "library/cell/port '$pattern' not found."
if { [is_object $pattern] } {
if { [object_type $pattern] != "LibertyPort" } {
sta_error 329 "object '$pattern' is not a liberty pin."
}
return {}
}
if { $libs != {} } {
set found_match 0
set cells {}
foreach lib $libs {
set cells [$lib find_liberty_cells_matching $cell_name $regexp $nocase]
foreach cell $cells {
set matches [$cell find_liberty_ports_matching $port_pattern \
$regexp $nocase]
foreach match $matches {
lappend ports $match
set found_match 1
set ports [concat $ports $pattern]
} else {
# match library/cell/port
set libs {}
if { [regexp $port_regexp1 $pattern ignore lib_name cell_name port_pattern] } {
set libs [get_libs -quiet $lib_name]
# match cell/port
} elseif { [regexp $port_regexp2 $pattern ignore cell_name port_pattern] } {
set libs [get_libs *]
} else {
if { !$quiet } {
sta_warn 355 "library/cell/port '$pattern' not found."
}
return {}
}
if { $libs != {} } {
set found_match 0
set cells {}
foreach lib $libs {
set cells [$lib find_liberty_cells_matching $cell_name $regexp $nocase]
foreach cell $cells {
set matches [$cell find_liberty_ports_matching $port_pattern \
$regexp $nocase]
foreach match $matches {
lappend ports $match
set found_match 1
}
}
}
}
if { !$found_match } {
if { !$quiet } {
sta_warn 356 "port '$port_pattern' not found."
if { !$found_match } {
if { !$quiet } {
sta_warn 356 "port '$port_pattern' not found."
}
}
} else {
if { !$quiet } {
sta_warn 357 "library '$lib_name' not found."
}
}
} else {
if { !$quiet } {
sta_warn 357 "library '$lib_name' not found."
}
}
}
@ -689,27 +733,38 @@ 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]}
define_cmd_alias "get_lib" "get_libs"
proc get_libs { args } {
parse_key_args "get_libs" args keys {-filter} flags {-regexp -nocase -quiet}
check_argc_eq1 "get_libs" $args
check_argc_eq0or1 "get_libs" $args
check_nocase_flag flags
# Copy backslashes that will be removed by foreach.
set patterns [string map {\\ \\\\} [lindex $args 0]]
if { $args == {} } {
set patterns "*"
} else {
set patterns [string map {\\ \\\\} [lindex $args 0]]
}
set regexp [info exists flags(-regexp)]
set nocase [info exists flags(-nocase)]
set libs {}
foreach pattern $patterns {
set matches [find_liberty_libraries_matching $pattern $regexp $nocase]
if {$matches != {}} {
set libs [concat $libs $matches]
if { [is_object $pattern] } {
if { [object_type $pattern] != "LibertyLibrary" } {
sta_error 330 "object '$pattern' is not a liberty library."
}
set libs [concat $libs $pattern]
} else {
if {![info exists flags(-quiet)]} {
sta_warn 359 "library '$pattern' not found."
set matches [find_liberty_libraries_matching $pattern $regexp $nocase]
if {$matches != {}} {
set libs [concat $libs $matches]
} else {
if {![info exists flags(-quiet)]} {
sta_warn 359 "library '$pattern' not found."
}
}
}
}
@ -766,7 +821,11 @@ proc get_nets { args } {
set hierarchical [info exists flags(-hierarchical)]
set quiet [info exists flags(-quiet)]
# Copy backslashes that will be removed by foreach.
set patterns [string map {\\ \\\\} [lindex $args 0]]
if { $args == {} } {
set patterns "*"
} else {
set patterns [string map {\\ \\\\} [lindex $args 0]]
}
if [info exists keys(-hsc)] {
set divider $keys(-hsc)
check_path_divider $divider
@ -790,16 +849,23 @@ proc get_nets { args } {
lappend nets [$pin net]
}
} else {
check_argc_eq1 "get_nets" $args
check_argc_eq0or1 "get_nets" $args
foreach pattern $patterns {
if { $hierarchical } {
set matches [find_nets_hier_matching $pattern $regexp $nocase]
if { [is_object $pattern] } {
if { [object_type $pattern] != "Net" } {
sta_error 331 "object '$pattern' is not a net."
}
set nets [concat $nets $pattern]
} else {
set matches [find_nets_matching $pattern $regexp $nocase]
}
set nets [concat $nets $matches]
if { $matches == {} && !$quiet } {
sta_warn 361 "net '$pattern' not found."
if { $hierarchical } {
set matches [find_nets_hier_matching $pattern $regexp $nocase]
} else {
set matches [find_nets_matching $pattern $regexp $nocase]
}
set nets [concat $nets $matches]
if { $matches == {} && !$quiet } {
sta_warn 361 "net '$pattern' not found."
}
}
}
}
@ -851,8 +917,12 @@ proc get_pins { args } {
$pin_iter finish
}
} else {
check_argc_eq1 "get_pins" $args
set patterns [lindex $args 0]
check_argc_eq0or1 "get_pins" $args
if { $args == {} } {
set patterns "*"
} else {
set patterns [lindex $args 0]
}
if [info exists keys(-hsc)] {
set divider $keys(-hsc)
check_path_divider $divider
@ -861,14 +931,21 @@ proc get_pins { args } {
# Copy backslashes that will be removed by foreach.
set patterns [string map {\\ \\\\} $patterns]
foreach pattern $patterns {
if { $hierarchical } {
set matches [find_pins_hier_matching $pattern $regexp $nocase]
if { [is_object $pattern] } {
if { [object_type $pattern] != "Pin" } {
sta_error 332 "object '$pattern' is not a pin."
}
set pins [concat $pins $pattern]
} else {
set matches [find_pins_matching $pattern $regexp $nocase]
}
set pins [concat $pins $matches]
if { $matches == {} && !$quiet } {
sta_warn 363 "pin '$pattern' not found."
if { $hierarchical } {
set matches [find_pins_hier_matching $pattern $regexp $nocase]
} else {
set matches [find_pins_matching $pattern $regexp $nocase]
}
set pins [concat $pins $matches]
if { $matches == {} && !$quiet } {
sta_warn 363 "pin '$pattern' not found."
}
}
}
}
@ -894,7 +971,11 @@ proc get_ports { args } {
set regexp [info exists flags(-regexp)]
set nocase [info exists flags(-nocase)]
# Copy backslashes that will be removed by foreach.
set patterns [string map {\\ \\\\} [lindex $args 0]]
if { $args == {} } {
set patterns "*"
} else {
set patterns [string map {\\ \\\\} [lindex $args 0]]
}
set ports {}
if [info exists keys(-of_objects)] {
if { $args != {} } {
@ -905,15 +986,22 @@ proc get_ports { args } {
set ports [concat $ports [$net ports]]
}
} else {
check_argc_eq1 "get_ports" $args
check_argc_eq0or1 "get_ports" $args
foreach pattern $patterns {
set matches [find_ports_matching $pattern $regexp $nocase]
if { $matches != {} } {
set ports [concat $ports $matches]
} else {
if {![info exists flags(-quiet)]} {
sta_warn 366 "port '$pattern' not found."
if { [is_object $pattern] } {
if { [object_type $pattern] != "Port" } {
sta_error 333 "object '$pattern' is not a port."
}
set ports [concat $ports $pattern]
} else {
set matches [find_ports_matching $pattern $regexp $nocase]
if { $matches != {} } {
set ports [concat $ports $matches]
} else {
if {![info exists flags(-quiet)]} {
sta_warn 366 "port '$pattern' not found."
}
}
}
}
}
@ -2755,7 +2843,14 @@ proc set_driving_cell { args } {
}
} else {
set library "NULL"
set cell [find_liberty_cell $cell_name]
if { [is_object $cell_name] } {
if { [object_type $cell_name] != "LibertyCell" } {
sta_error 334 "object '$cell_name' is not a liberty cell."
}
set cell $cell_name
} else {
set cell [find_liberty_cell $cell_name]
}
if { $cell == "NULL" } {
sta_error 453 "'$cell_name' not found."
}

View File

@ -16,14 +16,9 @@
#pragma once
#include "SdcClass.hh"
namespace sta {
class Report;
class MinMax;
class Network;
class Graph;
class MinMaxAll;
class Corner;
class StaState;

View File

@ -26,7 +26,7 @@
#include "SdcClass.hh"
#include "StaState.hh"
// Header for ReadSdf.cc to communicate with SdfLex.cc, SdfParse.cc
// Header for SdfReader.cc to communicate with SdfLex.cc, SdfParse.cc
// global namespace

View File

@ -146,8 +146,8 @@ PathExpanded::startIndex() const
return pathsIndex(start_index_);
}
PathRef *
PathExpanded::path(size_t index)
const PathRef *
PathExpanded::path(size_t index) const
{
if (index < paths_.size())
return &paths_[pathsIndex(index)];

View File

@ -1260,7 +1260,7 @@ getProperty(PathEnd *end,
PathExpanded expanded(end->path(), sta);
PathRefSeq paths;
for (auto i = expanded.startIndex(); i < expanded.size(); i++) {
PathRef *path = expanded.path(i);
const PathRef *path = expanded.path(i);
paths.push_back(*path);
}
return PropertyValue(&paths);

View File

@ -269,58 +269,16 @@ ReportPath::setReportSigmas(bool report)
////////////////////////////////////////////////////////////////
void
ReportPath::reportPathEndHeader()
{
switch (format_) {
case ReportPathFormat::full:
case ReportPathFormat::full_clock:
case ReportPathFormat::full_clock_expanded:
case ReportPathFormat::shorter:
case ReportPathFormat::endpoint:
break;
case ReportPathFormat::summary:
reportSummaryHeader();
break;
case ReportPathFormat::slack_only:
reportSlackOnlyHeader();
break;
default:
report_->critical(1470, "unsupported path type");
break;
}
}
void
ReportPath::reportPathEndFooter()
{
string header;
switch (format_) {
case ReportPathFormat::full:
case ReportPathFormat::full_clock:
case ReportPathFormat::full_clock_expanded:
case ReportPathFormat::shorter:
break;
case ReportPathFormat::endpoint:
case ReportPathFormat::summary:
case ReportPathFormat::slack_only:
reportBlankLine();
break;
default:
report_->critical(1471, "unsupported path type");
break;
}
}
void
ReportPath::reportPathEnd(PathEnd *end)
{
reportPathEnd(end, nullptr);
reportPathEnd(end, nullptr, true);
}
void
ReportPath::reportPathEnd(PathEnd *end,
PathEnd *prev_end)
PathEnd *prev_end,
bool last)
{
switch (format_) {
case ReportPathFormat::full:
@ -345,8 +303,8 @@ ReportPath::reportPathEnd(PathEnd *end,
case ReportPathFormat::slack_only:
reportSlackOnly(end);
break;
default:
report_->critical(1473, "unsupported path type");
case ReportPathFormat::json:
reportJson(end, last);
break;
}
}
@ -367,6 +325,49 @@ ReportPath::reportPathEnds(PathEndSeq *ends)
reportPathEndFooter();
}
void
ReportPath::reportPathEndHeader()
{
switch (format_) {
case ReportPathFormat::full:
case ReportPathFormat::full_clock:
case ReportPathFormat::full_clock_expanded:
case ReportPathFormat::shorter:
case ReportPathFormat::endpoint:
break;
case ReportPathFormat::summary:
reportSummaryHeader();
break;
case ReportPathFormat::slack_only:
reportSlackOnlyHeader();
break;
case ReportPathFormat::json:
reportJsonHeader();
break;
}
}
void
ReportPath::reportPathEndFooter()
{
string header;
switch (format_) {
case ReportPathFormat::full:
case ReportPathFormat::full_clock:
case ReportPathFormat::full_clock_expanded:
case ReportPathFormat::shorter:
break;
case ReportPathFormat::endpoint:
case ReportPathFormat::summary:
case ReportPathFormat::slack_only:
reportBlankLine();
break;
case ReportPathFormat::json:
reportJsonFooter();
break;
}
}
void
ReportPath::reportEndpointHeader(PathEnd *end,
PathEnd *prev_end)
@ -1043,6 +1044,146 @@ ReportPath::pathEndpoint(PathEnd *end)
////////////////////////////////////////////////////////////////
void
ReportPath::reportJsonHeader()
{
report_->reportLine("{\"checks\": [");
}
void
ReportPath::reportJsonFooter()
{
report_->reportLine("]");
report_->reportLine("}");
}
void
ReportPath::reportJson(const PathEnd *end,
bool last)
{
string result;
result += "{\n";
stringAppend(result, " \"type\": \"%s\",\n", end->typeName());
stringAppend(result, " \"path_group\": \"%s\",\n",
search_->pathGroup(end)->name());
stringAppend(result, " \"path_type\": \"%s\",\n",
end->minMax(this)->asString());
PathExpanded expanded(end->path(), this);
const Pin *startpoint = expanded.startPath()->vertex(this)->pin();
const Pin *endpoint = expanded.endPath()->vertex(this)->pin();
stringAppend(result, " \"startpoint\": \"%s\",\n",
network_->pathName(startpoint));
stringAppend(result, " \"endpoint\": \"%s\",\n",
network_->pathName(endpoint));
const ClockEdge *src_clk_edge = end->sourceClkEdge(this);
const PathVertex *tgt_clk_path = end->targetClkPath();
if (src_clk_edge) {
stringAppend(result, " \"source_clock\": \"%s\",\n",
src_clk_edge->clock()->name());
stringAppend(result, " \"source_clock_edge\": \"%s\",\n",
src_clk_edge->transition()->name());
}
reportJson(expanded, "source_path", 2, !end->isUnconstrained(), result);
const ClockEdge *tgt_clk_edge = end->targetClkEdge(this);
if (tgt_clk_edge) {
stringAppend(result, " \"target_clock\": \"%s\",\n",
tgt_clk_edge->clock()->name());
stringAppend(result, " \"target_clock_edge\": \"%s\",\n",
tgt_clk_edge->transition()->name());
}
if (tgt_clk_path)
reportJson(end->targetClkPath(), "target_clock_path", 2, true, result);
if (end->checkRole(this)) {
stringAppend(result, " \"data_arrival_time\": %.3e,\n",
end->dataArrivalTimeOffset(this));
const MultiCyclePath *mcp = end->multiCyclePath();
if (mcp)
stringAppend(result, " \"multi_cycle_path\": %d,\n",
mcp->pathMultiplier());
PathDelay *path_delay = end->pathDelay();
if (path_delay)
stringAppend(result, " \"path_delay\": %.3e,\n",
path_delay->delay());
stringAppend(result, " \"crpr\": %.3e,\n", end->checkCrpr(this));
stringAppend(result, " \"margin\": %.3e,\n", end->margin(this));
stringAppend(result, " \"required_time\": %.3e,\n",
end->requiredTimeOffset(this));
stringAppend(result, " \"slack\": %.3e\n", end->slack(this));
}
result += "}";
if (!last)
result += ",";
report_->reportLineString(result);
}
void
ReportPath::reportJson(const Path *path)
{
string result;
result += "{\n";
reportJson(path, "path", 0, false, result);
result += "}\n";
report_->reportLineString(result);
}
void
ReportPath::reportJson(const Path *path,
const char *path_name,
int indent,
bool trailing_comma,
string &result)
{
PathExpanded expanded(path, this);
reportJson(expanded, path_name, indent, trailing_comma, result);
}
void
ReportPath::reportJson(const PathExpanded &expanded,
const char *path_name,
int indent,
bool trailing_comma,
string &result)
{
stringAppend(result, "%*s\"%s\": [\n", indent, "", path_name);
for (size_t i = 0; i < expanded.size(); i++) {
const PathRef *path = expanded.path(i);
const Pin *pin = path->vertex(this)->pin();
stringAppend(result, "%*s {\n", indent, "");
stringAppend(result, "%*s \"pin\": \"%s\",\n",
indent, "",
network_->pathName(pin));
double x, y;
bool exists;
network_->location(pin, x, y, exists);
if (exists) {
stringAppend(result, "%*s \"x\": %.9f,\n", indent, "", x);
stringAppend(result, "%*s \"y\": %.9f,\n", indent, "", y);
}
stringAppend(result, "%*s \"arrival\": %.3e,\n",
indent, "",
delayAsFloat(path->arrival(this)));
stringAppend(result, "%*s \"slew\": %.3e\n",
indent, "",
delayAsFloat(path->slew(this)));
stringAppend(result, "%*s }%s\n",
indent, "",
(i < expanded.size() - 1) ? "," : "");
}
stringAppend(result, "%*s]%s\n",
indent, "",
trailing_comma ? "," : "");
}
////////////////////////////////////////////////////////////////
void
ReportPath::reportSlackOnlyHeader()
{
@ -2365,12 +2506,13 @@ ReportPath::reportPath(const Path *path)
reportPathFull(path);
break;
case ReportPathFormat::json:
reportPathJson(path);
reportJson(path);
break;
case ReportPathFormat::shorter:
case ReportPathFormat::endpoint:
case ReportPathFormat::summary:
case ReportPathFormat::slack_only:
default:
report_->critical(1474, "unsupported path type");
report_->reportLine("Format not supported.");
break;
}
}
@ -2383,54 +2525,7 @@ ReportPath::reportPathFull(const Path *path)
reportSrcClkAndPath(path, expanded, 0.0, delay_zero, delay_zero, false);
}
void
ReportPath::reportPathJson(const Path *path)
{
report_->reportLine("{ \"path\": [");
PathExpanded expanded(path, this);
for (auto i = expanded.startIndex(); i < expanded.size(); i++) {
string line;
PathRef *path = expanded.path(i);
const Pin *pin = path->vertex(this)->pin();
report_->reportLine(" {");
line = " \"pin\": \"";
line += network_->pathName(pin);
line += "\",";
report_->reportLineString(line);
double x, y;
bool exists;
string tmp;
network_->location(pin, x, y, exists);
if (exists) {
line = " \"x\": ";
stringPrint(tmp, "%.9f", x);
line += tmp + ",\n";
line += " \"y\": ";
stringPrint(tmp, "%.9f", y);
line += tmp + ",";
report_->reportLineString(line);
}
line = " \"arrival\": ";
stringPrint(tmp, "%.3e", delayAsFloat(path->arrival(this)));
line += tmp;
line += ",";
report_->reportLineString(line);
line = " \"slew\": ";
stringPrint(tmp, "%.3e", delayAsFloat(path->slew(this)));
line += tmp;
report_->reportLineString(line);
line = " }";
if (i < expanded.size() - 1)
line += ",";
report_->reportLineString(line);
}
report_->reportLine(" ]");
report_->reportLine("}");
}
////////////////////////////////////////////////////////////////
void
ReportPath::reportPath1(const Path *path,
@ -2517,7 +2612,7 @@ ReportPath::reportPath4(const Path *path,
Arrival prev_time(0.0);
if (skip_first_path) {
path_first_index = 1;
PathRef *start = expanded.path(0);
const PathRef *start = expanded.path(0);
prev_time = start->arrival(this) + time_offset;
}
size_t path_last_index = expanded.size() - 1;
@ -2551,7 +2646,7 @@ ReportPath::reportPath5(const Path *path,
expanded.clkPath(clk_path);
Vertex *clk_start = clk_path.vertex(this);
for (size_t i = path_first_index; i <= path_last_index; i++) {
PathRef *path1 = expanded.path(i);
const PathRef *path1 = expanded.path(i);
TimingArc *prev_arc = expanded.prevArc(i);
Vertex *vertex = path1->vertex(this);
Pin *pin = vertex->pin();

View File

@ -61,7 +61,8 @@ public:
// Previous path end is used to detect path group changes
// so headers are reported by group.
void reportPathEnd(PathEnd *end,
PathEnd *prev_end);
PathEnd *prev_end,
bool last);
void reportPathEnds(PathEndSeq *ends);
void reportPath(const Path *path);
@ -81,6 +82,22 @@ public:
void reportFull(const PathEndGatedClock *end);
void reportFull(const PathEndDataCheck *end);
void reportJsonHeader();
void reportJsonFooter();
void reportJson(const PathEnd *end,
bool last);
void reportJson(const Path *path);
void reportJson(const Path *path,
const char *path_name,
int indent,
bool trailing_comma,
string &result);
void reportJson(const PathExpanded &expanded,
const char *path_name,
int indent,
bool trailing_comma,
string &result);
void reportEndHeader();
void reportEndLine(PathEnd *end);
@ -264,7 +281,6 @@ protected:
void reportPath(const PathEnd *end,
PathExpanded &expanded);
void reportPathFull(const Path *path);
void reportPathJson(const Path *path);
void reportPathHeader();
void reportPath1(const Path *path,
PathExpanded &expanded,

View File

@ -480,9 +480,10 @@ report_path_end(PathEnd *end)
void
report_path_end2(PathEnd *end,
PathEnd *prev_end)
PathEnd *prev_end,
bool last)
{
Sta::sta()->reportPathEnd(end, prev_end);
Sta::sta()->reportPathEnd(end, prev_end, last);
}
void

View File

@ -1069,9 +1069,12 @@ proc parse_path_group_arg { group_names } {
proc report_path_ends { path_ends } {
report_path_end_header
set prev_end "NULL"
set end_count [llength $path_ends]
set i 0
foreach path_end $path_ends {
report_path_end2 $path_end $prev_end
report_path_end2 $path_end $prev_end [expr $i == ($end_count - 1)]
set prev_end $path_end
incr i
}
report_path_end_footer
}

View File

@ -2518,12 +2518,6 @@ Sta::setReportPathSigmas(bool report_sigmas)
report_path_->setReportSigmas(report_sigmas);
}
void
Sta::reportPathEnds(PathEndSeq *ends)
{
report_path_->reportPathEnds(ends);
}
void
Sta::reportPathEndHeader()
{
@ -2544,9 +2538,10 @@ Sta::reportPathEnd(PathEnd *end)
void
Sta::reportPathEnd(PathEnd *end,
PathEnd *prev_end)
PathEnd *prev_end,
bool last)
{
report_path_->reportPathEnd(end, prev_end);
report_path_->reportPathEnd(end, prev_end, last);
}
void

View File

@ -84,10 +84,10 @@ private:
float maxTime();
float pathMaxTime();
void writeMeasureDelayStmt(Stage stage,
Path *from_path,
Path *to_path);
const Path *from_path,
const Path *to_path);
void writeMeasureSlewStmt(Stage stage,
Path *path);
const Path *path);
void writeInputWaveform();
void writeClkWaveform();
@ -110,9 +110,9 @@ private:
int stageGateInputPathIndex(Stage stage);
int stageDrvrPathIndex(Stage stage);
int stageLoadPathIndex(Stage stage);
PathRef *stageGateInputPath(Stage stage);
PathRef *stageDrvrPath(Stage stage);
PathRef *stageLoadPath(Stage stage);
const PathRef *stageGateInputPath(Stage stage);
const PathRef *stageDrvrPath(Stage stage);
const PathRef *stageLoadPath(Stage stage);
TimingArc *stageGateArc(Stage stage);
TimingArc *stageWireArc(Stage stage);
Edge *stageGateEdge(Stage stage);
@ -128,8 +128,8 @@ private:
LibertyCell *stageLibertyCell(Stage stage);
Instance *stageInstance(Stage stage);
float findSlew(Path *path);
float findSlew(Path *path,
float findSlew(const Path *path);
float findSlew(const Path *path,
const RiseFall *rf,
TimingArc *next_arc);
Path *path_;
@ -240,7 +240,7 @@ float
WritePathSpice::maxTime()
{
Stage input_stage = stageFirst();
PathRef *input_path = stageDrvrPath(input_stage);
const PathRef *input_path = stageDrvrPath(input_stage);
if (input_path->isClock(this)) {
const Clock *clk = input_path->clock(this);
float period = clk->period();
@ -258,7 +258,7 @@ WritePathSpice::pathMaxTime()
{
float max_time = 0.0;
for (size_t i = 0; i < path_expanded_.size(); i++) {
PathRef *path = path_expanded_.path(i);
const PathRef *path = path_expanded_.path(i);
const RiseFall *rf = path->transition(this);
Vertex *vertex = path->vertex(this);
float path_max_slew = railToRailSlew(findSlew(vertex,rf,nullptr), rf);
@ -315,7 +315,7 @@ WritePathSpice::writeInputSource()
streamPrint(spice_stream_, "**************\n\n");
Stage input_stage = stageFirst();
PathRef *input_path = stageDrvrPath(input_stage);
const PathRef *input_path = stageDrvrPath(input_stage);
if (input_path->isClock(this))
writeClkWaveform();
else
@ -327,7 +327,7 @@ void
WritePathSpice::writeInputWaveform()
{
Stage input_stage = stageFirst();
PathRef *input_path = stageDrvrPath(input_stage);
const PathRef *input_path = stageDrvrPath(input_stage);
const RiseFall *rf = input_path->transition(this);
TimingArc *next_arc = stageGateArc(input_stage + 1);
float slew0 = findSlew(input_path, rf, next_arc);
@ -352,7 +352,7 @@ void
WritePathSpice::writeClkWaveform()
{
Stage input_stage = stageFirst();
PathRef *input_path = stageDrvrPath(input_stage);
const PathRef *input_path = stageDrvrPath(input_stage);
TimingArc *next_arc = stageGateArc(input_stage + 1);
const ClockEdge *clk_edge = input_path->clkEdge(this);
@ -387,7 +387,7 @@ WritePathSpice::writeClkWaveform()
}
float
WritePathSpice::findSlew(Path *path)
WritePathSpice::findSlew(const Path *path)
{
Vertex *vertex = path->vertex(this);
const RiseFall *rf = path->transition(this);
@ -395,9 +395,9 @@ WritePathSpice::findSlew(Path *path)
}
float
WritePathSpice::findSlew(Path *path,
const RiseFall *rf,
TimingArc *next_arc)
WritePathSpice::findSlew(const Path *path,
const RiseFall *rf,
TimingArc *next_arc)
{
Vertex *vertex = path->vertex(this);
return findSlew(vertex, rf, next_arc);
@ -413,9 +413,9 @@ WritePathSpice::writeMeasureStmts()
streamPrint(spice_stream_, "********************\n\n");
for (Stage stage = stageFirst(); stage <= stageLast(); stage++) {
PathRef *gate_input_path = stageGateInputPath(stage);
PathRef *drvr_path = stageDrvrPath(stage);
PathRef *load_path = stageLoadPath(stage);
const PathRef *gate_input_path = stageGateInputPath(stage);
const PathRef *drvr_path = stageDrvrPath(stage);
const PathRef *load_path = stageLoadPath(stage);
if (gate_input_path) {
// gate input -> gate output
writeMeasureSlewStmt(stage, gate_input_path);
@ -432,8 +432,8 @@ WritePathSpice::writeMeasureStmts()
void
WritePathSpice::writeMeasureDelayStmt(Stage stage,
Path *from_path,
Path *to_path)
const Path *from_path,
const Path *to_path)
{
writeMeasureDelayStmt(from_path->pin(this), from_path->transition(this),
to_path->pin(this), to_path->transition(this),
@ -442,7 +442,7 @@ WritePathSpice::writeMeasureDelayStmt(Stage stage,
void
WritePathSpice::writeMeasureSlewStmt(Stage stage,
Path *path)
const Path *path)
{
const Pin *pin = path->pin(this);
const RiseFall *rf = path->transition(this);
@ -514,7 +514,7 @@ WritePathSpice::writeGateStage(Stage stage)
drvr_port->name());
writeSubcktInst(inst);
PathRef *drvr_path = stageDrvrPath(stage);
const PathRef *drvr_path = stageDrvrPath(stage);
const RiseFall *drvr_rf = drvr_path->transition(this);
Edge *gate_edge = stageGateEdge(stage);
@ -544,7 +544,7 @@ WritePathSpice::writeGateStage(Stage stage)
void
WritePathSpice::writeStageParasitics(Stage stage)
{
PathRef *drvr_path = stageDrvrPath(stage);
const PathRef *drvr_path = stageDrvrPath(stage);
DcalcAnalysisPt *dcalc_ap = drvr_path->dcalcAnalysisPt(this);
ParasiticAnalysisPt *parasitic_ap = dcalc_ap->parasiticAnalysisPt();
const Pin *drvr_pin = stageDrvrPin(stage);
@ -637,21 +637,21 @@ WritePathSpice::stageLoadPathIndex(Stage stage)
return stage * 2 - 1;
}
PathRef *
const PathRef *
WritePathSpice::stageGateInputPath(Stage stage)
{
int path_index = stageGateInputPathIndex(stage);
return path_expanded_.path(path_index);
}
PathRef *
const PathRef *
WritePathSpice::stageDrvrPath(Stage stage)
{
int path_index = stageDrvrPathIndex(stage);
return path_expanded_.path(path_index);
}
PathRef *
const PathRef *
WritePathSpice::stageLoadPath(Stage stage)
{
int path_index = stageLoadPathIndex(stage);
@ -678,7 +678,7 @@ WritePathSpice::stageWireArc(Stage stage)
Edge *
WritePathSpice::stageGateEdge(Stage stage)
{
PathRef *path = stageDrvrPath(stage);
const PathRef *path = stageDrvrPath(stage);
TimingArc *arc = stageGateArc(stage);
return path->prevEdge(arc, this);
}
@ -686,7 +686,7 @@ WritePathSpice::stageGateEdge(Stage stage)
Edge *
WritePathSpice::stageWireEdge(Stage stage)
{
PathRef *path = stageLoadPath(stage);
const PathRef *path = stageLoadPath(stage);
TimingArc *arc = stageWireArc(stage);
return path->prevEdge(arc, this);
}
@ -694,7 +694,7 @@ WritePathSpice::stageWireEdge(Stage stage)
Pin *
WritePathSpice::stageGateInputPin(Stage stage)
{
PathRef *path = stageGateInputPath(stage);
const PathRef *path = stageGateInputPath(stage);
return path->pin(this);
}
@ -708,7 +708,7 @@ WritePathSpice::stageGateInputPort(Stage stage)
Pin *
WritePathSpice::stageDrvrPin(Stage stage)
{
PathRef *path = stageDrvrPath(stage);
const PathRef *path = stageDrvrPath(stage);
return path->pin(this);
}
@ -722,7 +722,7 @@ WritePathSpice::stageDrvrPort(Stage stage)
Pin *
WritePathSpice::stageLoadPin(Stage stage)
{
PathRef *path = stageLoadPath(stage);
const PathRef *path = stageLoadPath(stage);
return path->pin(this);
}

View File

@ -78,8 +78,8 @@ proc get_object_args { objects clks_var libcells_var libports_var \
foreach obj $objects {
if { [llength $obj] > 1 } {
# List arg. Recursive call without initing objects.
get_object_args $obj clks libcells libports cells insts \
ports pins nets edges timing_arc_sets
get_object_args $obj $clks_var $libcells_var $libports_var $cells_var $insts_var \
$ports_var $pins_var $nets_var $edges_var $timing_arc_sets_var
} elseif { [is_object $obj] } {
# Explicit object arg.
set object_type [object_type $obj]
@ -117,7 +117,6 @@ proc get_object_args { objects clks_var libcells_var libports_var \
if { $matches != {} } {
set clks [concat $clks $matches]
} else {
if { $libcells_var != {} } {
set matches [get_lib_cells -quiet $obj]
}

View File

@ -341,21 +341,20 @@ proc sta_unknown { args } {
}
if { $ret != 0 } {
return -code $ret -errorcode $errorCode \
"error in unknown while checking if \"$name\" is a unique command abbreviation: $msg"
"Error in unknown while checking if \"$name\" is a unique command abbreviation: $msg."
}
if { [llength $cmds] == 1 } {
return [uplevel 1 [lreplace $args 0 0 $cmds]]
}
if { [llength $cmds] > 1 } {
if {[string equal $name ""]} {
return -code error "empty command name \"\""
return -code error "Empty command name \"\""
} else {
return -code error \
"ambiguous command name \"$name\": [lsort $cmds]"
"Ambiguous command name \"$name\": [lsort $cmds]."
}
}
::unknown {*}$args
return [uplevel 1 [::unknown {*}$args]]
}
proc is_bus_subscript { subscript } {

View File

@ -1,3 +1,5 @@
# Test get_* -filter
# Read in design and libraries
read_liberty asap7_small.lib.gz
read_verilog reg1_asap7.v

65
test/get_noargs.ok Normal file
View File

@ -0,0 +1,65 @@
[get_cells]
r1
r2
r3
u1
u2
[get_clocks]
clk
vclk
[get_lib_cells]
asap7_small/AND2x2_ASAP7_75t_R
asap7_small/BUFx2_ASAP7_75t_R
asap7_small/DFFHQx4_ASAP7_75t_R
[get_lib_pins]
A
A
B
CLK
D
IQ
IQN
Q
Y
Y
[get_libs]
asap7_small
[get_nets]
clk1
clk2
clk3
in1
in2
out
r1q
r2q
u1z
u2z
[get_pins]
r1/CLK
r1/D
r1/IQ
r1/IQN
r1/Q
r2/CLK
r2/D
r2/IQ
r2/IQN
r2/Q
r3/CLK
r3/D
r3/IQ
r3/IQN
r3/Q
u1/A
u1/Y
u2/A
u2/B
u2/Y
[get_ports]
clk1
clk2
clk3
in1
in2
out

26
test/get_noargs.tcl Normal file
View File

@ -0,0 +1,26 @@
# get_* with no arguments
# Read in design and libraries
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
# Test each SDC get_* command with no arguments
puts {[get_cells]}
report_object_full_names [get_cells]
puts {[get_clocks]}
report_object_full_names [get_clocks]
puts {[get_lib_cells]}
report_object_full_names [get_lib_cells]
puts {[get_lib_pins]}
report_object_full_names [get_lib_pins]
puts {[get_libs]}
report_object_full_names [get_libs]
puts {[get_nets]}
report_object_full_names [get_nets]
puts {[get_pins]}
report_object_full_names [get_pins]
puts {[get_ports]}
report_object_full_names [get_ports]

45
test/get_objrefs.ok Normal file
View File

@ -0,0 +1,45 @@
[get_cells [all_registers -cells]]
r1
r2
r3
[get_clocks [all_clocks]]
clk
vclk
[get_lib_cells [get_lib_cells]]
asap7_small/AND2x2_ASAP7_75t_R
asap7_small/BUFx2_ASAP7_75t_R
asap7_small/DFFHQx4_ASAP7_75t_R
[get_lib_pins [get_lib_pins]]
A
A
B
CLK
D
IQ
IQN
Q
Y
Y
[get_libs [get_libs]]
asap7_small
[get_nets [get_nets]]
clk1
clk2
clk3
in1
in2
out
r1q
r2q
u1z
u2z
[get_pins [all_registers -data_pins]]
r1/D
r2/D
r3/D
[get_ports [all_inputs]]
clk1
clk2
clk3
in1
in2

29
test/get_objrefs.tcl Normal file
View File

@ -0,0 +1,29 @@
# get_* on object references
# Read in design and libraries
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
# Test that set_driving_cell works with an object reference
set_driving_cell [all_inputs] -lib_cell [lindex [get_lib_cells] 0]
# Test each SDC get_* command on object references
puts {[get_cells [all_registers -cells]]}
report_object_full_names [get_cells [all_registers -cells]]
puts {[get_clocks [all_clocks]]}
report_object_full_names [get_clocks [all_clocks]]
puts {[get_lib_cells [get_lib_cells]]}
report_object_full_names [get_lib_cells [get_lib_cells]]
puts {[get_lib_pins [get_lib_pins]]}
report_object_full_names [get_lib_pins [get_lib_pins]]
puts {[get_libs [get_libs]]}
report_object_full_names [get_libs [get_libs]]
puts {[get_nets [get_nets]]}
report_object_full_names [get_nets [get_nets]]
puts {[get_pins [all_registers -data_pins]]}
report_object_full_names [get_pins [all_registers -data_pins]]
puts {[get_ports [all_inputs]]}
report_object_full_names [get_ports [all_inputs]]

View File

@ -1,220 +0,0 @@
Warning: liberty_arcs_one2one.lib line 48, timing port A and related port Y are different sizes.
Warning: liberty_arcs_one2one.lib line 76, timing port A and related port Y are different sizes.
TEST 1:
Startpoint: a[0] (input port clocked by clk)
Endpoint: y[0] (output port 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 v input external delay
0.00 0.00 v a[0] (in)
1.00 1.00 ^ partial_wide_inv_cell/Y[0] (inv_8_to_4)
0.00 1.00 ^ y[0] (out)
1.00 data arrival time
0.00 0.00 clock clk (rise edge)
0.00 0.00 clock network delay (ideal)
0.00 0.00 clock reconvergence pessimism
0.00 0.00 output external delay
0.00 data required time
---------------------------------------------------------
0.00 data required time
-1.00 data arrival time
---------------------------------------------------------
-1.00 slack (VIOLATED)
Startpoint: a[1] (input port clocked by clk)
Endpoint: y[1] (output port 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 v input external delay
0.00 0.00 v a[1] (in)
1.00 1.00 ^ partial_wide_inv_cell/Y[1] (inv_8_to_4)
0.00 1.00 ^ y[1] (out)
1.00 data arrival time
0.00 0.00 clock clk (rise edge)
0.00 0.00 clock network delay (ideal)
0.00 0.00 clock reconvergence pessimism
0.00 0.00 output external delay
0.00 data required time
---------------------------------------------------------
0.00 data required time
-1.00 data arrival time
---------------------------------------------------------
-1.00 slack (VIOLATED)
Startpoint: a[2] (input port clocked by clk)
Endpoint: y[2] (output port 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 v input external delay
0.00 0.00 v a[2] (in)
1.00 1.00 ^ partial_wide_inv_cell/Y[2] (inv_8_to_4)
0.00 1.00 ^ y[2] (out)
1.00 data arrival time
0.00 0.00 clock clk (rise edge)
0.00 0.00 clock network delay (ideal)
0.00 0.00 clock reconvergence pessimism
0.00 0.00 output external delay
0.00 data required time
---------------------------------------------------------
0.00 data required time
-1.00 data arrival time
---------------------------------------------------------
-1.00 slack (VIOLATED)
Startpoint: a[3] (input port clocked by clk)
Endpoint: y[3] (output port 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 v input external delay
0.00 0.00 v a[3] (in)
1.00 1.00 ^ partial_wide_inv_cell/Y[3] (inv_8_to_4)
0.00 1.00 ^ y[3] (out)
1.00 data arrival time
0.00 0.00 clock clk (rise edge)
0.00 0.00 clock network delay (ideal)
0.00 0.00 clock reconvergence pessimism
0.00 0.00 output external delay
0.00 data required time
---------------------------------------------------------
0.00 data required time
-1.00 data arrival time
---------------------------------------------------------
-1.00 slack (VIOLATED)
TEST 2:
Startpoint: a[0] (input port clocked by clk)
Endpoint: y[0] (output port 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 v input external delay
0.00 0.00 v a[0] (in)
1.00 1.00 ^ partial_wide_inv_cell/Y[0] (inv_4_to_8)
0.00 1.00 ^ y[0] (out)
1.00 data arrival time
0.00 0.00 clock clk (rise edge)
0.00 0.00 clock network delay (ideal)
0.00 0.00 clock reconvergence pessimism
0.00 0.00 output external delay
0.00 data required time
---------------------------------------------------------
0.00 data required time
-1.00 data arrival time
---------------------------------------------------------
-1.00 slack (VIOLATED)
Startpoint: a[1] (input port clocked by clk)
Endpoint: y[1] (output port 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 v input external delay
0.00 0.00 v a[1] (in)
1.00 1.00 ^ partial_wide_inv_cell/Y[1] (inv_4_to_8)
0.00 1.00 ^ y[1] (out)
1.00 data arrival time
0.00 0.00 clock clk (rise edge)
0.00 0.00 clock network delay (ideal)
0.00 0.00 clock reconvergence pessimism
0.00 0.00 output external delay
0.00 data required time
---------------------------------------------------------
0.00 data required time
-1.00 data arrival time
---------------------------------------------------------
-1.00 slack (VIOLATED)
Startpoint: a[2] (input port clocked by clk)
Endpoint: y[2] (output port 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 v input external delay
0.00 0.00 v a[2] (in)
1.00 1.00 ^ partial_wide_inv_cell/Y[2] (inv_4_to_8)
0.00 1.00 ^ y[2] (out)
1.00 data arrival time
0.00 0.00 clock clk (rise edge)
0.00 0.00 clock network delay (ideal)
0.00 0.00 clock reconvergence pessimism
0.00 0.00 output external delay
0.00 data required time
---------------------------------------------------------
0.00 data required time
-1.00 data arrival time
---------------------------------------------------------
-1.00 slack (VIOLATED)
Startpoint: a[3] (input port clocked by clk)
Endpoint: y[3] (output port 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 v input external delay
0.00 0.00 v a[3] (in)
1.00 1.00 ^ partial_wide_inv_cell/Y[3] (inv_4_to_8)
0.00 1.00 ^ y[3] (out)
1.00 data arrival time
0.00 0.00 clock clk (rise edge)
0.00 0.00 clock network delay (ideal)
0.00 0.00 clock reconvergence pessimism
0.00 0.00 output external delay
0.00 data required time
---------------------------------------------------------
0.00 data required time
-1.00 data arrival time
---------------------------------------------------------
-1.00 slack (VIOLATED)

View File

@ -1,17 +0,0 @@
read_liberty liberty_arcs_one2one.lib
puts "TEST 1:"
read_verilog liberty_arcs_one2one_1.v
link_design liberty_arcs_one2one_1
create_clock -name clk -period 0
set_input_delay -clock clk 0 [all_inputs]
set_output_delay -clock clk 0 [all_outputs]
report_checks -group_count 5
puts "TEST 2:"
read_verilog liberty_arcs_one2one_2.v
link_design liberty_arcs_one2one_2
create_clock -name clk -period 0
set_input_delay -clock clk 0 [all_inputs]
set_output_delay -clock clk 0 [all_outputs]
report_checks -group_count 5

View File

@ -1,4 +1,4 @@
library (one_to_one_mismatched_width) {
library (liberty_arcs_one2one_1) {
delay_model : "table_lookup";
simulation : false;
capacitive_load_unit (1,pF);
@ -47,34 +47,7 @@ library (one_to_one_mismatched_width) {
direction : "output";
timing () {
related_pin : "A";
cell_rise (scalar) {
values ("1");
}
cell_fall (scalar) {
values ("1");
}
rise_transition (scalar) {
values ("1");
}
fall_transition (scalar) {
values ("1");
}
}
}
}
cell (inv_4_to_8) {
bus (A) {
capacitance : 1;
bus_type : "bus4";
direction : "input";
}
bus (Y) {
function : "!A";
bus_type : "bus8";
direction : "output";
timing () {
related_pin : "A";
timing_sense : "negative_unate";
cell_rise (scalar) {
values ("1");
}

View File

@ -0,0 +1,21 @@
Warning: liberty_arcs_one2one_1.lib line 48, timing port A and related port Y are different sizes.
report_edges -from partial_wide_inv_cell/A[0]
A[0] -> Y[0] combinational
^ -> v 1.00:1.00
v -> ^ 1.00:1.00
report_edges -from partial_wide_inv_cell/A[1]
A[1] -> Y[1] combinational
^ -> v 1.00:1.00
v -> ^ 1.00:1.00
report_edges -from partial_wide_inv_cell/A[2]
A[2] -> Y[2] combinational
^ -> v 1.00:1.00
v -> ^ 1.00:1.00
report_edges -from partial_wide_inv_cell/A[3]
A[3] -> Y[3] combinational
^ -> v 1.00:1.00
v -> ^ 1.00:1.00
report_edges -from partial_wide_inv_cell/A[4]
report_edges -from partial_wide_inv_cell/A[5]
report_edges -from partial_wide_inv_cell/A[6]
report_edges -from partial_wide_inv_cell/A[7]

View File

@ -0,0 +1,11 @@
# Test one-to-one functionality with mismatched widths where A width (8) is larger than Y width (4)
read_liberty liberty_arcs_one2one_1.lib
read_verilog liberty_arcs_one2one_1.v
link_design liberty_arcs_one2one_1
create_clock -name clk -period 0
set_input_delay -clock clk 0 [all_inputs]
set_output_delay -clock clk 0 [all_outputs]
for {set i 0} {$i < 8} {incr i} {
puts "report_edges -from partial_wide_inv_cell/A[$i]"
report_edges -from partial_wide_inv_cell/A[$i]
}

View File

@ -0,0 +1,66 @@
library (liberty_arcs_one2one_2) {
delay_model : "table_lookup";
simulation : false;
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 : 85.0;
nom_voltage : 0.75;
type (bus8) {
base_type : "array";
data_type : "bit";
bit_width : 8;
bit_from : 7;
bit_to : 0;
}
type (bus4) {
base_type : "array";
data_type : "bit";
bit_width : 4;
bit_from : 3;
bit_to : 0;
}
cell (inv_4_to_8) {
bus (A) {
capacitance : 1;
bus_type : "bus4";
direction : "input";
}
bus (Y) {
function : "!A";
bus_type : "bus8";
direction : "output";
timing () {
related_pin : "A";
timing_sense : "negative_unate";
cell_rise (scalar) {
values ("1");
}
cell_fall (scalar) {
values ("1");
}
rise_transition (scalar) {
values ("1");
}
fall_transition (scalar) {
values ("1");
}
}
}
}
}

View File

@ -0,0 +1,21 @@
Warning: liberty_arcs_one2one_2.lib line 48, timing port A and related port Y are different sizes.
report_edges -to partial_wide_inv_cell/Y[0]
A[0] -> Y[0] combinational
^ -> v 1.00:1.00
v -> ^ 1.00:1.00
report_edges -to partial_wide_inv_cell/Y[1]
A[1] -> Y[1] combinational
^ -> v 1.00:1.00
v -> ^ 1.00:1.00
report_edges -to partial_wide_inv_cell/Y[2]
A[2] -> Y[2] combinational
^ -> v 1.00:1.00
v -> ^ 1.00:1.00
report_edges -to partial_wide_inv_cell/Y[3]
A[3] -> Y[3] combinational
^ -> v 1.00:1.00
v -> ^ 1.00:1.00
report_edges -to partial_wide_inv_cell/Y[4]
report_edges -to partial_wide_inv_cell/Y[5]
report_edges -to partial_wide_inv_cell/Y[6]
report_edges -to partial_wide_inv_cell/Y[7]

View File

@ -0,0 +1,11 @@
# Test one-to-one functionality with mismatched widths where Y width (8) is larger than A width (4)
read_liberty liberty_arcs_one2one_2.lib
read_verilog liberty_arcs_one2one_2.v
link_design liberty_arcs_one2one_2
create_clock -name clk -period 0
set_input_delay -clock clk 0 [all_inputs]
set_output_delay -clock clk 0 [all_outputs]
for {set i 0} {$i < 8} {incr i} {
puts "report_edges -to partial_wide_inv_cell/Y[$i]"
report_edges -to partial_wide_inv_cell/Y[$i]
}

View File

@ -124,8 +124,11 @@ record_example_tests {
record_sta_tests {
prima3
verilog_attribute
liberty_arcs_one2one
liberty_arcs_one2one_1
liberty_arcs_one2one_2
get_filter
get_noargs
get_objrefs
}
define_test_group fast [group_tests all]

View File

@ -1,3 +1,4 @@
# Tests whether Verilog attributes can be parsed and retrieved correctly
read_liberty ../examples/sky130hd_tt.lib
read_verilog verilog_attribute.v
link_design counter

View File

@ -76,6 +76,20 @@ stringPrint(string &str,
str = tmp;
}
void
stringAppend(string &str,
const char *fmt,
...)
{
va_list args;
va_start(args, fmt);
char *tmp;
size_t tmp_length;
stringPrintTmp(fmt, args, tmp, tmp_length);
va_end(args);
str += tmp;
}
string
stdstrPrint(const char *fmt,
...)