Merge remote-tracking branch 'parallax/master'
Signed-off-by: Eder Monteiro <emrmonteiro@precisioninno.com>
This commit is contained in:
commit
3878318e50
|
|
@ -562,8 +562,8 @@ set(CXX_FLAGS -Wall -Wextra -pedantic -Wcast-qual -Wredundant-decls -Wformat-sec
|
|||
|
||||
if(USE_SANITIZE)
|
||||
message(STATUS "Sanitize: ${USE_SANITIZE}")
|
||||
set(CXX_FLAGS "${CXX_FLAGS};-fsanitize=address;-fno-omit-frame-pointer;-fno-common")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-fsanitize=address")
|
||||
set(CXX_FLAGS "${CXX_FLAGS};-fsanitize=thread")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-fsanitize=thread")
|
||||
endif()
|
||||
|
||||
target_compile_options(OpenSTA
|
||||
|
|
|
|||
|
|
@ -314,7 +314,7 @@ CcsCeffDelayCalc::makeResult(const LibertyLibrary *drvr_library,
|
|||
dcalc_result.setGateDelay(gate_delay);
|
||||
dcalc_result.setDrvrSlew(drvr_slew);
|
||||
|
||||
for (const auto [load_pin, load_idx] : load_pin_index_map) {
|
||||
for (const auto &[load_pin, load_idx] : load_pin_index_map) {
|
||||
ArcDelay wire_delay;
|
||||
Slew load_slew;
|
||||
loadDelaySlew(load_pin, drvr_library, rf, drvr_slew, wire_delay, load_slew);
|
||||
|
|
@ -452,7 +452,7 @@ CcsCeffDelayCalc::findVlTime(double v,
|
|||
double t_init = region_ramp_times_[0];
|
||||
double t_final = region_ramp_times_[region_count_];
|
||||
bool root_fail = false;
|
||||
double time = findRoot([=] (double t,
|
||||
double time = findRoot([&] (double t,
|
||||
double &y,
|
||||
double &dy) {
|
||||
vl(t, elmore, y, dy);
|
||||
|
|
|
|||
|
|
@ -343,7 +343,7 @@ DmpAlg::findDriverParams(double ceff)
|
|||
x_[DmpParam::dt] = dt;
|
||||
x_[DmpParam::t0] = t0;
|
||||
newtonRaphson(100, x_, nr_order_, driver_param_tol,
|
||||
[=] () { evalDmpEqns(); },
|
||||
[this] () { evalDmpEqns(); },
|
||||
fvec_, fjac_, index_, p_, scale_);
|
||||
t0_ = x_[DmpParam::t0];
|
||||
dt_ = x_[DmpParam::dt];
|
||||
|
|
@ -494,7 +494,7 @@ DmpAlg::findVoCrossing(double vth,
|
|||
double t_lower,
|
||||
double t_upper)
|
||||
{
|
||||
FindRootFunc vo_func = [=] (double t,
|
||||
FindRootFunc vo_func = [&] (double t,
|
||||
double &y,
|
||||
double &dy) {
|
||||
double vo, vo_dt;
|
||||
|
|
@ -612,7 +612,7 @@ DmpAlg::findVlCrossing(double vth,
|
|||
double t_lower,
|
||||
double t_upper)
|
||||
{
|
||||
FindRootFunc vl_func = [=] (double t,
|
||||
FindRootFunc vl_func = [&] (double t,
|
||||
double &y,
|
||||
double &dy) {
|
||||
double vl, vl_dt;
|
||||
|
|
@ -1516,7 +1516,7 @@ DmpCeffDelayCalc::gateDelay(const Pin *drvr_pin,
|
|||
dcalc_result.setGateDelay(gate_delay);
|
||||
dcalc_result.setDrvrSlew(drvr_slew);
|
||||
|
||||
for (const auto [load_pin, load_idx] : load_pin_index_map) {
|
||||
for (const auto &[load_pin, load_idx] : load_pin_index_map) {
|
||||
ArcDelay wire_delay;
|
||||
Slew load_slew;
|
||||
loadDelaySlew(load_pin, drvr_slew, rf, drvr_library, parasitic,
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include "FindRoot.hh"
|
||||
|
||||
#include <algorithm> // abs
|
||||
#include <cmath> // abs
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ ParallelDelayCalc::gateDelaysParallel(ArcDcalcArgSeq &dcalc_args,
|
|||
slew_sum += 1.0 / drvr_slew;
|
||||
|
||||
dcalc_result.setLoadCount(load_pin_index_map.size());
|
||||
for (const auto [load_pin, load_idx] : load_pin_index_map) {
|
||||
for (const auto &[load_pin, load_idx] : load_pin_index_map) {
|
||||
dcalc_result.setWireDelay(load_idx, gate_result.wireDelay(load_idx));
|
||||
dcalc_result.setLoadSlew(load_idx, gate_result.loadSlew(load_idx));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@ is now supported by the the read_saif command.
|
|||
|
||||
read_saif [-scope scope] filename
|
||||
|
||||
The report_checks -group_count option has been renamed to -group_path_count.
|
||||
The report_checks -endpoing_count option has been renamed to -endpoint_path_count.
|
||||
|
||||
Release 2.5.0 2024/01/17
|
||||
-------------------------
|
||||
|
||||
|
|
|
|||
BIN
doc/OpenSTA.odt
BIN
doc/OpenSTA.odt
Binary file not shown.
BIN
doc/OpenSTA.pdf
BIN
doc/OpenSTA.pdf
Binary file not shown.
693
doc/messages.txt
693
doc/messages.txt
|
|
@ -20,13 +20,15 @@
|
|||
0125 CmdArgs.tcl:696 instance '$arg' not found.
|
||||
0126 CmdArgs.tcl:715 $arg_name type '$object_type' is not an instance.
|
||||
0127 CmdArgs.tcl:722 instance '$arg' not found.
|
||||
0131 CmdArgs.tcl:783 $arg_name type '$object_type' is not a pin or port.
|
||||
0132 CmdArgs.tcl:790 pin '$arg' not found.
|
||||
0133 CmdArgs.tcl:810 $arg_name type '$object_type' is not a port.
|
||||
0139 CmdArgs.tcl:891 unsupported object type $object_type.
|
||||
0141 CmdArgs.tcl:912 $arg_name '$object_type' is not a net.
|
||||
0142 CmdArgs.tcl:936 unsupported object type $object_type.
|
||||
0143 CmdArgs.tcl:917 $arg_name '$arg' not found.
|
||||
0128 CmdArgs.tcl:742 $arg_name type '$object_type' is not a liberty cell.
|
||||
0129 CmdArgs.tcl:749 liberty cell '$arg' not found.
|
||||
0131 CmdArgs.tcl:810 $arg_name type '$object_type' is not a pin or port.
|
||||
0132 CmdArgs.tcl:817 pin '$arg' not found.
|
||||
0133 CmdArgs.tcl:837 $arg_name type '$object_type' is not a port.
|
||||
0139 CmdArgs.tcl:918 unsupported object type $object_type.
|
||||
0141 CmdArgs.tcl:939 $arg_name '$object_type' is not a net.
|
||||
0142 CmdArgs.tcl:963 unsupported object type $object_type.
|
||||
0143 CmdArgs.tcl:944 $arg_name '$arg' not found.
|
||||
0144 CmdArgs.tcl:408 corner object type '$object_type' is not a corner.
|
||||
0160 CmdUtil.tcl:44 no commands match '$pattern'.
|
||||
0161 CmdUtil.tcl:89 Usage: $cmd $cmd_args($cmd)
|
||||
|
|
@ -86,7 +88,7 @@
|
|||
0274 Parasitics.tcl:50 read_spef -delete_after_reduce is deprecated.
|
||||
0275 Parasitics.tcl:54 read_spef -save is deprecated.
|
||||
0276 Parasitics.tcl:62 path instance '$path' not found.
|
||||
0280 PathEnum.cc:572 diversion path not found
|
||||
0280 PathEnum.cc:574 diversion path not found
|
||||
0301 Power.tcl:234 activity should be 0.0 to 1.0 or 2.0
|
||||
0302 Power.tcl:242 duty should be 0.0 to 1.0
|
||||
0303 Power.tcl:257 activity cannot be set on clock ports.
|
||||
|
|
@ -101,12 +103,13 @@
|
|||
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 '$cell_name' is not a liberty cell.
|
||||
0329 Sdc.tcl:689 object '$pattern' is not a liberty pin.
|
||||
0330 Sdc.tcl:769 object '$pattern' is not a liberty library.
|
||||
0331 Sdc.tcl:868 object '$pattern' is not a net.
|
||||
0332 Sdc.tcl:948 object '$pattern' is not a pin.
|
||||
0333 Sdc.tcl:1005 object '$pattern' is not a port.
|
||||
0334 Sdc.tcl:2860 object '$cell_name' is not a liberty cell.
|
||||
0335 Sdc.tcl:679 positional arguments not supported with -of_objects.
|
||||
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'.
|
||||
|
|
@ -122,147 +125,149 @@
|
|||
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.
|
||||
0355 Sdc.tcl:702 library/cell/port '$pattern' not found.
|
||||
0356 Sdc.tcl:722 port '$port_pattern' not found.
|
||||
0357 Sdc.tcl:727 library '$lib_name' not found.
|
||||
0358 Sdc.tcl:742 -nocase ignored without -regexp.
|
||||
0359 Sdc.tcl:778 library '$pattern' not found.
|
||||
0360 Sdc.tcl:849 patterns argument not supported with -of_objects.
|
||||
0361 Sdc.tcl:879 net '$pattern' not found.
|
||||
0362 Sdc.tcl:912 patterns argument not supported with -of_objects.
|
||||
0363 Sdc.tcl:959 pin '$pattern' not found.
|
||||
0365 Sdc.tcl:994 patterns argument not supported with -of_objects.
|
||||
0366 Sdc.tcl:1014 port '$pattern' not found.
|
||||
0368 Sdc.tcl:1054 -add requires -name.
|
||||
0369 Sdc.tcl:1059 -name or port_pin_list must be specified.
|
||||
0370 Sdc.tcl:1067 missing -period argument.
|
||||
0371 Sdc.tcl:1073 -waveform edge_list must have an even number of edge times.
|
||||
0372 Sdc.tcl:1082 non-increasing clock -waveform edge times.
|
||||
0373 Sdc.tcl:1085 -waveform time greater than two periods.
|
||||
0374 Sdc.tcl:1143 empty ports/pins/nets argument.
|
||||
0375 Sdc.tcl:1151 -add requires -name.
|
||||
0376 Sdc.tcl:1156 name or port_pin_list must be specified.
|
||||
0377 Sdc.tcl:1163 missing -source argument.
|
||||
0378 Sdc.tcl:1178 -master_clock argument empty.
|
||||
0379 Sdc.tcl:1181 -add requireds -master_clock.
|
||||
0380 Sdc.tcl:1185 -multiply_by and -divide_by options are exclusive.
|
||||
0381 Sdc.tcl:1189 -divide_by is not an integer greater than one.
|
||||
0382 Sdc.tcl:1192 -combinational implies -divide_by 1.
|
||||
0383 Sdc.tcl:1197 -multiply_by is not an integer greater than one.
|
||||
0384 Sdc.tcl:1203 -duty_cycle is not a float between 0 and 100.
|
||||
0385 Sdc.tcl:1209 -edges only supported for three edges.
|
||||
0386 Sdc.tcl:1215 edges times are not monotonically increasing.
|
||||
0387 Sdc.tcl:1224 -edge_shift length does not match -edges length.
|
||||
0388 Sdc.tcl:1230 missing -multiply_by, -divide_by, -combinational or -edges argument.
|
||||
0389 Sdc.tcl:1238 cannot specify -invert without -multiply_by, -divide_by or -combinational.
|
||||
0390 Sdc.tcl:1244 -duty_cycle requires -multiply_by value.
|
||||
0391 Sdc.tcl:1304 group_path command failed.
|
||||
0392 Sdc.tcl:1311 positional arguments not supported.
|
||||
0393 Sdc.tcl:1315 -from, -through or -to required.
|
||||
0394 Sdc.tcl:1321 -name and -default are mutually exclusive.
|
||||
0395 Sdc.tcl:1323 -name or -default option is required.
|
||||
0396 Sdc.tcl:1364 cannot specify both -high and -low.
|
||||
0397 Sdc.tcl:1372 missing -setup or -hold argument.
|
||||
0398 Sdc.tcl:1386 -high and -low only permitted for pins and instances.
|
||||
0399 Sdc.tcl:1393 -high and -low only permitted for pins and instances.
|
||||
0400 Sdc.tcl:1436 one of -logically_exclusive, -physically_exclusive or -asynchronous is required.
|
||||
0401 Sdc.tcl:1439 the keywords -logically_exclusive, -physically_exclusive and -asynchronous are mutually exclusive.
|
||||
0402 Sdc.tcl:1458 unknown keyword argument $arg.
|
||||
0403 Sdc.tcl:1460 extra positional argument $arg.
|
||||
0404 Sdc.tcl:1489 the -all and -name options are mutually exclusive.
|
||||
0405 Sdc.tcl:1492 either -all or -name options must be specified.
|
||||
0406 Sdc.tcl:1500 one of -logically_exclusive, -physically_exclusive or -asynchronous is required.
|
||||
0407 Sdc.tcl:1503 the keywords -logically_exclusive, -physically_exclusive and -asynchronous are mutually exclusive.
|
||||
0408 Sdc.tcl:1553 -clock ignored for clock objects.
|
||||
0409 Sdc.tcl:1567 -source '[get_full_name $pin]' is not a clock pin.
|
||||
0410 Sdc.tcl:1574 -early/-late is only allowed with -source.
|
||||
0411 Sdc.tcl:1603 -clock ignored for clock objects.
|
||||
0412 Sdc.tcl:1615 -source '[$pin path_name]' is not a clock pin.
|
||||
0413 Sdc.tcl:1643 set_sense -type data not supported.
|
||||
0414 Sdc.tcl:1647 set_sense -type clock|data
|
||||
0415 Sdc.tcl:1658 set_clock_sense is deprecated as of SDC 2.1. Use set_sense -type clock.
|
||||
0416 Sdc.tcl:1670 -pulse argument not supported.
|
||||
0417 Sdc.tcl:1679 -positive, -negative, -stop_propagation and -pulse are mutually exclusive.
|
||||
0418 Sdc.tcl:1692 hierarchical pin '[get_full_name $pin]' not supported.
|
||||
0419 Sdc.tcl:1716 transition time can not be specified for virtual clocks.
|
||||
0420 Sdc.tcl:1749 missing uncertainty value.
|
||||
0421 Sdc.tcl:1797 -from/-to must be used together.
|
||||
0422 Sdc.tcl:1817 -rise, -fall options not allowed for single clock uncertainty.
|
||||
0423 Sdc.tcl:1883 -from/-to must be used together.
|
||||
0424 Sdc.tcl:1903 -rise, -fall options not allowed for single clock uncertainty.
|
||||
0425 Sdc.tcl:1944 missing -from, -rise_from or -fall_from argument.
|
||||
0426 Sdc.tcl:1956 missing -to, -rise_to or -fall_to argument.
|
||||
0427 Sdc.tcl:2004 missing -from, -rise_from or -fall_from argument.
|
||||
0428 Sdc.tcl:2016 missing -to, -rise_to or -fall_to argument.
|
||||
0429 Sdc.tcl:2058 -from/-to keywords ignored for lib_pin, port and pin arguments.
|
||||
0430 Sdc.tcl:2088 -from/-to hierarchical instance not supported.
|
||||
0431 Sdc.tcl:2120 pin '[get_full_name $inst]${hierarchy_separator}${port_name}' not found.
|
||||
0432 Sdc.tcl:2177 pin '[get_name $cell]${hierarchy_separator}${port_name}' not found.
|
||||
0434 Sdc.tcl:2211 -from/-to keywords ignored for lib_pin, port and pin arguments.
|
||||
0435 Sdc.tcl:2263 -from/-to hierarchical instance not supported.
|
||||
0436 Sdc.tcl:2317 '$args' ignored.
|
||||
0437 Sdc.tcl:2321 -from, -through or -to required.
|
||||
0438 Sdc.tcl:2400 -source_latency_included ignored with -reference_pin.
|
||||
0439 Sdc.tcl:2403 -network_latency_included ignored with -reference_pin.
|
||||
0440 Sdc.tcl:2422 $cmd not allowed on [pin_direction $pin] port '[get_full_name $pin]'.
|
||||
0441 Sdc.tcl:2424 $cmd relative to a clock defined on the same port/pin not allowed.
|
||||
0442 Sdc.tcl:2472 missing delay argument.
|
||||
0443 Sdc.tcl:2478 '$args' ignored.
|
||||
0444 Sdc.tcl:2603 missing path multiplier argument.
|
||||
0445 Sdc.tcl:2608 '$args' ignored.
|
||||
0446 Sdc.tcl:2615 cannot use -start with -end.
|
||||
0447 Sdc.tcl:2665 $cmd command failed.
|
||||
0448 Sdc.tcl:2672 positional arguments not supported.
|
||||
0449 Sdc.tcl:2676 -from, -through or -to required.
|
||||
0450 Sdc.tcl:2743 virtual clock [get_name $clk] can not be propagated.
|
||||
0451 Sdc.tcl:2785 value must be 0, zero, 1, one, rise, rising, fall, or falling.
|
||||
0452 Sdc.tcl:2854 cell '$lib_name:$cell_name' not found.
|
||||
0453 Sdc.tcl:2867 '$cell_name' not found.
|
||||
0454 Sdc.tcl:2871 missing -lib_cell argument.
|
||||
0455 Sdc.tcl:2879 port '$to_port_name' not found.
|
||||
0456 Sdc.tcl:2891 -pin argument required for cells with multiple outputs.
|
||||
0457 Sdc.tcl:2906 port '$from_port_name' not found.
|
||||
0458 Sdc.tcl:2924 -multiply_by ignored.
|
||||
0459 Sdc.tcl:2927 -dont_scale ignored.
|
||||
0460 Sdc.tcl:2930 -no_design_rule ignored.
|
||||
0461 Sdc.tcl:2953 set_fanout_load not supported.
|
||||
0462 Sdc.tcl:2977 -clock not supported.
|
||||
0463 Sdc.tcl:2980 -clock_fall not supported.
|
||||
0464 Sdc.tcl:3030 -pin_load not allowed for net objects.
|
||||
0465 Sdc.tcl:3033 -wire_load not allowed for net objects.
|
||||
0466 Sdc.tcl:3036 -rise/-fall not allowed for net objects.
|
||||
0467 Sdc.tcl:3123 port '[get_name $port]' is not an input.
|
||||
0468 Sdc.tcl:3169 -data_path, -clock_path, -rise, -fall ignored for ports and designs.
|
||||
0469 Sdc.tcl:3240 derating factor greater than 2.0.
|
||||
0470 Sdc.tcl:3277 -cell_delay and -cell_check flags ignored for net objects.
|
||||
0471 Sdc.tcl:3347 no valid objects specified for $key.
|
||||
0472 Sdc.tcl:3380 no valid objects specified for $key
|
||||
0473 Sdc.tcl:3429 no valid objects specified for $key.
|
||||
0474 Sdc.tcl:3497 operating condition '$op_cond_name' not found.
|
||||
0475 Sdc.tcl:3515 operating condition '$op_cond_name' not found.
|
||||
0476 Sdc.tcl:3529 -analysis_type must be single, bc_wc or on_chip_variation.
|
||||
0477 Sdc.tcl:3541 set_wire_load_min_block_size not supported.
|
||||
0478 Sdc.tcl:3554 mode must be top, enclosed or segmented.
|
||||
0479 Sdc.tcl:3569 no wire load model specified.
|
||||
0480 Sdc.tcl:3591 wire load model '$model_name' not found.
|
||||
0481 Sdc.tcl:3630 wire load selection group '$selection_name' not found.
|
||||
0482 Sdc.tcl:3718 define_corners must be called before read_liberty.
|
||||
0500 Sdc.tcl:3791 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.
|
||||
0512 Search.tcl:165 -endpoint_count must be a positive integer.
|
||||
0513 Search.tcl:174 -group_count must be >= 1.
|
||||
0514 Search.tcl:205 '$arg' is not a known keyword or flag.
|
||||
0515 Search.tcl:207 positional arguments not supported.
|
||||
0516 Search.tcl:328 report_clock_skew -setup and -hold are mutually exclusive options.
|
||||
0520 Search.tcl:532 analysis type single is not consistent with doing both setup/max and hold/min checks.
|
||||
0521 Search.tcl:537 positional arguments not supported.
|
||||
0522 Search.tcl:791 -min and -max cannot both be specified.
|
||||
0523 Search.tcl:811 pin '$pin_arg' is hierarchical.
|
||||
0524 Search.tcl:867 -format $format not recognized.
|
||||
0526 Search.tcl:1015 specify one of -setup and -hold.
|
||||
0527 Search.tcl:1065 unknown path group '$name'.
|
||||
0502 Search.tcl:165 $cmd -endpoint_count is deprecated. Use -endpoint_path_count instead.
|
||||
0503 Search.tcl:178 $cmd -group_count is deprecated. Use -group_path_count instead.
|
||||
0510 Search.tcl:137 $cmd -path_delay must be min, min_rise, min_fall, max, max_rise, max_fall or min_max.
|
||||
0511 Search.tcl:147 $cmd command failed.
|
||||
0512 Search.tcl:172 -endpoint_path_count must be a positive integer.
|
||||
0513 Search.tcl:186 -group_path_count must be >= 1.
|
||||
0514 Search.tcl:216 '$arg' is not a known keyword or flag.
|
||||
0515 Search.tcl:218 positional arguments not supported.
|
||||
0516 Search.tcl:339 report_clock_skew -setup and -hold are mutually exclusive options.
|
||||
0520 Search.tcl:543 analysis type single is not consistent with doing both setup/max and hold/min checks.
|
||||
0521 Search.tcl:548 positional arguments not supported.
|
||||
0522 Search.tcl:802 -min and -max cannot both be specified.
|
||||
0523 Search.tcl:822 pin '$pin_arg' is hierarchical.
|
||||
0524 Search.tcl:878 -format $format not recognized.
|
||||
0526 Search.tcl:1026 specify one of -setup and -hold.
|
||||
0527 Search.tcl:1076 unknown path group '$name'.
|
||||
0540 Sta.tcl:158 -from/-to arguments not supported with -of_objects.
|
||||
0560 Util.tcl:44 $cmd $key missing value.
|
||||
0561 Util.tcl:61 $cmd $key missing value.
|
||||
|
|
@ -281,7 +286,7 @@
|
|||
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:3709 define_corners must define at least one corner.
|
||||
0577 Sdc.tcl:3721 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.
|
||||
|
|
@ -289,17 +294,17 @@
|
|||
0620 Sdf.tcl:41 -cond_use must be min, max or min_max.
|
||||
0621 Sdf.tcl:46 -cond_use min_max cannot be used with analysis type single.
|
||||
0623 Sdf.tcl:154 SDF -divider must be / or .
|
||||
0800 VcdReader.cc:110 unhandled vcd command.
|
||||
0801 VcdReader.cc:148 timescale syntax error.
|
||||
0802 VcdReader.cc:162 Unknown timescale unit.
|
||||
0804 VcdReader.cc:219 Variable syntax error.
|
||||
0800 VcdReader.cc:112 unhandled vcd command.
|
||||
0801 VcdReader.cc:151 timescale syntax error.
|
||||
0802 VcdReader.cc:165 Unknown timescale unit.
|
||||
0804 VcdReader.cc:222 Variable syntax error.
|
||||
1000 ConcreteNetwork.cc:1973 cell type %s can not be linked.
|
||||
1010 CycleAccting.cc:87 No common period was found between clocks %s and %s.
|
||||
1040 DmpCeff.cc:1510 parasitic Pi model has NaNs.
|
||||
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:556 unknown cudd constant
|
||||
1100 Power.cc:559 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.
|
||||
|
|
@ -317,168 +322,168 @@
|
|||
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:626 library %s already exists.
|
||||
1141 LibertyReader.cc:660 library missing name.
|
||||
1142 LibertyReader.cc:686 default_wire_load %s not found.
|
||||
1143 LibertyReader.cc:697 default_wire_selection %s not found.
|
||||
1144 LibertyReader.cc:709 default_operating_condition %s not found.
|
||||
1145 LibertyReader.cc:719 input_threshold_pct_%s not found.
|
||||
1146 LibertyReader.cc:723 output_threshold_pct_%s not found.
|
||||
1147 LibertyReader.cc:727 slew_lower_threshold_pct_%s not found.
|
||||
1148 LibertyReader.cc:731 slew_upper_threshold_pct_%s not found.
|
||||
1149 LibertyReader.cc:736 Library %s is missing one or more thresholds.
|
||||
1150 LibertyReader.cc:815 unknown unit multiplier %s.
|
||||
1151 LibertyReader.cc:838 unknown unit scale %c.
|
||||
1152 LibertyReader.cc:841 unknown unit suffix %s.
|
||||
1153 LibertyReader.cc:844 unknown unit suffix %s.
|
||||
1154 LibertyReader.cc:869 capacitive_load_units are not ff or pf.
|
||||
1155 LibertyReader.cc:872 capacitive_load_units are not a string.
|
||||
1156 LibertyReader.cc:875 capacitive_load_units missing suffix.
|
||||
1157 LibertyReader.cc:878 capacitive_load_units scale is not a float.
|
||||
1158 LibertyReader.cc:881 capacitive_load_units missing scale and suffix.
|
||||
1159 LibertyReader.cc:884 capacitive_load_unit missing values suffix.
|
||||
1160 LibertyReader.cc:902 delay_model %s not supported.
|
||||
1161 LibertyReader.cc:906 delay_model %s not supported.
|
||||
1162 LibertyReader.cc:910 delay_model %s not supported.
|
||||
1163 LibertyReader.cc:915 delay_model %s not supported..
|
||||
1164 LibertyReader.cc:918 unknown delay_model %s.
|
||||
1165 LibertyReader.cc:937 unknown bus_naming_style format.
|
||||
1166 LibertyReader.cc:958 voltage_map voltage is not a float.
|
||||
1167 LibertyReader.cc:961 voltage_map missing voltage.
|
||||
1168 LibertyReader.cc:964 voltage_map supply name is not a string.
|
||||
1169 LibertyReader.cc:967 voltage_map missing supply name and voltage.
|
||||
1170 LibertyReader.cc:970 voltage_map missing values suffix.
|
||||
1171 LibertyReader.cc:1055 default_max_transition is 0.0.
|
||||
1172 LibertyReader.cc:1070 default_max_fanout is 0.0.
|
||||
1173 LibertyReader.cc:1160 default_fanout_load is 0.0.
|
||||
1174 LibertyReader.cc:1188 default_wire_load_mode %s not found.
|
||||
1175 LibertyReader.cc:1359 table template missing name.
|
||||
1176 LibertyReader.cc:1404 missing variable_%d attribute.
|
||||
1177 LibertyReader.cc:1480 missing table index values.
|
||||
1178 LibertyReader.cc:1486 non-increasing table index values.
|
||||
1179 LibertyReader.cc:1518 bus type %s missing bit_from.
|
||||
1180 LibertyReader.cc:1520 bus type %s missing bit_to.
|
||||
1181 LibertyReader.cc:1524 type missing name.
|
||||
1182 LibertyReader.cc:1551 scaling_factors do not have a name.
|
||||
1183 LibertyReader.cc:1720 operating_conditions missing name.
|
||||
1184 LibertyReader.cc:1791 wire_load missing name.
|
||||
1185 LibertyReader.cc:1834 fanout_length is missing length and fanout.
|
||||
1186 LibertyReader.cc:1849 wire_load_selection missing name.
|
||||
1187 LibertyReader.cc:1880 wireload %s not found.
|
||||
1189 LibertyReader.cc:1887 wire_load_from_area min not a float.
|
||||
1190 LibertyReader.cc:1890 wire_load_from_area max not a float.
|
||||
1191 LibertyReader.cc:1893 wire_load_from_area missing parameters.
|
||||
1192 LibertyReader.cc:1896 wire_load_from_area missing parameters.
|
||||
1193 LibertyReader.cc:1915 cell missing name.
|
||||
1194 LibertyReader.cc:1939 cell %s ocv_derate_group %s not found.
|
||||
1195 LibertyReader.cc:1972 port %s function size does not match port size.
|
||||
1196 LibertyReader.cc:2069 %s %s bus width mismatch.
|
||||
1197 LibertyReader.cc:2080 %s %s bus width mismatch.
|
||||
1198 LibertyReader.cc:2090 clear
|
||||
1199 LibertyReader.cc:2100 preset
|
||||
1200 LibertyReader.cc:2136 latch enable function is non-unate for port %s.
|
||||
1201 LibertyReader.cc:2141 latch enable function is unknown for port %s.
|
||||
1202 LibertyReader.cc:2243 operating conditions %s not found.
|
||||
1203 LibertyReader.cc:2246 scaled_cell missing operating condition.
|
||||
1204 LibertyReader.cc:2249 scaled_cell cell %s has not been defined.
|
||||
1205 LibertyReader.cc:2252 scaled_cell missing name.
|
||||
1206 LibertyReader.cc:2278 scaled_cell %s, %s port functions do not match cell port functions.
|
||||
1207 LibertyReader.cc:2283 scaled_cell ports do not match cell ports.
|
||||
1208 LibertyReader.cc:2285 scaled_cell %s, %s timing does not match cell timing.
|
||||
1209 LibertyReader.cc:2304 combinational timing to an input port.
|
||||
1210 LibertyReader.cc:2399 missing %s_transition.
|
||||
1211 LibertyReader.cc:2401 missing cell_%s.
|
||||
1212 LibertyReader.cc:2422 timing group from output port.
|
||||
1213 LibertyReader.cc:2432 timing group from output port.
|
||||
1214 LibertyReader.cc:2442 timing group from output port.
|
||||
1215 LibertyReader.cc:2477 timing group from output port.
|
||||
1217 LibertyReader.cc:2487 timing group from output port.
|
||||
1218 LibertyReader.cc:2588 receiver_capacitance group not in timing or pin group.
|
||||
1219 LibertyReader.cc:2606 unsupported model axis.
|
||||
1220 LibertyReader.cc:2634 output_current_%s group not in timing group.
|
||||
1221 LibertyReader.cc:2676 output current waveform %.2e %.2e not found.
|
||||
1222 LibertyReader.cc:2697 unsupported model axis.
|
||||
1223 LibertyReader.cc:2739 vector index_1 and index_2 must have exactly one value.
|
||||
1224 LibertyReader.cc:2741 vector reference_time not found.
|
||||
1225 LibertyReader.cc:2774 normalized_driver_waveform variable_2 must be normalized_voltage
|
||||
1226 LibertyReader.cc:2777 normalized_driver_waveform variable_1 must be input_net_transition
|
||||
1228 LibertyReader.cc:2999 level_shifter_type must be HL, LH, or HL_LH
|
||||
1229 LibertyReader.cc:3035 switch_cell_type must be coarse_grain or fine_grain
|
||||
1230 LibertyReader.cc:3059 scaling_factors %s not found.
|
||||
1231 LibertyReader.cc:3120 pin name is not a string.
|
||||
1232 LibertyReader.cc:3137 pin name is not a string.
|
||||
1233 LibertyReader.cc:3151 pin name is not a string.
|
||||
1234 LibertyReader.cc:3229 bus %s bus_type not found.
|
||||
1235 LibertyReader.cc:3281 bus_type %s not found.
|
||||
1236 LibertyReader.cc:3284 bus_type is not a string.
|
||||
1237 LibertyReader.cc:3302 bundle %s member not found.
|
||||
1238 LibertyReader.cc:3325 member is not a string.
|
||||
1239 LibertyReader.cc:3332 members attribute is missing values.
|
||||
1240 LibertyReader.cc:3383 unknown port direction.
|
||||
1241 LibertyReader.cc:3630 max_transition is 0.0.
|
||||
1242 LibertyReader.cc:3736 pulse_latch unknown pulse type.
|
||||
1243 LibertyReader.cc:4155 timing group missing related_pin/related_bus_pin.
|
||||
1244 LibertyReader.cc:4254 unknown timing_type %s.
|
||||
1245 LibertyReader.cc:4274 unknown timing_sense %s.
|
||||
1246 LibertyReader.cc:4314 mode value is not a string.
|
||||
1247 LibertyReader.cc:4317 missing mode value.
|
||||
1248 LibertyReader.cc:4320 mode name is not a string.
|
||||
1249 LibertyReader.cc:4323 mode missing values.
|
||||
1250 LibertyReader.cc:4326 mode missing mode name and value.
|
||||
1251 LibertyReader.cc:4402 unsupported model axis.
|
||||
1252 LibertyReader.cc:4429 unsupported model axis.
|
||||
1253 LibertyReader.cc:4458 unsupported model axis.
|
||||
1254 LibertyReader.cc:4493 unsupported model axis.
|
||||
1255 LibertyReader.cc:4509 %s group not in timing group.
|
||||
1256 LibertyReader.cc:4548 table template %s not found.
|
||||
1257 LibertyReader.cc:4632 %s is missing values.
|
||||
1258 LibertyReader.cc:4655 %s is not a list of floats.
|
||||
1259 LibertyReader.cc:4657 table row has %u columns but axis has %d.
|
||||
1260 LibertyReader.cc:4667 table has %u rows but axis has %d.
|
||||
1261 LibertyReader.cc:4718 lut output is not a string.
|
||||
1262 LibertyReader.cc:4734 cell %s test_cell redefinition.
|
||||
1263 LibertyReader.cc:4773 mode definition missing name.
|
||||
1264 LibertyReader.cc:4790 mode value missing name.
|
||||
1265 LibertyReader.cc:4804 when attribute inside table model.
|
||||
1266 LibertyReader.cc:4853 %s attribute is not a string.
|
||||
1267 LibertyReader.cc:4856 %s is not a simple attribute.
|
||||
1268 LibertyReader.cc:4876 %s attribute is not an integer.
|
||||
1269 LibertyReader.cc:4879 %s is not a simple attribute.
|
||||
1270 LibertyReader.cc:4892 %s is not a simple attribute.
|
||||
1271 LibertyReader.cc:4918 %s value %s is not a float.
|
||||
1272 LibertyReader.cc:4947 %s missing values.
|
||||
1273 LibertyReader.cc:4951 %s missing values.
|
||||
1274 LibertyReader.cc:4954 %s is not a complex attribute.
|
||||
1275 LibertyReader.cc:4980 %s is not a float.
|
||||
1276 LibertyReader.cc:5003 %s is missing values.
|
||||
1277 LibertyReader.cc:5006 %s has more than one string.
|
||||
1278 LibertyReader.cc:5015 %s is missing values.
|
||||
1279 LibertyReader.cc:5040 %s attribute is not boolean.
|
||||
1280 LibertyReader.cc:5043 %s attribute is not boolean.
|
||||
1281 LibertyReader.cc:5046 %s is not a simple attribute.
|
||||
1282 LibertyReader.cc:5062 attribute %s value %s not recognized.
|
||||
1283 LibertyReader.cc:5093 unknown early/late value.
|
||||
1284 LibertyReader.cc:5313 OCV derate group named %s not found.
|
||||
1285 LibertyReader.cc:5329 ocv_derate missing name.
|
||||
1286 LibertyReader.cc:5382 unknown rise/fall.
|
||||
1287 LibertyReader.cc:5402 unknown derate type.
|
||||
1288 LibertyReader.cc:5434 unsupported model axis.
|
||||
1289 LibertyReader.cc:5466 unsupported model axis.
|
||||
1290 LibertyReader.cc:5498 unsupported model axis.
|
||||
1291 LibertyReader.cc:5569 unknown pg_type.
|
||||
1292 LibertyReader.cc:5983 port %s subscript out of range.
|
||||
1293 LibertyReader.cc:5987 port range %s of non-bus port %s.
|
||||
1294 LibertyReader.cc:6001 port %s not found.
|
||||
1295 LibertyReader.cc:6071 port %s not found.
|
||||
1297 LibertyReader.cc:1446 axis type %s not supported.
|
||||
1298 LibertyReader.cc:2160 statetable input port %s not found.
|
||||
1299 LibertyReader.cc:3785 unknown signal_type %s.
|
||||
1300 LibertyReader.cc:4029 table row must have 3 groups separated by ':'.
|
||||
1301 LibertyReader.cc:4034 table row has %zu input values but %zu are required.
|
||||
1302 LibertyReader.cc:4041 table row has %zu current values but %zu are required.
|
||||
1303 LibertyReader.cc:4048 table row has %zu next values but %zu are required.
|
||||
1304 LibertyReader.cc:4094 table input value '%s' not recognized.
|
||||
1305 LibertyReader.cc:4113 table internal value '%s' not recognized.
|
||||
1140 LibertyReader.cc:632 library %s already exists.
|
||||
1141 LibertyReader.cc:665 library missing name.
|
||||
1142 LibertyReader.cc:691 default_wire_load %s not found.
|
||||
1143 LibertyReader.cc:702 default_wire_selection %s not found.
|
||||
1144 LibertyReader.cc:714 default_operating_condition %s not found.
|
||||
1145 LibertyReader.cc:724 input_threshold_pct_%s not found.
|
||||
1146 LibertyReader.cc:728 output_threshold_pct_%s not found.
|
||||
1147 LibertyReader.cc:732 slew_lower_threshold_pct_%s not found.
|
||||
1148 LibertyReader.cc:736 slew_upper_threshold_pct_%s not found.
|
||||
1149 LibertyReader.cc:741 Library %s is missing one or more thresholds.
|
||||
1150 LibertyReader.cc:820 unknown unit multiplier %s.
|
||||
1151 LibertyReader.cc:843 unknown unit scale %c.
|
||||
1152 LibertyReader.cc:846 unknown unit suffix %s.
|
||||
1153 LibertyReader.cc:849 unknown unit suffix %s.
|
||||
1154 LibertyReader.cc:874 capacitive_load_units are not ff or pf.
|
||||
1155 LibertyReader.cc:877 capacitive_load_units are not a string.
|
||||
1156 LibertyReader.cc:880 capacitive_load_units missing suffix.
|
||||
1157 LibertyReader.cc:883 capacitive_load_units scale is not a float.
|
||||
1158 LibertyReader.cc:886 capacitive_load_units missing scale and suffix.
|
||||
1159 LibertyReader.cc:889 capacitive_load_unit missing values suffix.
|
||||
1160 LibertyReader.cc:907 delay_model %s not supported.
|
||||
1161 LibertyReader.cc:911 delay_model %s not supported.
|
||||
1162 LibertyReader.cc:915 delay_model %s not supported.
|
||||
1163 LibertyReader.cc:920 delay_model %s not supported..
|
||||
1164 LibertyReader.cc:923 unknown delay_model %s.
|
||||
1165 LibertyReader.cc:942 unknown bus_naming_style format.
|
||||
1166 LibertyReader.cc:963 voltage_map voltage is not a float.
|
||||
1167 LibertyReader.cc:966 voltage_map missing voltage.
|
||||
1168 LibertyReader.cc:969 voltage_map supply name is not a string.
|
||||
1169 LibertyReader.cc:972 voltage_map missing supply name and voltage.
|
||||
1170 LibertyReader.cc:975 voltage_map missing values suffix.
|
||||
1171 LibertyReader.cc:1060 default_max_transition is 0.0.
|
||||
1172 LibertyReader.cc:1075 default_max_fanout is 0.0.
|
||||
1173 LibertyReader.cc:1165 default_fanout_load is 0.0.
|
||||
1174 LibertyReader.cc:1193 default_wire_load_mode %s not found.
|
||||
1175 LibertyReader.cc:1379 table template missing name.
|
||||
1176 LibertyReader.cc:1424 missing variable_%d attribute.
|
||||
1177 LibertyReader.cc:1500 missing table index values.
|
||||
1178 LibertyReader.cc:1506 non-increasing table index values.
|
||||
1179 LibertyReader.cc:1538 bus type %s missing bit_from.
|
||||
1180 LibertyReader.cc:1540 bus type %s missing bit_to.
|
||||
1181 LibertyReader.cc:1544 type missing name.
|
||||
1182 LibertyReader.cc:1571 scaling_factors do not have a name.
|
||||
1183 LibertyReader.cc:1740 operating_conditions missing name.
|
||||
1184 LibertyReader.cc:1811 wire_load missing name.
|
||||
1185 LibertyReader.cc:1854 fanout_length is missing length and fanout.
|
||||
1186 LibertyReader.cc:1869 wire_load_selection missing name.
|
||||
1187 LibertyReader.cc:1900 wireload %s not found.
|
||||
1189 LibertyReader.cc:1907 wire_load_from_area min not a float.
|
||||
1190 LibertyReader.cc:1910 wire_load_from_area max not a float.
|
||||
1191 LibertyReader.cc:1913 wire_load_from_area missing parameters.
|
||||
1192 LibertyReader.cc:1916 wire_load_from_area missing parameters.
|
||||
1193 LibertyReader.cc:1935 cell missing name.
|
||||
1194 LibertyReader.cc:1959 cell %s ocv_derate_group %s not found.
|
||||
1195 LibertyReader.cc:1992 port %s function size does not match port size.
|
||||
1196 LibertyReader.cc:2089 %s %s bus width mismatch.
|
||||
1197 LibertyReader.cc:2100 %s %s bus width mismatch.
|
||||
1198 LibertyReader.cc:2110 clear
|
||||
1199 LibertyReader.cc:2120 preset
|
||||
1200 LibertyReader.cc:2156 latch enable function is non-unate for port %s.
|
||||
1201 LibertyReader.cc:2161 latch enable function is unknown for port %s.
|
||||
1202 LibertyReader.cc:2263 operating conditions %s not found.
|
||||
1203 LibertyReader.cc:2266 scaled_cell missing operating condition.
|
||||
1204 LibertyReader.cc:2269 scaled_cell cell %s has not been defined.
|
||||
1205 LibertyReader.cc:2272 scaled_cell missing name.
|
||||
1206 LibertyReader.cc:2298 scaled_cell %s, %s port functions do not match cell port functions.
|
||||
1207 LibertyReader.cc:2303 scaled_cell ports do not match cell ports.
|
||||
1208 LibertyReader.cc:2305 scaled_cell %s, %s timing does not match cell timing.
|
||||
1209 LibertyReader.cc:2324 combinational timing to an input port.
|
||||
1210 LibertyReader.cc:2419 missing %s_transition.
|
||||
1211 LibertyReader.cc:2421 missing cell_%s.
|
||||
1212 LibertyReader.cc:2442 timing group from output port.
|
||||
1213 LibertyReader.cc:2452 timing group from output port.
|
||||
1214 LibertyReader.cc:2462 timing group from output port.
|
||||
1215 LibertyReader.cc:2497 timing group from output port.
|
||||
1217 LibertyReader.cc:2507 timing group from output port.
|
||||
1218 LibertyReader.cc:2608 receiver_capacitance group not in timing or pin group.
|
||||
1219 LibertyReader.cc:2626 unsupported model axis.
|
||||
1220 LibertyReader.cc:2654 output_current_%s group not in timing group.
|
||||
1221 LibertyReader.cc:2696 output current waveform %.2e %.2e not found.
|
||||
1222 LibertyReader.cc:2717 unsupported model axis.
|
||||
1223 LibertyReader.cc:2759 vector index_1 and index_2 must have exactly one value.
|
||||
1224 LibertyReader.cc:2761 vector reference_time not found.
|
||||
1225 LibertyReader.cc:2794 normalized_driver_waveform variable_2 must be normalized_voltage
|
||||
1226 LibertyReader.cc:2797 normalized_driver_waveform variable_1 must be input_net_transition
|
||||
1228 LibertyReader.cc:3019 level_shifter_type must be HL, LH, or HL_LH
|
||||
1229 LibertyReader.cc:3055 switch_cell_type must be coarse_grain or fine_grain
|
||||
1230 LibertyReader.cc:3079 scaling_factors %s not found.
|
||||
1231 LibertyReader.cc:3140 pin name is not a string.
|
||||
1232 LibertyReader.cc:3157 pin name is not a string.
|
||||
1233 LibertyReader.cc:3171 pin name is not a string.
|
||||
1234 LibertyReader.cc:3243 bus %s bus_type not found.
|
||||
1235 LibertyReader.cc:3295 bus_type %s not found.
|
||||
1236 LibertyReader.cc:3298 bus_type is not a string.
|
||||
1237 LibertyReader.cc:3316 bundle %s member not found.
|
||||
1238 LibertyReader.cc:3339 member is not a string.
|
||||
1239 LibertyReader.cc:3346 members attribute is missing values.
|
||||
1240 LibertyReader.cc:3397 unknown port direction.
|
||||
1241 LibertyReader.cc:3644 max_transition is 0.0.
|
||||
1242 LibertyReader.cc:3750 pulse_latch unknown pulse type.
|
||||
1243 LibertyReader.cc:4194 timing group missing related_pin/related_bus_pin.
|
||||
1244 LibertyReader.cc:4293 unknown timing_type %s.
|
||||
1245 LibertyReader.cc:4313 unknown timing_sense %s.
|
||||
1246 LibertyReader.cc:4353 mode value is not a string.
|
||||
1247 LibertyReader.cc:4356 missing mode value.
|
||||
1248 LibertyReader.cc:4359 mode name is not a string.
|
||||
1249 LibertyReader.cc:4362 mode missing values.
|
||||
1250 LibertyReader.cc:4365 mode missing mode name and value.
|
||||
1251 LibertyReader.cc:4441 unsupported model axis.
|
||||
1252 LibertyReader.cc:4468 unsupported model axis.
|
||||
1253 LibertyReader.cc:4497 unsupported model axis.
|
||||
1254 LibertyReader.cc:4532 unsupported model axis.
|
||||
1255 LibertyReader.cc:4548 %s group not in timing group.
|
||||
1256 LibertyReader.cc:4587 table template %s not found.
|
||||
1257 LibertyReader.cc:4671 %s is missing values.
|
||||
1258 LibertyReader.cc:4694 %s is not a list of floats.
|
||||
1259 LibertyReader.cc:4696 table row has %u columns but axis has %d.
|
||||
1260 LibertyReader.cc:4706 table has %u rows but axis has %d.
|
||||
1261 LibertyReader.cc:4757 lut output is not a string.
|
||||
1262 LibertyReader.cc:4773 cell %s test_cell redefinition.
|
||||
1263 LibertyReader.cc:4821 mode definition missing name.
|
||||
1264 LibertyReader.cc:4838 mode value missing name.
|
||||
1265 LibertyReader.cc:4852 when attribute inside table model.
|
||||
1266 LibertyReader.cc:4901 %s attribute is not a string.
|
||||
1267 LibertyReader.cc:4904 %s is not a simple attribute.
|
||||
1268 LibertyReader.cc:4924 %s attribute is not an integer.
|
||||
1269 LibertyReader.cc:4927 %s is not a simple attribute.
|
||||
1270 LibertyReader.cc:4940 %s is not a simple attribute.
|
||||
1271 LibertyReader.cc:4966 %s value %s is not a float.
|
||||
1272 LibertyReader.cc:4995 %s missing values.
|
||||
1273 LibertyReader.cc:4999 %s missing values.
|
||||
1274 LibertyReader.cc:5002 %s is not a complex attribute.
|
||||
1275 LibertyReader.cc:5028 %s is not a float.
|
||||
1276 LibertyReader.cc:5051 %s is missing values.
|
||||
1277 LibertyReader.cc:5054 %s has more than one string.
|
||||
1278 LibertyReader.cc:5063 %s is missing values.
|
||||
1279 LibertyReader.cc:5088 %s attribute is not boolean.
|
||||
1280 LibertyReader.cc:5091 %s attribute is not boolean.
|
||||
1281 LibertyReader.cc:5094 %s is not a simple attribute.
|
||||
1282 LibertyReader.cc:5110 attribute %s value %s not recognized.
|
||||
1283 LibertyReader.cc:5141 unknown early/late value.
|
||||
1284 LibertyReader.cc:5361 OCV derate group named %s not found.
|
||||
1285 LibertyReader.cc:5377 ocv_derate missing name.
|
||||
1286 LibertyReader.cc:5430 unknown rise/fall.
|
||||
1287 LibertyReader.cc:5450 unknown derate type.
|
||||
1288 LibertyReader.cc:5482 unsupported model axis.
|
||||
1289 LibertyReader.cc:5514 unsupported model axis.
|
||||
1290 LibertyReader.cc:5546 unsupported model axis.
|
||||
1291 LibertyReader.cc:5617 unknown pg_type.
|
||||
1292 LibertyReader.cc:6031 port %s subscript out of range.
|
||||
1293 LibertyReader.cc:6035 port range %s of non-bus port %s.
|
||||
1294 LibertyReader.cc:6049 port %s not found.
|
||||
1295 LibertyReader.cc:6119 port %s not found.
|
||||
1297 LibertyReader.cc:1466 axis type %s not supported.
|
||||
1298 LibertyReader.cc:2180 statetable input port %s not found.
|
||||
1299 LibertyReader.cc:3809 unknown signal_type %s.
|
||||
1300 LibertyReader.cc:4068 table row must have 3 groups separated by ':'.
|
||||
1301 LibertyReader.cc:4073 table row has %zu input values but %zu are required.
|
||||
1302 LibertyReader.cc:4080 table row has %zu current values but %zu are required.
|
||||
1303 LibertyReader.cc:4087 table row has %zu next values but %zu are required.
|
||||
1304 LibertyReader.cc:4133 table input value '%s' not recognized.
|
||||
1305 LibertyReader.cc:4152 table internal value '%s' not recognized.
|
||||
1340 LibertyWriter.cc:307 %s/%s bundled ports not supported.
|
||||
1341 LibertyWriter.cc:455 %s/%s/%s timing model not supported.
|
||||
1342 LibertyWriter.cc:475 3 axis table models not supported.
|
||||
|
|
@ -486,7 +491,7 @@
|
|||
1350 LumpedCapDelayCalc.cc:138 gate delay input variable is NaN
|
||||
1355 MakeTimingModel.cc:227 clock %s pin %s is inside model block.
|
||||
1360 Vcd.cc:172 Unknown variable %s ID %s
|
||||
1370 PathEnum.cc:476 path diversion missing edge.
|
||||
1370 PathEnum.cc:478 path diversion missing edge.
|
||||
1398 VerilogReader.cc:1860 %s is not a verilog module.
|
||||
1399 VerilogReader.cc:1865 %s is not a verilog module.
|
||||
1400 PathVertex.cc:236 missing arrivals.
|
||||
|
|
@ -507,33 +512,33 @@
|
|||
1554 Sta.cc:1996 '%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:1120 POCV support requires compilation with SSTA=1.
|
||||
1575 Search.i:529 unknown report path field %s
|
||||
1576 Search.i:541 unknown report path field %s
|
||||
1574 Search.i:1121 POCV support requires compilation with SSTA=1.
|
||||
1575 Search.i:530 unknown report path field %s
|
||||
1576 Search.i:542 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,
|
||||
1604 WriteSpice.cc:1019 no register/latch found for path from %s to %s,
|
||||
1605 WriteSpice.cc:241 The subkct file %s is missing definitions for %s
|
||||
1606 WriteSpice.cc:270 subckt %s port %s has no corresponding liberty port, pg_port and is not power or ground.
|
||||
1640 SpefReader.cc:154 illegal bus delimiters.
|
||||
1641 SpefReader.cc:238 unknown units %s.
|
||||
1642 SpefReader.cc:251 unknown units %s.
|
||||
1643 SpefReader.cc:264 unknown units %s.
|
||||
1644 SpefReader.cc:279 unknown units %s.
|
||||
1645 SpefReader.cc:300 no name map entry for %d.
|
||||
1646 SpefReader.cc:319 unknown port direction %s.
|
||||
1647 SpefReader.cc:346 pin %s not found.
|
||||
1648 SpefReader.cc:349 instance %s not found.
|
||||
1650 SpefReader.cc:369 net %s not found.
|
||||
1651 SpefReader.cc:483 %s not connected to net %s.
|
||||
1652 SpefReader.cc:489 pin %s not found.
|
||||
1653 SpefReader.cc:503 %s not connected to net %s.
|
||||
1654 SpefReader.cc:509 node %s not a pin or net:number
|
||||
1655 SpefReader.cc:521 %s not connected to net %s.
|
||||
1656 SpefReader.cc:525 pin %s not found.
|
||||
1657 SpefReader.cc:642 %s.
|
||||
1658 SpefReader.cc:60 Delay calculator %s does not support reduction.
|
||||
1640 SpefReader.cc:157 illegal bus delimiters.
|
||||
1641 SpefReader.cc:241 unknown units %s.
|
||||
1642 SpefReader.cc:254 unknown units %s.
|
||||
1643 SpefReader.cc:267 unknown units %s.
|
||||
1644 SpefReader.cc:282 unknown units %s.
|
||||
1645 SpefReader.cc:303 no name map entry for %d.
|
||||
1646 SpefReader.cc:322 unknown port direction %s.
|
||||
1647 SpefReader.cc:349 pin %s not found.
|
||||
1648 SpefReader.cc:352 instance %s not found.
|
||||
1650 SpefReader.cc:372 net %s not found.
|
||||
1651 SpefReader.cc:486 %s not connected to net %s.
|
||||
1652 SpefReader.cc:492 pin %s not found.
|
||||
1653 SpefReader.cc:506 %s not connected to net %s.
|
||||
1654 SpefReader.cc:512 node %s not a pin or net:number
|
||||
1655 SpefReader.cc:524 %s not connected to net %s.
|
||||
1656 SpefReader.cc:528 pin %s not found.
|
||||
1657 SpefReader.cc:645 %s.
|
||||
1658 SpefReader.cc:61 Delay calculator %s does not support reduction.
|
||||
1700 CcsCeffDelayCalc.cc:102 VDD not defined in library %s
|
||||
1701 CcsCeffDelayCalc.cc:273 unsupported ccs region count.
|
||||
1720 PrimaDelayCalc.cc:229 VDD not defined in library %s
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ public:
|
|||
int index() const { return index_; }
|
||||
bool isPropagated() const { return is_propagated_; }
|
||||
void setIsPropagated(bool propagated);
|
||||
bool isIdeal() const { return !is_propagated_; }
|
||||
// Ideal clock slew.
|
||||
void slew(const RiseFall *rf,
|
||||
const MinMax *min_max,
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class LibertyCell;
|
|||
class LibertyPort;
|
||||
|
||||
typedef Map<const char*, ConcreteCell*, CharPtrLess> ConcreteCellMap;
|
||||
typedef Map<string, string> AttributeMap;
|
||||
typedef std::map<string, string> AttributeMap;
|
||||
typedef Vector<ConcretePort*> ConcretePortSeq;
|
||||
typedef Map<const char*, ConcretePort*, CharPtrLess> ConcretePortMap;
|
||||
typedef ConcreteCellMap::ConstIterator ConcreteLibraryCellIterator;
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class ConcreteBindingTbl;
|
|||
class ConcreteLibertyLibraryIterator;
|
||||
|
||||
typedef Vector<ConcreteLibrary*> ConcreteLibrarySeq;
|
||||
typedef Map<string, string> AttributeMap;
|
||||
typedef std::map<string, string> AttributeMap;
|
||||
typedef Map<const char*, ConcreteLibrary*, CharPtrLess> ConcreteLibraryMap;
|
||||
typedef ConcreteLibrarySeq::ConstIterator ConcreteLibraryIterator;
|
||||
typedef Map<const char *, ConcreteInstance*,
|
||||
|
|
|
|||
|
|
@ -1147,5 +1147,7 @@ private:
|
|||
|
||||
string
|
||||
portLibertyToSta(const char *port_name);
|
||||
const char *
|
||||
scanSignalTypeName(ScanSignalType scan_type);
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ class TableAxis;
|
|||
class GateTimingModel;
|
||||
class CheckTimingModel;
|
||||
class ScaleFactors;
|
||||
class Group;
|
||||
class Wireload;
|
||||
class WireloadSelection;
|
||||
class TimingArcSet;
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ public:
|
|||
// Required time with source clock offset.
|
||||
virtual Required requiredTimeOffset(const StaState *sta) const;
|
||||
virtual ArcDelay margin(const StaState *sta) const = 0;
|
||||
virtual float macroClkTreeDelay(const StaState *) const { return 0.0; }
|
||||
virtual Slack slack(const StaState *sta) const = 0;
|
||||
virtual Slack slackNoCrpr(const StaState *sta) const = 0;
|
||||
virtual Arrival borrow(const StaState *sta) const;
|
||||
|
|
@ -324,6 +325,7 @@ public:
|
|||
virtual void reportFull(ReportPath *report) const;
|
||||
virtual bool isCheck() const { return true; }
|
||||
virtual ArcDelay margin(const StaState *sta) const;
|
||||
virtual float macroClkTreeDelay(const StaState *sta) const;
|
||||
virtual TimingRole *checkRole(const StaState *sta) const;
|
||||
virtual TimingArc *checkArc() const { return check_arc_; }
|
||||
virtual int exceptPathCmp(const PathEnd *path_end,
|
||||
|
|
@ -339,6 +341,7 @@ protected:
|
|||
Crpr crpr,
|
||||
bool crpr_valid);
|
||||
Delay sourceClkDelay(const StaState *sta) const;
|
||||
virtual Required requiredTimeNoCrpr(const StaState *sta) const;
|
||||
|
||||
TimingArc *check_arc_;
|
||||
Edge *check_edge_;
|
||||
|
|
|
|||
|
|
@ -40,15 +40,15 @@ public:
|
|||
virtual ~PathGroup();
|
||||
// Path group that compares compare slacks.
|
||||
static PathGroup *makePathGroupArrival(const char *name,
|
||||
int group_count,
|
||||
int endpoint_count,
|
||||
int group_path_count,
|
||||
int endpoint_path_count,
|
||||
bool unique_pins,
|
||||
const MinMax *min_max,
|
||||
const StaState *sta);
|
||||
// Path group that compares arrival time, sorted by min_max.
|
||||
static PathGroup *makePathGroupSlack(const char *name,
|
||||
int group_count,
|
||||
int endpoint_count,
|
||||
int group_path_count,
|
||||
int endpoint_path_count,
|
||||
bool unique_pins,
|
||||
float min_slack,
|
||||
float max_slack,
|
||||
|
|
@ -57,20 +57,20 @@ public:
|
|||
const MinMax *minMax() const { return min_max_;}
|
||||
const PathEndSeq &pathEnds() const { return path_ends_; }
|
||||
void insert(PathEnd *path_end);
|
||||
// Push group_count into path_ends.
|
||||
// Push group_path_count into path_ends.
|
||||
void pushEnds(PathEndSeq &path_ends);
|
||||
// Predicates to determine if a PathEnd is worth saving.
|
||||
virtual bool savable(PathEnd *path_end);
|
||||
int maxPaths() const { return group_count_; }
|
||||
int maxPaths() const { return group_path_count_; }
|
||||
PathGroupIterator *iterator();
|
||||
// This does NOT delete the path ends.
|
||||
void clear();
|
||||
static int group_count_max;
|
||||
static int group_path_count_max;
|
||||
|
||||
protected:
|
||||
PathGroup(const char *name,
|
||||
int group_count,
|
||||
int endpoint_count,
|
||||
int group_path_count,
|
||||
int endpoint_path_count,
|
||||
bool unique_pins,
|
||||
float min_slack,
|
||||
float max_slack,
|
||||
|
|
@ -82,8 +82,8 @@ protected:
|
|||
void sort();
|
||||
|
||||
const char *name_;
|
||||
int group_count_;
|
||||
int endpoint_count_;
|
||||
int group_path_count_;
|
||||
int endpoint_path_count_;
|
||||
bool unique_pins_;
|
||||
float slack_min_;
|
||||
float slack_max_;
|
||||
|
|
@ -98,8 +98,8 @@ protected:
|
|||
class PathGroups : public StaState
|
||||
{
|
||||
public:
|
||||
PathGroups(int group_count,
|
||||
int endpoint_count,
|
||||
PathGroups(int group_path_count,
|
||||
int endpoint_path_count,
|
||||
bool unique_pins,
|
||||
float slack_min,
|
||||
float slack_max,
|
||||
|
|
@ -130,8 +130,8 @@ public:
|
|||
|
||||
protected:
|
||||
void makeGroupPathEnds(ExceptionTo *to,
|
||||
int group_count,
|
||||
int endpoint_count,
|
||||
int group_path_count,
|
||||
int endpoint_path_count,
|
||||
bool unique_pins,
|
||||
const Corner *corner,
|
||||
const MinMaxAll *min_max);
|
||||
|
|
@ -144,8 +144,8 @@ protected:
|
|||
const MinMaxAll *min_max,
|
||||
PathEndVisitor *visitor);
|
||||
void enumPathEnds(PathGroup *group,
|
||||
int group_count,
|
||||
int endpoint_count,
|
||||
int group_path_count,
|
||||
int endpoint_path_count,
|
||||
bool unique_pins,
|
||||
bool cmp_slack);
|
||||
|
||||
|
|
@ -153,8 +153,8 @@ protected:
|
|||
void pushUnconstrainedPathEnds(PathEndSeq &path_ends,
|
||||
const MinMaxAll *min_max);
|
||||
|
||||
void makeGroups(int group_count,
|
||||
int endpoint_count,
|
||||
void makeGroups(int group_path_count,
|
||||
int endpoint_path_count,
|
||||
bool unique_pins,
|
||||
float slack_min,
|
||||
float slack_max,
|
||||
|
|
@ -168,8 +168,8 @@ protected:
|
|||
PathGroupNameSet *group_names) const;
|
||||
GroupPath *groupPathTo(const PathEnd *path_end) const;
|
||||
|
||||
int group_count_;
|
||||
int endpoint_count_;
|
||||
int group_path_count_;
|
||||
int endpoint_path_count_;
|
||||
bool unique_pins_;
|
||||
float slack_min_;
|
||||
float slack_max_;
|
||||
|
|
|
|||
|
|
@ -112,6 +112,18 @@ private:
|
|||
const Network *network_;
|
||||
};
|
||||
|
||||
class NetWireCaps : public MinMaxFloatValues
|
||||
{
|
||||
public:
|
||||
NetWireCaps();
|
||||
bool subtractPinCap(const MinMax *min_max);
|
||||
void setSubtractPinCap(bool subtrace_pin_cap,
|
||||
const MinMax *min_max);
|
||||
|
||||
private:
|
||||
bool subtract_pin_cap_[MinMax::index_count];
|
||||
};
|
||||
|
||||
typedef Map<const char*,Clock*, CharPtrLess> ClockNameMap;
|
||||
typedef UnorderedMap<const Pin*, ClockSet*, PinIdHash> ClockPinMap;
|
||||
typedef Set<InputDelay*> InputDelaySet;
|
||||
|
|
@ -149,8 +161,8 @@ typedef Map<const Pin*, MinMaxFloatValues> PinCapLimitMap;
|
|||
typedef Map<const Port*, MinMaxFloatValues> PortFanoutLimitMap;
|
||||
typedef Map<const Cell*, MinMaxFloatValues> CellFanoutLimitMap;
|
||||
typedef Map<const Port*, PortExtCap*, PortIdLess> PortExtCapMap;
|
||||
typedef Map<const Net*, MinMaxFloatValues, NetIdLess> NetWireCapMap;
|
||||
typedef Map<const Pin*, MinMaxFloatValues*, PinIdLess> PinWireCapMap;
|
||||
typedef Map<const Net*, NetWireCaps, NetIdLess> NetWireCapMap;
|
||||
typedef Map<const Pin*, NetWireCaps*, PinIdLess> PinWireCapMap;
|
||||
typedef Map<const Instance*, Pvt*> InstancePvtMap;
|
||||
typedef Map<const Edge*, ClockLatency*> EdgeClockLatencyMap;
|
||||
typedef Map<const Pin*, RiseFallValues*> PinMinPulseWidthMap;
|
||||
|
|
@ -595,7 +607,7 @@ public:
|
|||
bool subtract_pin_cap,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max,
|
||||
float cap);
|
||||
float wire_cap);
|
||||
bool hasNetWireCap(const Net *net) const;
|
||||
// True if driver pin net has wire capacitance.
|
||||
bool drvrPinHasWireCap(const Pin *pin,
|
||||
|
|
@ -606,7 +618,8 @@ public:
|
|||
const MinMax *min_max,
|
||||
// Return values.
|
||||
float &cap,
|
||||
bool &exists) const;
|
||||
bool &exists,
|
||||
bool &subtract_pin_cap) const;
|
||||
// Pin capacitance derated by operating conditions and instance pvt.
|
||||
float pinCapacitance(const Pin *pin,
|
||||
const RiseFall *rf,
|
||||
|
|
|
|||
|
|
@ -89,8 +89,8 @@ public:
|
|||
bool unconstrained,
|
||||
const Corner *corner,
|
||||
const MinMaxAll *min_max,
|
||||
int group_count,
|
||||
int endpoint_count,
|
||||
int group_path_count,
|
||||
int endpoint_path_count,
|
||||
bool unique_pins,
|
||||
float slack_min,
|
||||
float slack_max,
|
||||
|
|
@ -156,8 +156,8 @@ public:
|
|||
|
||||
PathGroup *pathGroup(const PathEnd *path_end) const;
|
||||
void deletePathGroups();
|
||||
void makePathGroups(int group_count,
|
||||
int endpoint_count,
|
||||
void makePathGroups(int group_path_count,
|
||||
int endpoint_path_count,
|
||||
bool unique_pins,
|
||||
float min_slack,
|
||||
float max_slack,
|
||||
|
|
@ -583,12 +583,14 @@ protected:
|
|||
// Entries in tags_ may be missing where previous filter tags were deleted.
|
||||
TagIndex tag_capacity_;
|
||||
Tag **tags_;
|
||||
Tag **tags_prev_;
|
||||
TagIndex tag_next_;
|
||||
// Holes in tags_ left by deleting filter tags.
|
||||
std::vector<TagIndex> tag_free_indices_;
|
||||
std::mutex tag_lock_;
|
||||
TagGroupSet *tag_group_set_;
|
||||
TagGroup **tag_groups_;
|
||||
TagGroup **tag_groups_prev_;
|
||||
TagGroupIndex tag_group_next_;
|
||||
// Holes in tag_groups_ left by deleting filter tag groups.
|
||||
std::vector<TagIndex> tag_group_free_indices_;
|
||||
|
|
|
|||
|
|
@ -862,11 +862,11 @@ public:
|
|||
const MinMaxAll *min_max,
|
||||
// Number of path ends to report in
|
||||
// each group.
|
||||
int group_count,
|
||||
int group_path_count,
|
||||
// Number of paths to report for
|
||||
// each endpoint.
|
||||
int endpoint_count,
|
||||
// endpoint_count paths report unique pins
|
||||
int endpoint_path_count,
|
||||
// endpoint_path_count paths report unique pins
|
||||
// without rise/fall variations.
|
||||
bool unique_pins,
|
||||
// Min/max bounds for slack of
|
||||
|
|
|
|||
|
|
@ -16,13 +16,16 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
|
||||
class Unit
|
||||
{
|
||||
public:
|
||||
Unit(const char *suffix);
|
||||
~Unit();
|
||||
Unit(float scale,
|
||||
const char *suffix,
|
||||
int digits);
|
||||
|
|
@ -34,9 +37,9 @@ public:
|
|||
float scale() const { return scale_; }
|
||||
void setScale(float scale);
|
||||
const char *scaleAbbreviation() const;
|
||||
const char *suffix() const { return suffix_; }
|
||||
const char *suffix() const { return suffix_.c_str(); }
|
||||
// scale abbreviation + suffix
|
||||
const char *scaledSuffix() const { return scaled_suffix_; }
|
||||
const char *scaledSuffix() const { return scaled_suffix_.c_str(); }
|
||||
void setSuffix(const char *suffix);
|
||||
int digits() const { return digits_; }
|
||||
void setDigits(int digits);
|
||||
|
|
@ -51,8 +54,8 @@ private:
|
|||
void setScaledSuffix();
|
||||
|
||||
float scale_; // multiplier from user units to internal units
|
||||
const char *suffix_; // print suffix
|
||||
const char *scaled_suffix_;
|
||||
string suffix_; // print suffix
|
||||
string scaled_suffix_;
|
||||
int digits_; // print digits (after decimal pt)
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2139,6 +2139,25 @@ LibertyPort::setScanSignalType(ScanSignalType type)
|
|||
scan_signal_type_ = type;
|
||||
}
|
||||
|
||||
static EnumNameMap<ScanSignalType> scan_signal_type_map =
|
||||
{{ScanSignalType::enable, "enable"},
|
||||
{ScanSignalType::enable_inverted, "enable_inverted"},
|
||||
{ScanSignalType::clock, "clock"},
|
||||
{ScanSignalType::clock_a, "clock_a"},
|
||||
{ScanSignalType::clock_b, "clock_b"},
|
||||
{ScanSignalType::input, "input"},
|
||||
{ScanSignalType::input_inverted, "input_inverted"},
|
||||
{ScanSignalType::output, "output"},
|
||||
{ScanSignalType::output_inverted, "output_inverted"},
|
||||
{ScanSignalType::none, "none"}};
|
||||
|
||||
|
||||
const char *
|
||||
scanSignalTypeName(ScanSignalType scan_type)
|
||||
{
|
||||
return scan_signal_type_map.find(scan_type);
|
||||
}
|
||||
|
||||
LibertyPort *
|
||||
LibertyPort::findLibertyMember(int index) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -339,6 +339,12 @@ set_direction(const char *dir)
|
|||
self->setDirection(PortDirection::find(dir));
|
||||
}
|
||||
|
||||
const char *
|
||||
scan_signal_type()
|
||||
{
|
||||
return scanSignalTypeName(self->scanSignalType());
|
||||
}
|
||||
|
||||
} // LibertyPort methods
|
||||
|
||||
%extend TimingArcSet {
|
||||
|
|
|
|||
|
|
@ -262,6 +262,9 @@ LibertyReader::defineVisitors()
|
|||
defineAttrVisitor("index_2", &LibertyReader::visitIndex2);
|
||||
defineAttrVisitor("index_3", &LibertyReader::visitIndex3);
|
||||
|
||||
defineGroupVisitor("technology",
|
||||
&LibertyReader::beginTechnology,
|
||||
&LibertyReader::endTechnology);
|
||||
defineGroupVisitor("rise_transition_degradation",
|
||||
&LibertyReader::beginRiseTransitionDegredation,
|
||||
&LibertyReader::endRiseFallTransitionDegredation);
|
||||
|
|
@ -372,6 +375,10 @@ LibertyReader::defineVisitors()
|
|||
&LibertyReader::visitLevelShifterDataPin);
|
||||
defineAttrVisitor("switch_pin", &LibertyReader::visitSwitchPin);
|
||||
|
||||
// Memory
|
||||
defineGroupVisitor("memory", &LibertyReader::beginMemory,
|
||||
&LibertyReader::endMemory);
|
||||
|
||||
// Register/latch
|
||||
defineGroupVisitor("ff", &LibertyReader::beginFF, &LibertyReader::endFF);
|
||||
defineGroupVisitor("ff_bank", &LibertyReader::beginFFBank,
|
||||
|
|
@ -652,6 +659,7 @@ LibertyReader::beginLibrary(LibertyGroup *group)
|
|||
library_->units()->currentUnit()->setScale(current_scale_);
|
||||
library_->units()->distanceUnit()->setScale(distance_scale_);
|
||||
|
||||
library_->setDelayModelType(DelayModelType::cmos_linear);
|
||||
scale_factors_ = new ScaleFactors("");
|
||||
library_->setScaleFactors(scale_factors_);
|
||||
}
|
||||
|
|
@ -1332,6 +1340,21 @@ LibertyReader::visitSlewDerateFromLibrary(LibertyAttr *attr)
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
LibertyReader::beginTechnology(LibertyGroup *group)
|
||||
{
|
||||
if (library_) {
|
||||
const char *tech = group->firstName();
|
||||
if (stringEq(tech, "fpga"))
|
||||
library_->setDelayModelType(DelayModelType::cmos_linear);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LibertyReader::endTechnology(LibertyGroup *)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
LibertyReader::beginTableTemplateDelay(LibertyGroup *group)
|
||||
{
|
||||
|
|
@ -3771,7 +3794,7 @@ LibertyReader::visitIsPllFeedbackPin(LibertyAttr *attr)
|
|||
void
|
||||
LibertyReader::visitSignalType(LibertyAttr *attr)
|
||||
{
|
||||
if (test_cell_ && port_) {
|
||||
if (test_cell_ && ports_) {
|
||||
const char *type = getAttrString(attr);
|
||||
if (type) {
|
||||
ScanSignalType signal_type = ScanSignalType::none;
|
||||
|
|
@ -3801,6 +3824,9 @@ LibertyReader::visitSignalType(LibertyAttr *attr)
|
|||
port_->setScanSignalType(signal_type);
|
||||
if (test_port_)
|
||||
test_port_->setScanSignalType(signal_type);
|
||||
|
||||
for (LibertyPort *port : *ports_)
|
||||
port->setScanSignalType(signal_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3845,6 +3871,21 @@ LibertyReader::visitPortBoolAttr(LibertyAttr *attr,
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
LibertyReader::beginMemory(LibertyGroup *)
|
||||
{
|
||||
if (cell_) {
|
||||
cell_->setIsMemory(true);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LibertyReader::endMemory(LibertyGroup *)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
LibertyReader::beginFF(LibertyGroup *group)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -144,6 +144,8 @@ public:
|
|||
RiseFall *rf);
|
||||
virtual void visitSlewDerateFromLibrary(LibertyAttr *attr);
|
||||
|
||||
virtual void beginTechnology(LibertyGroup *group);
|
||||
virtual void endTechnology(LibertyGroup *group);
|
||||
virtual void beginTableTemplateDelay(LibertyGroup *group);
|
||||
virtual void beginTableTemplateOutputCurrent(LibertyGroup *group);
|
||||
virtual void beginTableTemplate(LibertyGroup *group,
|
||||
|
|
@ -289,6 +291,9 @@ public:
|
|||
virtual void endWireloadSelection(LibertyGroup *group);
|
||||
virtual void visitWireloadFromArea(LibertyAttr *attr);
|
||||
|
||||
virtual void beginMemory(LibertyGroup *group);
|
||||
virtual void endMemory(LibertyGroup *group);
|
||||
|
||||
virtual void beginFF(LibertyGroup *group);
|
||||
virtual void endFF(LibertyGroup *group);
|
||||
virtual void beginFFBank(LibertyGroup *group);
|
||||
|
|
|
|||
|
|
@ -185,6 +185,7 @@ LibertyWriter::writeHeader()
|
|||
if (exists)
|
||||
fprintf(stream_, " default_fanout_load : %.2f;\n", fanout_load);
|
||||
fprintf(stream_, "\n");
|
||||
|
||||
fprintf(stream_, " nom_process : %.1f;\n",
|
||||
library_->nominalProcess());
|
||||
fprintf(stream_, " nom_temperature : %.1f;\n",
|
||||
|
|
|
|||
|
|
@ -29,8 +29,7 @@ using std::abs;
|
|||
|
||||
Unit::Unit(const char *suffix) :
|
||||
scale_(1.0),
|
||||
suffix_(stringCopy(suffix)),
|
||||
scaled_suffix_(nullptr),
|
||||
suffix_(suffix),
|
||||
digits_(3)
|
||||
{
|
||||
setScaledSuffix();
|
||||
|
|
@ -40,8 +39,7 @@ Unit::Unit(float scale,
|
|||
const char *suffix,
|
||||
int digits) :
|
||||
scale_(scale),
|
||||
suffix_(stringCopy(suffix)),
|
||||
scaled_suffix_(nullptr),
|
||||
suffix_(suffix),
|
||||
digits_(digits)
|
||||
{
|
||||
setScaledSuffix();
|
||||
|
|
@ -50,24 +48,15 @@ Unit::Unit(float scale,
|
|||
void
|
||||
Unit::setScaledSuffix()
|
||||
{
|
||||
stringDelete(scaled_suffix_);
|
||||
scaled_suffix_ = stringPrint("%s%s", scaleAbbreviation(), suffix_);
|
||||
}
|
||||
|
||||
Unit::~Unit()
|
||||
{
|
||||
stringDelete(suffix_);
|
||||
stringDelete(scaled_suffix_);
|
||||
scaled_suffix_ = scaleAbbreviation() + suffix_;
|
||||
}
|
||||
|
||||
void
|
||||
Unit::operator=(const Unit &unit)
|
||||
{
|
||||
scale_ = unit.scale_;
|
||||
stringDelete(suffix_);
|
||||
suffix_ = stringCopy(unit.suffix_);
|
||||
stringDelete(scaled_suffix_);
|
||||
scaled_suffix_ = stringCopy(unit.scaled_suffix_);
|
||||
suffix_ = unit.suffix_;
|
||||
scaled_suffix_ = unit.scaled_suffix_;
|
||||
digits_ = unit.digits_;
|
||||
}
|
||||
|
||||
|
|
@ -116,8 +105,7 @@ Unit::scaleAbbreviation() const
|
|||
void
|
||||
Unit::setSuffix(const char *suffix)
|
||||
{
|
||||
stringDelete(suffix_);
|
||||
suffix_ = stringCopy(suffix);
|
||||
suffix_ = suffix;
|
||||
setScaledSuffix();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -272,15 +272,15 @@ void
|
|||
ConcreteCell::setAttribute(const string &key,
|
||||
const string &value)
|
||||
{
|
||||
attribute_map_.insert(key, value);
|
||||
attribute_map_[key] = value;
|
||||
}
|
||||
|
||||
string
|
||||
ConcreteCell::getAttribute(const string &key) const
|
||||
{
|
||||
if (attribute_map_.hasKey(key)) {
|
||||
return attribute_map_.findKey(key);
|
||||
}
|
||||
const auto &itr = attribute_map_.find(key);
|
||||
if (itr != attribute_map_.end())
|
||||
return itr->second;
|
||||
return "";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1686,15 +1686,15 @@ void
|
|||
ConcreteInstance::setAttribute(const string &key,
|
||||
const string &value)
|
||||
{
|
||||
attribute_map_.insert(key, value);
|
||||
attribute_map_[key] = value;
|
||||
}
|
||||
|
||||
string
|
||||
ConcreteInstance::getAttribute(const string &key) const
|
||||
{
|
||||
if (attribute_map_.hasKey(key)) {
|
||||
return attribute_map_.findKey(key);
|
||||
}
|
||||
const auto &itr = attribute_map_.find(key);
|
||||
if (itr != attribute_map_.end())
|
||||
return itr->second;
|
||||
return "";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -946,9 +946,9 @@ ConcreteParasitics::findPiElmore(const Pin *drvr_pin,
|
|||
const RiseFall *rf,
|
||||
const ParasiticAnalysisPt *ap) const
|
||||
{
|
||||
LockGuard lock(lock_);
|
||||
if (!drvr_parasitic_map_.empty()) {
|
||||
int ap_rf_index = parasiticAnalysisPtIndex(ap, rf);
|
||||
LockGuard lock(lock_);
|
||||
ConcreteParasitic **parasitics = drvr_parasitic_map_.findKey(drvr_pin);
|
||||
if (parasitics) {
|
||||
ConcreteParasitic *parasitic = parasitics[ap_rf_index];
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include "SpefReader.hh"
|
||||
|
||||
#include "Zlib.hh"
|
||||
#include "Stats.hh"
|
||||
#include "Report.hh"
|
||||
#include "Debug.hh"
|
||||
#include "StringUtil.hh"
|
||||
|
|
@ -64,6 +65,7 @@ readSpefFile(const char *filename,
|
|||
// Use zlib to uncompress gzip'd files automagically.
|
||||
gzFile stream = gzopen(filename, "rb");
|
||||
if (stream) {
|
||||
Stats stats(sta->debug(), sta->report());
|
||||
SpefReader reader(filename, stream, instance, ap,
|
||||
pin_cap_included, keep_coupling_caps, coupling_cap_factor,
|
||||
reduce, corner, min_max, sta);
|
||||
|
|
@ -73,6 +75,7 @@ readSpefFile(const char *filename,
|
|||
success = (::SpefParse_parse() == 0);
|
||||
gzclose(stream);
|
||||
spef_reader = nullptr;
|
||||
stats.report("Read spef");
|
||||
}
|
||||
else
|
||||
throw FileNotReadable(filename);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include <cmath> // abs
|
||||
|
||||
#include "cudd.h"
|
||||
#include "Stats.hh"
|
||||
#include "Debug.hh"
|
||||
#include "EnumNameMap.hh"
|
||||
#include "Hash.hh"
|
||||
|
|
@ -233,6 +234,7 @@ Power::power(const Corner *corner,
|
|||
pad.clear();
|
||||
|
||||
ensureActivities();
|
||||
Stats stats(debug_, report_);
|
||||
LeafInstanceIterator *inst_iter = network_->leafInstanceIterator();
|
||||
while (inst_iter->hasNext()) {
|
||||
Instance *inst = inst_iter->next();
|
||||
|
|
@ -255,6 +257,7 @@ Power::power(const Corner *corner,
|
|||
}
|
||||
}
|
||||
delete inst_iter;
|
||||
stats.report("Find power");
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -617,6 +620,7 @@ Power::ensureActivities()
|
|||
// No need to propagate activites if global activity is set.
|
||||
if (!global_activity_.isSet()) {
|
||||
if (!activities_valid_) {
|
||||
Stats stats(debug_, report_);
|
||||
// Clear existing activities.
|
||||
activity_map_.clear();
|
||||
seq_activity_map_.clear();
|
||||
|
|
@ -646,6 +650,7 @@ Power::ensureActivities()
|
|||
pass, visitor.maxChange());
|
||||
pass++;
|
||||
}
|
||||
stats.report("Find power activities");
|
||||
activities_valid_ = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include "VcdReader.hh"
|
||||
|
||||
#include "Zlib.hh"
|
||||
#include "Stats.hh"
|
||||
#include "Report.hh"
|
||||
#include "Error.hh"
|
||||
#include "StringUtil.hh"
|
||||
|
|
@ -79,6 +80,7 @@ VcdReader::read(const char *filename)
|
|||
vcd_ = &vcd;
|
||||
stream_ = gzopen(filename, "r");
|
||||
if (stream_) {
|
||||
Stats stats(debug_, report_);
|
||||
filename_ = filename;
|
||||
file_line_ = 1;
|
||||
stmt_line_ = 1;
|
||||
|
|
@ -113,6 +115,7 @@ VcdReader::read(const char *filename)
|
|||
token = getToken();
|
||||
}
|
||||
gzclose(stream_);
|
||||
stats.report("Read VCD");
|
||||
}
|
||||
else
|
||||
throw FileNotReadable(filename);
|
||||
|
|
|
|||
61
sdc/Sdc.cc
61
sdc/Sdc.cc
|
|
@ -3057,14 +3057,18 @@ Sdc::drvrPinWireCap(const Pin *pin,
|
|||
const MinMax *min_max,
|
||||
// Return values.
|
||||
float &cap,
|
||||
bool &exists) const
|
||||
bool &exists,
|
||||
bool &subtract_pin_cap) const
|
||||
{
|
||||
MinMaxFloatValues *values = drvr_pin_wire_cap_maps_[corner->index()].findKey(pin);
|
||||
if (values)
|
||||
values->value(min_max, cap, exists);
|
||||
NetWireCaps *net_caps = drvr_pin_wire_cap_maps_[corner->index()].findKey(pin);
|
||||
if (net_caps) {
|
||||
net_caps->value(min_max, cap, exists);
|
||||
subtract_pin_cap = net_caps->subtractPinCap(min_max);
|
||||
}
|
||||
else {
|
||||
cap = 0.0;
|
||||
exists = false;
|
||||
subtract_pin_cap = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3073,27 +3077,15 @@ Sdc::setNetWireCap(const Net *net,
|
|||
bool subtract_pin_cap,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max,
|
||||
float cap)
|
||||
float wire_cap)
|
||||
{
|
||||
float wire_cap = cap;
|
||||
if (subtract_pin_cap) {
|
||||
NetConnectedPinIterator *pin_iter = network_->connectedPinIterator(net);
|
||||
if (pin_iter->hasNext()) {
|
||||
const Pin *pin = pin_iter->next();
|
||||
float pin_cap_rise = connectedPinCap(pin, RiseFall::rise(), corner, min_max);
|
||||
float pin_cap_fall = connectedPinCap(pin, RiseFall::fall(), corner, min_max);
|
||||
float pin_cap = (pin_cap_rise + pin_cap_fall) / 2.0F;
|
||||
wire_cap -= pin_cap;
|
||||
if ((wire_cap + pin_cap) < 0.0)
|
||||
wire_cap = -pin_cap;
|
||||
delete pin_iter;
|
||||
}
|
||||
}
|
||||
MinMaxFloatValues &values = net_wire_cap_maps_[corner->index()][net];
|
||||
values.setValue(min_max, wire_cap);
|
||||
NetWireCaps &net_caps = net_wire_cap_maps_[corner->index()][net];
|
||||
net_caps.setValue(min_max, wire_cap);
|
||||
net_caps.setSubtractPinCap(subtract_pin_cap, min_max);
|
||||
|
||||
|
||||
for (const Pin *pin : *network_->drivers(net))
|
||||
drvr_pin_wire_cap_maps_[corner->index()][pin] = &values;
|
||||
drvr_pin_wire_cap_maps_[corner->index()][pin] = &net_caps;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -3121,7 +3113,10 @@ Sdc::connectedCap(const Pin *pin,
|
|||
{
|
||||
netCaps(pin, rf, corner, min_max, pin_cap, wire_cap, fanout, has_net_load);
|
||||
float net_wire_cap;
|
||||
drvrPinWireCap(pin, corner, min_max, net_wire_cap, has_net_load);
|
||||
bool subtract_pin_cap;
|
||||
drvrPinWireCap(pin, corner, min_max, net_wire_cap, has_net_load, subtract_pin_cap);
|
||||
if (subtract_pin_cap)
|
||||
pin_cap = 0.0;
|
||||
if (has_net_load)
|
||||
wire_cap += net_wire_cap;
|
||||
}
|
||||
|
|
@ -5800,4 +5795,24 @@ findLeafDriverPins(const Pin *pin,
|
|||
leaf_pins->insert(pin);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
NetWireCaps::NetWireCaps() :
|
||||
subtract_pin_cap_{false, false}
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
NetWireCaps::subtractPinCap(const MinMax *min_max)
|
||||
{
|
||||
return subtract_pin_cap_[min_max->index()];
|
||||
}
|
||||
|
||||
void
|
||||
NetWireCaps::setSubtractPinCap(bool subtrace_pin_cap,
|
||||
const MinMax *min_max)
|
||||
{
|
||||
subtract_pin_cap_[min_max->index()] = subtrace_pin_cap;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
16
sdc/Sdc.tcl
16
sdc/Sdc.tcl
|
|
@ -643,14 +643,16 @@ 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]\
|
||||
[-of_objects objects] [patterns]}
|
||||
|
||||
define_cmd_alias "get_lib_pin" "get_lib_pins"
|
||||
|
||||
# "get_lib_ports" in sta terminology.
|
||||
proc get_lib_pins { args } {
|
||||
global hierarchy_separator
|
||||
parse_key_args "get_lib_pins" args keys {-hsc -filter} flags {-regexp -nocase -quiet}
|
||||
parse_key_args "get_lib_pins" args keys {-hsc -of_objects -filter} \
|
||||
flags {-regexp -nocase -quiet}
|
||||
check_argc_eq0or1 "get_lib_pins" $args
|
||||
check_nocase_flag flags
|
||||
|
||||
|
|
@ -672,6 +674,15 @@ proc get_lib_pins { args } {
|
|||
set port_regexp1 [port_regexp_hsc $divider]
|
||||
set port_regexp2 [cell_regexp_hsc $divider]
|
||||
set ports {}
|
||||
if [info exists keys(-of_objects)] {
|
||||
if { $args != {} } {
|
||||
sta_warn 335 "positional arguments not supported with -of_objects."
|
||||
}
|
||||
set libcells [get_libcells_error "objects" $keys(-of_objects)]
|
||||
foreach libcell $libcells {
|
||||
lappend ports {*}[$libcell find_liberty_ports_matching * 0 1]
|
||||
}
|
||||
} else {
|
||||
foreach pattern $patterns {
|
||||
if { [is_object $pattern] } {
|
||||
if { [object_type $pattern] != "LibertyPort" } {
|
||||
|
|
@ -718,6 +729,7 @@ proc get_lib_pins { args } {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if [info exists keys(-filter)] {
|
||||
set ports [filter_objs $keys(-filter) $ports filter_lib_pins "liberty port"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -190,6 +190,7 @@ BfsIterator::visitParallel(Level to_level,
|
|||
else {
|
||||
size_t from = 0;
|
||||
size_t chunk_size = vertex_count / thread_count;
|
||||
BfsIndex bfs_index = bfs_index_;
|
||||
for (size_t k = 0; k < thread_count; k++) {
|
||||
// Last thread gets the left overs.
|
||||
size_t to = (k == thread_count - 1) ? vertex_count : from + chunk_size;
|
||||
|
|
@ -197,7 +198,7 @@ BfsIterator::visitParallel(Level to_level,
|
|||
for (size_t i = from; i < to; i++) {
|
||||
Vertex *vertex = level_vertices[i];
|
||||
if (vertex) {
|
||||
vertex->setBfsInQueue(bfs_index_, false);
|
||||
vertex->setBfsInQueue(bfs_index, false);
|
||||
visitors[k]->visit(vertex);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,36 +87,36 @@ CheckSlewLimits::CheckSlewLimits(const StaState *sta) :
|
|||
{
|
||||
}
|
||||
|
||||
void
|
||||
CheckSlewLimits::checkSlewLimits(const Pin *pin,
|
||||
bool violators,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max,
|
||||
PinSeq &slew_pins,
|
||||
float &min_slack)
|
||||
{
|
||||
const Corner *corner1;
|
||||
const RiseFall *rf;
|
||||
Slew slew;
|
||||
float limit, slack;
|
||||
checkSlew(pin, corner, min_max, true, corner1, rf, slew, limit, slack);
|
||||
if (!fuzzyInf(slack)) {
|
||||
if (violators) {
|
||||
if (slack < 0.0)
|
||||
slew_pins.push_back(pin);
|
||||
}
|
||||
else {
|
||||
if (slew_pins.empty()
|
||||
|| slack < min_slack) {
|
||||
slew_pins.push_back(pin);
|
||||
min_slack = slack;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CheckSlewLimits::checkSlew(const Pin *pin,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max,
|
||||
bool check_clks,
|
||||
// Return values.
|
||||
const Corner *&corner1,
|
||||
const RiseFall *&rf,
|
||||
Slew &slew,
|
||||
float &limit,
|
||||
float &slack) const
|
||||
{
|
||||
corner1 = nullptr;
|
||||
rf = nullptr;
|
||||
slew = 0.0;
|
||||
limit = 0.0;
|
||||
slack = MinMax::min()->initValue();
|
||||
if (corner)
|
||||
checkSlews1(pin, corner, min_max, check_clks,
|
||||
corner1, rf, slew, limit, slack);
|
||||
else {
|
||||
for (auto corner : *sta_->corners()) {
|
||||
checkSlews1(pin, corner, min_max, check_clks,
|
||||
corner1, rf, slew, limit, slack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CheckSlewLimits::checkSlews1(const Pin *pin,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max,
|
||||
bool check_clks,
|
||||
|
|
@ -127,18 +127,25 @@ CheckSlewLimits::checkSlews1(const Pin *pin,
|
|||
float &limit1,
|
||||
float &slack1) const
|
||||
{
|
||||
corner1 = nullptr;
|
||||
rf1 = nullptr;
|
||||
slew1 = 0.0;
|
||||
limit1 = 0.0;
|
||||
slack1 = MinMax::min()->initValue();
|
||||
|
||||
Vertex *vertex, *bidirect_drvr_vertex;
|
||||
sta_->graph()->pinVertices(pin, vertex, bidirect_drvr_vertex);
|
||||
if (vertex)
|
||||
checkSlews1(vertex, corner, min_max, check_clks,
|
||||
checkSlew1(pin, vertex, corner, min_max, check_clks,
|
||||
corner1, rf1, slew1, limit1, slack1);
|
||||
if (bidirect_drvr_vertex)
|
||||
checkSlews1(bidirect_drvr_vertex, corner, min_max, check_clks,
|
||||
checkSlew1(pin, bidirect_drvr_vertex, corner, min_max, check_clks,
|
||||
corner1, rf1, slew1, limit1, slack1);
|
||||
}
|
||||
|
||||
void
|
||||
CheckSlewLimits::checkSlews1(Vertex *vertex,
|
||||
CheckSlewLimits::checkSlew1(const Pin *pin,
|
||||
const Vertex *vertex,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max,
|
||||
bool check_clks,
|
||||
|
|
@ -149,31 +156,87 @@ CheckSlewLimits::checkSlews1(Vertex *vertex,
|
|||
float &limit1,
|
||||
float &slack1) const
|
||||
{
|
||||
const Pin *pin = vertex->pin();
|
||||
if (!vertex->isDisabledConstraint()
|
||||
&& !vertex->isConstant()
|
||||
&& !sta_->clkNetwork()->isIdealClock(pin)) {
|
||||
for (auto rf : RiseFall::range()) {
|
||||
ClockSet clks;
|
||||
if (check_clks)
|
||||
clks = clockDomains(vertex);
|
||||
if (corner)
|
||||
checkSlew2(pin, vertex, corner, min_max, clks,
|
||||
corner1, rf1, slew1, limit1, slack1);
|
||||
else {
|
||||
for (auto corner : *sta_->corners()) {
|
||||
checkSlew2(pin, vertex, corner, min_max, clks,
|
||||
corner1, rf1, slew1, limit1, slack1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CheckSlewLimits::checkSlew2(const Pin *pin,
|
||||
const Vertex *vertex,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max,
|
||||
const ClockSet &clks,
|
||||
// Return values.
|
||||
const Corner *&corner1,
|
||||
const RiseFall *&rf1,
|
||||
Slew &slew1,
|
||||
float &limit1,
|
||||
float &slack1) const
|
||||
{
|
||||
for (const RiseFall *rf : RiseFall::range()) {
|
||||
float limit;
|
||||
bool exists;
|
||||
findLimit(pin, vertex, corner, rf, min_max, check_clks,
|
||||
findLimit(pin, corner, rf, min_max, clks,
|
||||
limit, exists);
|
||||
if (exists) {
|
||||
checkSlew(vertex, corner, rf, min_max, limit,
|
||||
checkSlew3(vertex, corner, rf, min_max, limit,
|
||||
corner1, rf1, slew1, slack1, limit1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CheckSlewLimits::checkSlew3(const Vertex *vertex,
|
||||
const Corner *corner,
|
||||
const RiseFall *rf,
|
||||
const MinMax *min_max,
|
||||
float limit,
|
||||
// Return values.
|
||||
const Corner *&corner1,
|
||||
const RiseFall *&rf1,
|
||||
Slew &slew1,
|
||||
float &slack1,
|
||||
float &limit1) const
|
||||
{
|
||||
const DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(min_max);
|
||||
Slew slew = sta_->graph()->slew(vertex, rf, dcalc_ap->index());
|
||||
float slew2 = delayAsFloat(slew);
|
||||
float slack = (min_max == MinMax::max())
|
||||
? limit - slew2 : slew2 - limit;
|
||||
if (corner1 == nullptr
|
||||
|| (slack < slack1
|
||||
// Break ties for the sake of regression stability.
|
||||
|| (fuzzyEqual(slack, slack1)
|
||||
&& rf->index() < rf1->index()))) {
|
||||
corner1 = corner;
|
||||
rf1 = rf;
|
||||
slew1 = slew;
|
||||
slack1 = slack;
|
||||
limit1 = limit;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the tightest limit.
|
||||
void
|
||||
CheckSlewLimits::findLimit(const Pin *pin,
|
||||
const Vertex *vertex,
|
||||
const Corner *corner,
|
||||
const RiseFall *rf,
|
||||
const MinMax *min_max,
|
||||
bool check_clks,
|
||||
const ClockSet &clks,
|
||||
// Return values.
|
||||
float &limit,
|
||||
bool &exists) const
|
||||
|
|
@ -186,14 +249,10 @@ CheckSlewLimits::findLimit(const Pin *pin,
|
|||
|
||||
float limit1;
|
||||
bool exists1;
|
||||
if (check_clks) {
|
||||
if (!clks.empty()) {
|
||||
// Look for clock slew limits.
|
||||
bool is_clk = sta_->clkNetwork()->isIdealClock(pin);
|
||||
ClockSet clks;
|
||||
clockDomains(vertex, clks);
|
||||
ClockSet::Iterator clk_iter(clks);
|
||||
while (clk_iter.hasNext()) {
|
||||
Clock *clk = clk_iter.next();
|
||||
for (Clock *clk : clks) {
|
||||
PathClkOrData clk_data = is_clk ? PathClkOrData::clk : PathClkOrData::data;
|
||||
sdc->slewLimit(clk, rf, clk_data, min_max,
|
||||
limit1, exists1);
|
||||
|
|
@ -284,11 +343,10 @@ CheckSlewLimits::findLimit(const LibertyPort *port,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
CheckSlewLimits::clockDomains(const Vertex *vertex,
|
||||
// Return value.
|
||||
ClockSet &clks) const
|
||||
ClockSet
|
||||
CheckSlewLimits::clockDomains(const Vertex *vertex) const
|
||||
{
|
||||
ClockSet clks;
|
||||
VertexPathIterator path_iter(const_cast<Vertex*>(vertex), sta_);
|
||||
while (path_iter.hasNext()) {
|
||||
Path *path = path_iter.next();
|
||||
|
|
@ -296,37 +354,7 @@ CheckSlewLimits::clockDomains(const Vertex *vertex,
|
|||
if (clk)
|
||||
clks.insert(const_cast<Clock*>(clk));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CheckSlewLimits::checkSlew(Vertex *vertex,
|
||||
const Corner *corner,
|
||||
const RiseFall *rf,
|
||||
const MinMax *min_max,
|
||||
float limit,
|
||||
// Return values.
|
||||
const Corner *&corner1,
|
||||
const RiseFall *&rf1,
|
||||
Slew &slew1,
|
||||
float &slack1,
|
||||
float &limit1) const
|
||||
{
|
||||
const DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(min_max);
|
||||
Slew slew = sta_->graph()->slew(vertex, rf, dcalc_ap->index());
|
||||
float slew2 = delayAsFloat(slew);
|
||||
float slack = (min_max == MinMax::max())
|
||||
? limit - slew2 : slew2 - limit;
|
||||
if (corner1 == nullptr
|
||||
|| (slack < slack1
|
||||
// Break ties for the sake of regression stability.
|
||||
|| (fuzzyEqual(slack, slack1)
|
||||
&& rf->index() < rf1->index()))) {
|
||||
corner1 = corner;
|
||||
rf1 = rf;
|
||||
slew1 = slew;
|
||||
slack1 = slack;
|
||||
limit1 = limit;
|
||||
}
|
||||
return clks;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
@ -383,32 +411,4 @@ CheckSlewLimits::checkSlewLimits(const Instance *inst,
|
|||
delete pin_iter;
|
||||
}
|
||||
|
||||
void
|
||||
CheckSlewLimits::checkSlewLimits(const Pin *pin,
|
||||
bool violators,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max,
|
||||
PinSeq &slew_pins,
|
||||
float &min_slack)
|
||||
{
|
||||
const Corner *corner1;
|
||||
const RiseFall *rf;
|
||||
Slew slew;
|
||||
float limit, slack;
|
||||
checkSlew(pin, corner, min_max, true, corner1, rf, slew, limit, slack);
|
||||
if (!fuzzyInf(slack)) {
|
||||
if (violators) {
|
||||
if (slack < 0.0)
|
||||
slew_pins.push_back(pin);
|
||||
}
|
||||
else {
|
||||
if (slew_pins.empty()
|
||||
|| slack < min_slack) {
|
||||
slew_pins.push_back(pin);
|
||||
min_slack = slack;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -33,6 +33,13 @@ class CheckSlewLimits
|
|||
{
|
||||
public:
|
||||
CheckSlewLimits(const StaState *sta);
|
||||
// Return pins with the min/max slew limit slack.
|
||||
// net=null check all nets
|
||||
// corner=nullptr checks all corners.
|
||||
PinSeq checkSlewLimits(const Net *net,
|
||||
bool violators,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max);
|
||||
// corner=nullptr checks all corners.
|
||||
void checkSlew(const Pin *pin,
|
||||
const Corner *corner,
|
||||
|
|
@ -45,13 +52,6 @@ public:
|
|||
Slew &slew,
|
||||
float &limit,
|
||||
float &slack) const;
|
||||
// Return pins with the min/max slew limit slack.
|
||||
// net=null check all nets
|
||||
// corner=nullptr checks all corners.
|
||||
PinSeq checkSlewLimits(const Net *net,
|
||||
bool violators,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max);
|
||||
void findLimit(const LibertyPort *port,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max,
|
||||
|
|
@ -60,7 +60,8 @@ public:
|
|||
bool &exists) const;
|
||||
|
||||
protected:
|
||||
void checkSlews1(const Pin *pin,
|
||||
void checkSlew1(const Pin *pin,
|
||||
const Vertex *vertex,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max,
|
||||
bool check_clks,
|
||||
|
|
@ -70,17 +71,18 @@ protected:
|
|||
Slew &slew1,
|
||||
float &limit1,
|
||||
float &slack1) const;
|
||||
void checkSlews1(Vertex *vertex,
|
||||
void checkSlew2(const Pin *pin,
|
||||
const Vertex *vertex,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max,
|
||||
bool check_clks,
|
||||
const ClockSet &clks,
|
||||
// Return values.
|
||||
const Corner *&corner1,
|
||||
const RiseFall *&rf1,
|
||||
Slew &slew1,
|
||||
float &limit1,
|
||||
float &slack1) const;
|
||||
void checkSlew(Vertex *vertex,
|
||||
void checkSlew3(const Vertex *vertex,
|
||||
const Corner *corner1,
|
||||
const RiseFall *rf1,
|
||||
const MinMax *min_max,
|
||||
|
|
@ -92,11 +94,10 @@ protected:
|
|||
float &slack,
|
||||
float &limit) const;
|
||||
void findLimit(const Pin *pin,
|
||||
const Vertex *vertex,
|
||||
const Corner *corner,
|
||||
const RiseFall *rf,
|
||||
const MinMax *min_max,
|
||||
bool check_clks,
|
||||
const ClockSet &clks,
|
||||
// Return values.
|
||||
float &limit,
|
||||
bool &limit_exists) const;
|
||||
|
|
@ -112,9 +113,7 @@ protected:
|
|||
const MinMax *min_max,
|
||||
PinSeq &slew_pins,
|
||||
float &min_slack);
|
||||
void clockDomains(const Vertex *vertex,
|
||||
// Return value.
|
||||
ClockSet &clks) const;
|
||||
ClockSet clockDomains(const Vertex *vertex) const;
|
||||
|
||||
const StaState *sta_;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ MakeTimingModel::makeTimingModel()
|
|||
|
||||
findTimingFromInputs();
|
||||
findClkedOutputPaths();
|
||||
findClkInsertionDelays();
|
||||
findClkTreeDelays();
|
||||
|
||||
cell_->finish(false, report_, debug_);
|
||||
restoreSdc();
|
||||
|
|
@ -525,7 +525,7 @@ MakeTimingModel::findClkedOutputPaths()
|
|||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
MakeTimingModel::findClkInsertionDelays()
|
||||
MakeTimingModel::findClkTreeDelays()
|
||||
{
|
||||
Instance *top_inst = network_->topInstance();
|
||||
Cell *top_cell = network_->cell(top_inst);
|
||||
|
|
@ -539,8 +539,7 @@ MakeTimingModel::findClkInsertionDelays()
|
|||
if (pin && sdc_->isClock(pin)) {
|
||||
lib_port->setIsClock(true);
|
||||
ClockSet *clks = sdc_->findClocks(pin);
|
||||
size_t clk_count = clks->size();
|
||||
if (clk_count == 1) {
|
||||
if (clks->size() == 1) {
|
||||
for (const Clock *clk : *clks) {
|
||||
ClkDelays delays = sta_->findClkDelays(clk, true);
|
||||
for (const MinMax *min_max : MinMax::range()) {
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ private:
|
|||
void findTimingFromInputs();
|
||||
void findTimingFromInput(Port *input_port);
|
||||
void findClkedOutputPaths();
|
||||
void findClkInsertionDelays();
|
||||
void findClkTreeDelays();
|
||||
void makeClkTreePaths(LibertyPort *lib_port,
|
||||
const MinMax *min_max,
|
||||
TimingSense sense,
|
||||
|
|
|
|||
|
|
@ -1048,6 +1048,40 @@ PathEndCheck::sourceClkDelay(const StaState *sta) const
|
|||
return 0.0;
|
||||
}
|
||||
|
||||
Required
|
||||
PathEndCheck::requiredTimeNoCrpr(const StaState *sta) const
|
||||
{
|
||||
Arrival tgt_clk_arrival = targetClkArrivalNoCrpr(sta);
|
||||
ArcDelay check_margin = margin(sta);
|
||||
float macro_clk_tree_delay = macroClkTreeDelay(sta);
|
||||
if (checkGenericRole(sta) == TimingRole::setup())
|
||||
return tgt_clk_arrival - (check_margin + macro_clk_tree_delay);
|
||||
else
|
||||
return tgt_clk_arrival + (check_margin - macro_clk_tree_delay);
|
||||
}
|
||||
|
||||
float
|
||||
PathEndCheck::macroClkTreeDelay(const StaState *sta) const
|
||||
{
|
||||
const ClockEdge *tgt_clk_edge = targetClkEdge(sta);
|
||||
const Clock *tgt_clk = tgt_clk_edge->clock();
|
||||
const Network *network = sta->network();
|
||||
const Pin *clk_pin = clk_path_.pin(sta);
|
||||
const Instance *inst = network->instance(clk_pin);
|
||||
const LibertyCell *inst_cell = network->libertyCell(inst);
|
||||
if (tgt_clk->isIdeal()
|
||||
&& inst_cell && inst_cell->isMacro()) {
|
||||
LibertyPort *clk_port = network->libertyPort(clk_pin);
|
||||
if (clk_port) {
|
||||
const MinMax *min_max = clk_path_.minMax(sta);
|
||||
const RiseFall *rf = clk_path_.transition(sta);
|
||||
float slew = delayAsFloat(clk_path_.slew(sta));
|
||||
return clk_port->clkTreeDelay(slew, rf, min_max);
|
||||
}
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
PathEndLatchCheck::PathEndLatchCheck(Path *path,
|
||||
|
|
@ -1945,7 +1979,9 @@ PathEndPathDelay::requiredTime(const StaState *sta) const
|
|||
{
|
||||
float delay = path_delay_->delay();
|
||||
if (path_delay_->ignoreClkLatency()) {
|
||||
float src_offset = path_.isClock(sta) ? path_.clkEdge(sta)->time() : src_clk_arrival_;
|
||||
Required src_offset = path_.isClock(sta)
|
||||
? path_.clkEdge(sta)->time()
|
||||
: src_clk_arrival_;
|
||||
return src_offset + delay
|
||||
+ ((minMax(sta) == MinMax::max()) ? -margin(sta) : margin(sta));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,15 +96,15 @@ deleteDiversionPathEnd(Diversion *div)
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
PathEnum::PathEnum(int group_count,
|
||||
int endpoint_count,
|
||||
PathEnum::PathEnum(int group_path_count,
|
||||
int endpoint_path_count,
|
||||
bool unique_pins,
|
||||
bool cmp_slack,
|
||||
const StaState *sta) :
|
||||
StaState(sta),
|
||||
cmp_slack_(cmp_slack),
|
||||
group_count_(group_count),
|
||||
endpoint_count_(endpoint_count),
|
||||
group_path_count_(group_path_count),
|
||||
endpoint_path_count_(endpoint_path_count),
|
||||
unique_pins_(unique_pins),
|
||||
div_queue_(DiversionGreater(sta)),
|
||||
div_count_(0),
|
||||
|
|
@ -181,7 +181,7 @@ PathEnum::findNext()
|
|||
}
|
||||
|
||||
path_counts_[vertex]++;
|
||||
if (path_counts_[vertex] <= endpoint_count_) {
|
||||
if (path_counts_[vertex] <= endpoint_path_count_) {
|
||||
// Add diversions for all arcs converging on the path up to the
|
||||
// diversion.
|
||||
makeDiversions(path_end, div->divPath());
|
||||
|
|
@ -191,8 +191,10 @@ PathEnum::findNext()
|
|||
break;
|
||||
}
|
||||
else {
|
||||
// We have endpoint_count paths for this endpoint, so we are done with it.
|
||||
debugPrint(debug_, "path_enum", 1, "endpoint_count reached for %s",
|
||||
// We have endpoint_path_count paths for this endpoint,
|
||||
// so we are done with it.
|
||||
debugPrint(debug_, "path_enum", 1,
|
||||
"endpoint_path_count reached for %s",
|
||||
vertex->name(sdc_network_));
|
||||
deleteDiversionPathEnd(div);
|
||||
}
|
||||
|
|
@ -421,7 +423,7 @@ PathEnum::makeDiversion(PathEnd *div_end,
|
|||
div_queue_.push(div);
|
||||
div_count_++;
|
||||
|
||||
if (static_cast<int>(div_queue_.size()) > group_count_ * 2)
|
||||
if (static_cast<int>(div_queue_.size()) > group_path_count_ * 2)
|
||||
// We have more potenial paths than we will need.
|
||||
pruneDiversionQueue();
|
||||
}
|
||||
|
|
@ -432,14 +434,14 @@ PathEnum::pruneDiversionQueue()
|
|||
debugPrint(debug_, "path_enum", 2, "prune queue");
|
||||
VertexPathCountMap path_counts;
|
||||
int end_count = 0;
|
||||
// Collect endpoint_count diversions per vertex.
|
||||
// Collect endpoint_path_count diversions per vertex.
|
||||
DiversionSeq divs;
|
||||
while (!div_queue_.empty()) {
|
||||
Diversion *div = div_queue_.top();
|
||||
Vertex *vertex = div->pathEnd()->vertex(this);
|
||||
if (end_count < group_count_
|
||||
if (end_count < group_path_count_
|
||||
&& ((unique_pins_ && path_counts[vertex] == 0)
|
||||
|| (!unique_pins_ && path_counts[vertex] < endpoint_count_))) {
|
||||
|| (!unique_pins_ && path_counts[vertex] < endpoint_path_count_))) {
|
||||
divs.push_back(div);
|
||||
path_counts[vertex]++;
|
||||
end_count++;
|
||||
|
|
|
|||
|
|
@ -52,8 +52,8 @@ private:
|
|||
class PathEnum : public Iterator<PathEnd*>, StaState
|
||||
{
|
||||
public:
|
||||
PathEnum(int group_count,
|
||||
int endpoint_count,
|
||||
PathEnum(int group_path_count,
|
||||
int endpoint_path_count,
|
||||
bool unique_pins,
|
||||
bool cmp_slack,
|
||||
const StaState *sta);
|
||||
|
|
@ -88,12 +88,12 @@ private:
|
|||
void findNext();
|
||||
|
||||
bool cmp_slack_;
|
||||
int group_count_;
|
||||
int endpoint_count_;
|
||||
int group_path_count_;
|
||||
int endpoint_path_count_;
|
||||
bool unique_pins_;
|
||||
DiversionQueue div_queue_;
|
||||
int div_count_;
|
||||
// Number of paths returned for each endpoint (limited to endpoint_count).
|
||||
// Number of paths returned for each endpoint (limit to endpoint_path_count).
|
||||
VertexPathCountMap path_counts_;
|
||||
bool inserts_pruned_;
|
||||
PathEnd *next_;
|
||||
|
|
|
|||
|
|
@ -38,36 +38,36 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
int PathGroup::group_count_max = std::numeric_limits<int>::max();
|
||||
int PathGroup::group_path_count_max = std::numeric_limits<int>::max();
|
||||
|
||||
PathGroup *
|
||||
PathGroup::makePathGroupSlack(const char *name,
|
||||
int group_count,
|
||||
int endpoint_count,
|
||||
int group_path_count,
|
||||
int endpoint_path_count,
|
||||
bool unique_pins,
|
||||
float slack_min,
|
||||
float slack_max,
|
||||
const StaState *sta)
|
||||
{
|
||||
return new PathGroup(name, group_count, endpoint_count, unique_pins,
|
||||
return new PathGroup(name, group_path_count, endpoint_path_count, unique_pins,
|
||||
slack_min, slack_max, true, MinMax::min(), sta);
|
||||
}
|
||||
|
||||
PathGroup *
|
||||
PathGroup::makePathGroupArrival(const char *name,
|
||||
int group_count,
|
||||
int endpoint_count,
|
||||
int group_path_count,
|
||||
int endpoint_path_count,
|
||||
bool unique_pins,
|
||||
const MinMax *min_max,
|
||||
const StaState *sta)
|
||||
{
|
||||
return new PathGroup(name, group_count, endpoint_count, unique_pins,
|
||||
return new PathGroup(name, group_path_count, endpoint_path_count, unique_pins,
|
||||
0.0, 0.0, false, min_max, sta);
|
||||
}
|
||||
|
||||
PathGroup::PathGroup(const char *name,
|
||||
int group_count,
|
||||
int endpoint_count,
|
||||
int group_path_count,
|
||||
int endpoint_path_count,
|
||||
bool unique_pins,
|
||||
float slack_min,
|
||||
float slack_max,
|
||||
|
|
@ -75,8 +75,8 @@ PathGroup::PathGroup(const char *name,
|
|||
const MinMax *min_max,
|
||||
const StaState *sta) :
|
||||
name_(name),
|
||||
group_count_(group_count),
|
||||
endpoint_count_(endpoint_count),
|
||||
group_path_count_(group_path_count),
|
||||
endpoint_path_count_(endpoint_path_count),
|
||||
unique_pins_(unique_pins),
|
||||
slack_min_(slack_min),
|
||||
slack_max_(slack_max),
|
||||
|
|
@ -95,17 +95,22 @@ PathGroup::~PathGroup()
|
|||
bool
|
||||
PathGroup::savable(PathEnd *path_end)
|
||||
{
|
||||
float threshold;
|
||||
{
|
||||
LockGuard lock(lock_);
|
||||
threshold = threshold_;
|
||||
}
|
||||
bool savable = false;
|
||||
if (compare_slack_) {
|
||||
// Crpr increases the slack, so check the slack
|
||||
// without crpr first because it is expensive to find.
|
||||
Slack slack = path_end->slackNoCrpr(sta_);
|
||||
if (!delayIsInitValue(slack, min_max_)
|
||||
&& delayLessEqual(slack, threshold_, sta_)
|
||||
&& delayLessEqual(slack, threshold, sta_)
|
||||
&& delayLessEqual(slack, slack_max_, sta_)) {
|
||||
// Now check with crpr.
|
||||
slack = path_end->slack(sta_);
|
||||
savable = delayLessEqual(slack, threshold_, sta_)
|
||||
savable = delayLessEqual(slack, threshold, sta_)
|
||||
&& delayLessEqual(slack, slack_max_, sta_)
|
||||
&& delayGreaterEqual(slack, slack_min_, sta_);
|
||||
}
|
||||
|
|
@ -113,7 +118,7 @@ PathGroup::savable(PathEnd *path_end)
|
|||
else {
|
||||
const Arrival &arrival = path_end->dataArrivalTime(sta_);
|
||||
savable = !delayIsInitValue(arrival, min_max_)
|
||||
&& delayGreaterEqual(arrival, threshold_, min_max_, sta_);
|
||||
&& delayGreaterEqual(arrival, threshold, min_max_, sta_);
|
||||
}
|
||||
return savable;
|
||||
}
|
||||
|
|
@ -123,8 +128,8 @@ PathGroup::insert(PathEnd *path_end)
|
|||
{
|
||||
LockGuard lock(lock_);
|
||||
path_ends_.push_back(path_end);
|
||||
if (group_count_ != group_count_max
|
||||
&& static_cast<int>(path_ends_.size()) > group_count_ * 2)
|
||||
if (group_path_count_ != group_path_count_max
|
||||
&& static_cast<int>(path_ends_.size()) > group_path_count_ * 2)
|
||||
prune();
|
||||
}
|
||||
|
||||
|
|
@ -137,9 +142,10 @@ PathGroup::prune()
|
|||
for (unsigned i = 0; i < path_ends_.size(); i++) {
|
||||
PathEnd *path_end = path_ends_[i];
|
||||
Vertex *vertex = path_end->vertex(sta_);
|
||||
// Squish up to endpoint_count path ends per vertex up to the front of path_ends_.
|
||||
if (end_count < group_count_
|
||||
&& path_counts[vertex] < endpoint_count_) {
|
||||
// Squish up to endpoint_path_count path ends per vertex
|
||||
// up to the front of path_ends_.
|
||||
if (end_count < group_path_count_
|
||||
&& path_counts[vertex] < endpoint_path_count_) {
|
||||
path_ends_[end_count++] = path_end;
|
||||
path_counts[vertex]++;
|
||||
}
|
||||
|
|
@ -175,7 +181,7 @@ PathGroup::iterator()
|
|||
void
|
||||
PathGroup::ensureSortedMaxPaths()
|
||||
{
|
||||
if (static_cast<int>(path_ends_.size()) > group_count_)
|
||||
if (static_cast<int>(path_ends_.size()) > group_path_count_)
|
||||
prune();
|
||||
else
|
||||
sort();
|
||||
|
|
@ -211,8 +217,8 @@ PathGroups::isGroupPathName(const char *group_name)
|
|||
|| stringEq(group_name, unconstrained_group_name_);
|
||||
}
|
||||
|
||||
PathGroups::PathGroups(int group_count,
|
||||
int endpoint_count,
|
||||
PathGroups::PathGroups(int group_path_count,
|
||||
int endpoint_path_count,
|
||||
bool unique_pins,
|
||||
float slack_min,
|
||||
float slack_max,
|
||||
|
|
@ -226,23 +232,25 @@ PathGroups::PathGroups(int group_count,
|
|||
bool unconstrained,
|
||||
const StaState *sta) :
|
||||
StaState(sta),
|
||||
group_count_(group_count),
|
||||
endpoint_count_(endpoint_count),
|
||||
group_path_count_(group_path_count),
|
||||
endpoint_path_count_(endpoint_path_count),
|
||||
unique_pins_(unique_pins),
|
||||
slack_min_(slack_min),
|
||||
slack_max_(slack_max)
|
||||
{
|
||||
makeGroups(group_count, endpoint_count, unique_pins, slack_min, slack_max, group_names,
|
||||
makeGroups(group_path_count, endpoint_path_count, unique_pins,
|
||||
slack_min, slack_max, group_names,
|
||||
setup, recovery, clk_gating_setup, unconstrained,
|
||||
MinMax::max());
|
||||
makeGroups(group_count, endpoint_count, unique_pins, slack_min, slack_max, group_names,
|
||||
makeGroups(group_path_count, endpoint_path_count, unique_pins,
|
||||
slack_min, slack_max, group_names,
|
||||
hold, removal, clk_gating_hold, unconstrained,
|
||||
MinMax::min());
|
||||
}
|
||||
|
||||
void
|
||||
PathGroups::makeGroups(int group_count,
|
||||
int endpoint_count,
|
||||
PathGroups::makeGroups(int group_path_count,
|
||||
int endpoint_path_count,
|
||||
bool unique_pins,
|
||||
float slack_min,
|
||||
float slack_max,
|
||||
|
|
@ -257,8 +265,10 @@ PathGroups::makeGroups(int group_count,
|
|||
if (setup_hold) {
|
||||
for (const auto [name, group] : sdc_->groupPaths()) {
|
||||
if (reportGroup(name, group_names)) {
|
||||
PathGroup *group = PathGroup::makePathGroupSlack(name, group_count,
|
||||
endpoint_count, unique_pins,
|
||||
PathGroup *group = PathGroup::makePathGroupSlack(name,
|
||||
group_path_count,
|
||||
endpoint_path_count,
|
||||
unique_pins,
|
||||
slack_min, slack_max,
|
||||
this);
|
||||
named_map_[mm_index][name] = group;
|
||||
|
|
@ -268,8 +278,10 @@ PathGroups::makeGroups(int group_count,
|
|||
for (auto clk : sdc_->clks()) {
|
||||
const char *clk_name = clk->name();
|
||||
if (reportGroup(clk_name, group_names)) {
|
||||
PathGroup *group = PathGroup::makePathGroupSlack(clk_name, group_count,
|
||||
endpoint_count, unique_pins,
|
||||
PathGroup *group = PathGroup::makePathGroupSlack(clk_name,
|
||||
group_path_count,
|
||||
endpoint_path_count,
|
||||
unique_pins,
|
||||
slack_min, slack_max,
|
||||
this);
|
||||
clk_map_[mm_index][clk] = group;
|
||||
|
|
@ -280,7 +292,8 @@ PathGroups::makeGroups(int group_count,
|
|||
if (setup_hold
|
||||
&& reportGroup(path_delay_group_name_, group_names))
|
||||
path_delay_[mm_index] = PathGroup::makePathGroupSlack(path_delay_group_name_,
|
||||
group_count, endpoint_count,
|
||||
group_path_count,
|
||||
endpoint_path_count,
|
||||
unique_pins,
|
||||
slack_min, slack_max,
|
||||
this);
|
||||
|
|
@ -290,7 +303,8 @@ PathGroups::makeGroups(int group_count,
|
|||
if (gated_clk
|
||||
&& reportGroup(gated_clk_group_name_, group_names))
|
||||
gated_clk_[mm_index] = PathGroup::makePathGroupSlack(gated_clk_group_name_,
|
||||
group_count, endpoint_count,
|
||||
group_path_count,
|
||||
endpoint_path_count,
|
||||
unique_pins,
|
||||
slack_min, slack_max,
|
||||
this);
|
||||
|
|
@ -300,7 +314,8 @@ PathGroups::makeGroups(int group_count,
|
|||
if (async
|
||||
&& reportGroup(async_group_name_, group_names))
|
||||
async_[mm_index] = PathGroup::makePathGroupSlack(async_group_name_,
|
||||
group_count, endpoint_count,
|
||||
group_path_count,
|
||||
endpoint_path_count,
|
||||
unique_pins,
|
||||
slack_min, slack_max,
|
||||
this);
|
||||
|
|
@ -311,8 +326,8 @@ PathGroups::makeGroups(int group_count,
|
|||
&& reportGroup(unconstrained_group_name_, group_names))
|
||||
unconstrained_[mm_index] =
|
||||
PathGroup::makePathGroupArrival(unconstrained_group_name_,
|
||||
group_count, endpoint_count, unique_pins,
|
||||
min_max, this);
|
||||
group_path_count, endpoint_path_count,
|
||||
unique_pins, min_max, this);
|
||||
else
|
||||
unconstrained_[mm_index] = nullptr;
|
||||
}
|
||||
|
|
@ -484,15 +499,15 @@ PathGroups::makePathEnds(ExceptionTo *to,
|
|||
bool sort_by_slack)
|
||||
{
|
||||
Stats stats(debug_, report_);
|
||||
makeGroupPathEnds(to, group_count_, endpoint_count_, unique_pins_,
|
||||
makeGroupPathEnds(to, group_path_count_, endpoint_path_count_, unique_pins_,
|
||||
corner, min_max);
|
||||
|
||||
PathEndSeq path_ends;
|
||||
pushGroupPathEnds(path_ends);
|
||||
if (sort_by_slack) {
|
||||
sort(path_ends, PathEndLess(this));
|
||||
if (static_cast<int>(path_ends.size()) > group_count_)
|
||||
path_ends.resize(group_count_);
|
||||
if (static_cast<int>(path_ends.size()) > group_path_count_)
|
||||
path_ends.resize(group_path_count_);
|
||||
}
|
||||
|
||||
if (unconstrained_paths
|
||||
|
|
@ -590,7 +605,7 @@ MakePathEnds1::vertexEnd(Vertex *)
|
|||
class MakePathEndsAll : public PathEndVisitor
|
||||
{
|
||||
public:
|
||||
MakePathEndsAll(int endpoint_count,
|
||||
MakePathEndsAll(int endpoint_path_count,
|
||||
PathGroups *path_groups);
|
||||
MakePathEndsAll(const MakePathEndsAll&) = default;
|
||||
virtual ~MakePathEndsAll();
|
||||
|
|
@ -602,7 +617,7 @@ private:
|
|||
void visitPathEnd(PathEnd *path_end,
|
||||
PathGroup *group);
|
||||
|
||||
int endpoint_count_;
|
||||
int endpoint_path_count_;
|
||||
PathGroups *path_groups_;
|
||||
const StaState *sta_;
|
||||
PathGroupEndsMap ends_;
|
||||
|
|
@ -610,9 +625,9 @@ private:
|
|||
PathEndNoCrprLess path_no_crpr_cmp_;
|
||||
};
|
||||
|
||||
MakePathEndsAll::MakePathEndsAll(int endpoint_count,
|
||||
MakePathEndsAll::MakePathEndsAll(int endpoint_path_count,
|
||||
PathGroups *path_groups) :
|
||||
endpoint_count_(endpoint_count),
|
||||
endpoint_path_count_(endpoint_path_count),
|
||||
path_groups_(path_groups),
|
||||
sta_(path_groups),
|
||||
slack_cmp_(path_groups),
|
||||
|
|
@ -674,7 +689,7 @@ MakePathEndsAll::vertexEnd(Vertex *)
|
|||
PathEndSeq::Iterator end_iter(ends);
|
||||
int n = 0;
|
||||
while (end_iter.hasNext()
|
||||
&& n < endpoint_count_) {
|
||||
&& n < endpoint_path_count_) {
|
||||
PathEnd *path_end = end_iter.next();
|
||||
// Only save the worst path end for each crpr tag.
|
||||
// PathEnum will peel the others.
|
||||
|
|
@ -714,18 +729,18 @@ MakePathEndsAll::vertexEnd(Vertex *)
|
|||
|
||||
void
|
||||
PathGroups::makeGroupPathEnds(ExceptionTo *to,
|
||||
int group_count,
|
||||
int endpoint_count,
|
||||
int group_path_count,
|
||||
int endpoint_path_count,
|
||||
bool unique_pins,
|
||||
const Corner *corner,
|
||||
const MinMaxAll *min_max)
|
||||
{
|
||||
if (endpoint_count == 1) {
|
||||
if (endpoint_path_count == 1) {
|
||||
MakePathEnds1 make_path_ends(this);
|
||||
makeGroupPathEnds(to, corner, min_max, &make_path_ends);
|
||||
}
|
||||
else {
|
||||
MakePathEndsAll make_path_ends(endpoint_count, this);
|
||||
MakePathEndsAll make_path_ends(endpoint_path_count, this);
|
||||
makeGroupPathEnds(to, corner, min_max, &make_path_ends);
|
||||
|
||||
for (auto path_min_max : MinMax::range()) {
|
||||
|
|
@ -734,41 +749,42 @@ PathGroups::makeGroupPathEnds(ExceptionTo *to,
|
|||
const char *name = name_group.first;
|
||||
PathGroup *group = findPathGroup(name, path_min_max);
|
||||
if (group)
|
||||
enumPathEnds(group, group_count, endpoint_count, unique_pins, true);
|
||||
enumPathEnds(group, group_path_count, endpoint_path_count, unique_pins, true);
|
||||
}
|
||||
|
||||
for (auto clk : sdc_->clks()) {
|
||||
PathGroup *group = findPathGroup(clk, path_min_max);
|
||||
if (group)
|
||||
enumPathEnds(group, group_count, endpoint_count, unique_pins, true);
|
||||
enumPathEnds(group, group_path_count, endpoint_path_count, unique_pins, true);
|
||||
}
|
||||
|
||||
PathGroup *group = unconstrained_[mm_index];
|
||||
if (group)
|
||||
enumPathEnds(group, group_count, endpoint_count, unique_pins, false);
|
||||
enumPathEnds(group, group_path_count, endpoint_path_count, unique_pins, false);
|
||||
group = path_delay_[mm_index];
|
||||
if (group)
|
||||
enumPathEnds(group, group_count, endpoint_count, unique_pins, true);
|
||||
enumPathEnds(group, group_path_count, endpoint_path_count, unique_pins, true);
|
||||
group = gated_clk_[mm_index];
|
||||
if (group)
|
||||
enumPathEnds(group, group_count, endpoint_count, unique_pins, true);
|
||||
enumPathEnds(group, group_path_count, endpoint_path_count, unique_pins, true);
|
||||
group = async_[mm_index];
|
||||
if (group)
|
||||
enumPathEnds(group, group_count, endpoint_count, unique_pins, true);
|
||||
enumPathEnds(group, group_path_count, endpoint_path_count, unique_pins, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PathGroups::enumPathEnds(PathGroup *group,
|
||||
int group_count,
|
||||
int endpoint_count,
|
||||
int group_path_count,
|
||||
int endpoint_path_count,
|
||||
bool unique_pins,
|
||||
bool cmp_slack)
|
||||
{
|
||||
// Insert the worst max_path path ends in the group into a path
|
||||
// enumerator.
|
||||
PathEnum path_enum(group_count, endpoint_count, unique_pins, cmp_slack, this);
|
||||
PathEnum path_enum(group_path_count, endpoint_path_count,
|
||||
unique_pins, cmp_slack, this);
|
||||
PathGroupIterator *end_iter = group->iterator();
|
||||
while (end_iter->hasNext()) {
|
||||
PathEnd *end = end_iter->next();
|
||||
|
|
@ -778,8 +794,8 @@ PathGroups::enumPathEnds(PathGroup *group,
|
|||
delete end_iter;
|
||||
group->clear();
|
||||
|
||||
// Parallel path enumeratation to find the endpoint_count/max path ends.
|
||||
for (int n = 0; path_enum.hasNext() && n < group_count; n++) {
|
||||
// Parallel path enumeratation to find the endpoint_path_count/max path ends.
|
||||
for (int n = 0; path_enum.hasNext() && n < group_path_count; n++) {
|
||||
PathEnd *end = path_enum.next();
|
||||
group->insert(end);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -726,6 +726,8 @@ getProperty(const LibertyCell *cell,
|
|||
return PropertyValue(cell->isBuffer());
|
||||
else if (stringEqual(property, "is_inverter"))
|
||||
return PropertyValue(cell->isInverter());
|
||||
else if (stringEqual(property, "is_memory"))
|
||||
return PropertyValue(cell->isMemory());
|
||||
else if (stringEqual(property, "dont_use"))
|
||||
return PropertyValue(cell->dontUse());
|
||||
else if (stringEqual(property, "area"))
|
||||
|
|
@ -769,7 +771,8 @@ getProperty(const Port *port,
|
|||
if (stringEqual(property, "name")
|
||||
|| stringEqual(property, "full_name"))
|
||||
return PropertyValue(network->name(port));
|
||||
else if (stringEqual(property, "direction"))
|
||||
else if (stringEqual(property, "direction")
|
||||
|| stringEqual(property, "port_direction"))
|
||||
return PropertyValue(network->direction(port)->name());
|
||||
else if (stringEqual(property, "liberty_port"))
|
||||
return PropertyValue(network->libertyPort(port));
|
||||
|
|
@ -868,7 +871,8 @@ getProperty(const LibertyPort *port,
|
|||
return PropertyValue(port->name());
|
||||
else if (stringEqual(property, "lib_cell"))
|
||||
return PropertyValue(port->libertyCell());
|
||||
else if (stringEqual(property, "direction"))
|
||||
else if (stringEqual(property, "direction")
|
||||
|| stringEqual(property, "port_direction"))
|
||||
return PropertyValue(port->direction()->name());
|
||||
else if (stringEqual(property, "capacitance")) {
|
||||
float cap = port->capacitance(RiseFall::rise(), MinMax::max());
|
||||
|
|
@ -955,7 +959,7 @@ getProperty(const Instance *inst,
|
|||
return PropertyValue(liberty_cell && liberty_cell->isInverter());
|
||||
else if (stringEqual(property, "is_macro"))
|
||||
return PropertyValue(liberty_cell && liberty_cell->isMacro());
|
||||
else if (stringEqual(property, "is_memory_cell"))
|
||||
else if (stringEqual(property, "is_memory"))
|
||||
return PropertyValue(liberty_cell && liberty_cell->isMemory());
|
||||
else
|
||||
throw PropertyUnknown("instance", property);
|
||||
|
|
@ -974,7 +978,8 @@ getProperty(const Pin *pin,
|
|||
return PropertyValue(network->portName(pin));
|
||||
else if (stringEqual(property, "full_name"))
|
||||
return PropertyValue(network->pathName(pin));
|
||||
else if (stringEqual(property, "direction"))
|
||||
else if (stringEqual(property, "direction")
|
||||
|| stringEqual(property, "pin_direction"))
|
||||
return PropertyValue(network->direction(pin)->name());
|
||||
else if (stringEqual(property, "is_hierarchical"))
|
||||
return PropertyValue(network->isHierarchical(pin));
|
||||
|
|
|
|||
|
|
@ -1103,7 +1103,7 @@ ReportPath::reportJson(const PathEnd *end,
|
|||
|
||||
if (end->checkRole(this)) {
|
||||
stringAppend(result, " \"data_arrival_time\": %.3e,\n",
|
||||
end->dataArrivalTimeOffset(this));
|
||||
delayAsFloat(end->dataArrivalTimeOffset(this)));
|
||||
|
||||
const MultiCyclePath *mcp = end->multiCyclePath();
|
||||
if (mcp)
|
||||
|
|
@ -1115,11 +1115,14 @@ ReportPath::reportJson(const PathEnd *end,
|
|||
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, " \"crpr\": %.3e,\n",
|
||||
delayAsFloat(end->checkCrpr(this)));
|
||||
stringAppend(result, " \"margin\": %.3e,\n",
|
||||
delayAsFloat(end->margin(this)));
|
||||
stringAppend(result, " \"required_time\": %.3e,\n",
|
||||
end->requiredTimeOffset(this));
|
||||
stringAppend(result, " \"slack\": %.3e\n", end->slack(this));
|
||||
delayAsFloat(end->requiredTimeOffset(this)));
|
||||
stringAppend(result, " \"slack\": %.3e\n",
|
||||
delayAsFloat(end->slack(this)));
|
||||
}
|
||||
result += "}";
|
||||
if (!last)
|
||||
|
|
@ -2426,10 +2429,16 @@ ReportPath::reportRequired(const PathEnd *end,
|
|||
{
|
||||
Required req_time = end->requiredTimeOffset(this);
|
||||
const EarlyLate *early_late = end->clkEarlyLate(this);
|
||||
float macro_clk_tree_delay = end->macroClkTreeDelay(this);
|
||||
ArcDelay margin = end->margin(this);
|
||||
if (end->minMax(this) == MinMax::max())
|
||||
if (end->minMax(this) == MinMax::min()) {
|
||||
margin = -margin;
|
||||
reportLine(margin_msg.c_str(), margin, req_time, early_late);
|
||||
macro_clk_tree_delay = -macro_clk_tree_delay;
|
||||
}
|
||||
if (macro_clk_tree_delay != 0.0)
|
||||
reportLine("macro clock tree delay", -macro_clk_tree_delay,
|
||||
req_time + margin, early_late);
|
||||
reportLine(margin_msg.c_str(), -margin, req_time, early_late);
|
||||
reportLine("data required time", req_time, early_late);
|
||||
reportDashLine();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -237,8 +237,10 @@ Search::init(StaState *sta)
|
|||
clk_info_set_ = new ClkInfoSet(ClkInfoLess(sta));
|
||||
tag_next_ = 0;
|
||||
tags_ = new Tag*[tag_capacity_];
|
||||
tags_prev_ = nullptr;
|
||||
tag_group_capacity_ = 127;
|
||||
tag_groups_ = new TagGroup*[tag_group_capacity_];
|
||||
tag_groups_prev_ = nullptr;
|
||||
tag_group_next_ = 0;
|
||||
tag_group_set_ = new TagGroupSet(tag_group_capacity_);
|
||||
pending_latch_outputs_ = new VertexSet(graph_);
|
||||
|
|
@ -270,7 +272,9 @@ Search::~Search()
|
|||
delete tag_set_;
|
||||
delete clk_info_set_;
|
||||
delete [] tags_;
|
||||
delete [] tags_prev_;
|
||||
delete [] tag_groups_;
|
||||
delete [] tag_groups_prev_;
|
||||
delete tag_group_set_;
|
||||
delete search_adj_;
|
||||
delete eval_pred_;
|
||||
|
|
@ -438,8 +442,8 @@ Search::findPathEnds(ExceptionFrom *from,
|
|||
bool unconstrained,
|
||||
const Corner *corner,
|
||||
const MinMaxAll *min_max,
|
||||
int group_count,
|
||||
int endpoint_count,
|
||||
int group_path_count,
|
||||
int endpoint_path_count,
|
||||
bool unique_pins,
|
||||
float slack_min,
|
||||
float slack_max,
|
||||
|
|
@ -457,7 +461,7 @@ Search::findPathEnds(ExceptionFrom *from,
|
|||
recovery = removal = false;
|
||||
if (!sdc_->gatedClkChecksEnabled())
|
||||
clk_gating_setup = clk_gating_hold = false;
|
||||
makePathGroups(group_count, endpoint_count, unique_pins,
|
||||
makePathGroups(group_path_count, endpoint_path_count, unique_pins,
|
||||
slack_min, slack_max,
|
||||
group_names, setup, hold,
|
||||
recovery, removal,
|
||||
|
|
@ -2135,6 +2139,18 @@ PathVisitor::visitFromPath(const Pin *from_pin,
|
|||
if (clk == nullptr
|
||||
|| !sdc_->clkStopPropagation(from_pin, clk)) {
|
||||
arc_delay = search_->deratedDelay(from_vertex, arc, edge, false, path_ap);
|
||||
|
||||
// Remove clock network delay for macros created with propagated
|
||||
// clocks when used in a context with ideal clocks.
|
||||
if (clk && clk->isIdeal()) {
|
||||
const LibertyPort *clk_port = network_->libertyPort(from_pin);
|
||||
const LibertyCell *inst_cell = clk_port->libertyCell();
|
||||
if (inst_cell->isMacro()) {
|
||||
float slew = delayAsFloat(from_path->slew(this));
|
||||
arc_delay -= clk_port->clkTreeDelay(slew, from_rf, min_max);
|
||||
}
|
||||
}
|
||||
|
||||
// Propagate from unclocked reg/latch clk pins, which have no
|
||||
// clk but are distinguished with a segment_start flag.
|
||||
if ((clk_edge == nullptr
|
||||
|
|
@ -2146,9 +2162,7 @@ PathVisitor::visitFromPath(const Pin *from_pin,
|
|||
// passed thru reg/latch D->Q edges.
|
||||
&& from_tag->isClock())) {
|
||||
const RiseFall *clk_rf = clk_edge ? clk_edge->transition() : nullptr;
|
||||
ClkInfo *to_clk_info = from_clk_info;
|
||||
if (network_->direction(to_pin)->isInternal())
|
||||
to_clk_info = search_->clkInfoWithCrprClkPath(from_clk_info,
|
||||
ClkInfo *to_clk_info = search_->clkInfoWithCrprClkPath(from_clk_info,
|
||||
from_path, path_ap);
|
||||
to_tag = search_->fromRegClkTag(from_pin, from_rf, clk, clk_rf,
|
||||
to_clk_info, to_pin, to_rf, min_max,
|
||||
|
|
@ -2647,15 +2661,15 @@ Search::findTagGroup(TagGroupBldr *tag_bldr)
|
|||
// std::vector doesn't seem to follow this protocol so multi-thread
|
||||
// search fails occasionally if a vector is used for tag_groups_.
|
||||
if (tag_group_next_ == tag_group_capacity_) {
|
||||
TagGroupIndex new_capacity = nextMersenne(tag_group_capacity_);
|
||||
TagGroup **new_tag_groups = new TagGroup*[new_capacity];
|
||||
memcpy(new_tag_groups, tag_groups_,
|
||||
TagGroupIndex tag_capacity = tag_group_capacity_ * 2;
|
||||
TagGroup **tag_groups = new TagGroup*[tag_capacity];
|
||||
memcpy(tag_groups, tag_groups_,
|
||||
tag_group_capacity_ * sizeof(TagGroup*));
|
||||
TagGroup **old_tag_groups = tag_groups_;
|
||||
tag_groups_ = new_tag_groups;
|
||||
tag_group_capacity_ = new_capacity;
|
||||
delete [] old_tag_groups;
|
||||
tag_group_set_->reserve(new_capacity);
|
||||
delete [] tag_groups_prev_;
|
||||
tag_groups_prev_ = tag_groups_;
|
||||
tag_groups_ = tag_groups;
|
||||
tag_group_capacity_ = tag_capacity;
|
||||
tag_group_set_->reserve(tag_capacity);
|
||||
}
|
||||
if (tag_group_next_ > tag_group_index_max)
|
||||
report_->critical(1510, "max tag group index exceeded");
|
||||
|
|
@ -2888,14 +2902,14 @@ Search::findTag(const RiseFall *rf,
|
|||
// std::vector doesn't seem to follow this protocol so multi-thread
|
||||
// search fails occasionally if a vector is used for tags_.
|
||||
if (tag_next_ == tag_capacity_) {
|
||||
TagIndex new_capacity = nextMersenne(tag_capacity_);
|
||||
Tag **new_tags = new Tag*[new_capacity];
|
||||
memcpy(new_tags, tags_, tag_capacity_ * sizeof(Tag*));
|
||||
Tag **old_tags = tags_;
|
||||
tags_ = new_tags;
|
||||
delete [] old_tags;
|
||||
tag_capacity_ = new_capacity;
|
||||
tag_set_->reserve(new_capacity);
|
||||
TagIndex tag_capacity = tag_capacity_ * 2;
|
||||
Tag **tags = new Tag*[tag_capacity];
|
||||
memcpy(tags, tags_, tag_capacity_ * sizeof(Tag*));
|
||||
delete [] tags_prev_;
|
||||
tags_prev_ = tags_;
|
||||
tags_ = tags;
|
||||
tag_capacity_ = tag_capacity;
|
||||
tag_set_->reserve(tag_capacity);
|
||||
}
|
||||
if (tag_next_ == tag_index_max)
|
||||
report_->critical(1511, "max tag index exceeded");
|
||||
|
|
@ -3982,8 +3996,8 @@ Search::wnsSlack(Vertex *vertex,
|
|||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
Search::makePathGroups(int group_count,
|
||||
int endpoint_count,
|
||||
Search::makePathGroups(int group_path_count,
|
||||
int endpoint_path_count,
|
||||
bool unique_pins,
|
||||
float slack_min,
|
||||
float slack_max,
|
||||
|
|
@ -3995,7 +4009,8 @@ Search::makePathGroups(int group_count,
|
|||
bool clk_gating_setup,
|
||||
bool clk_gating_hold)
|
||||
{
|
||||
path_groups_ = new PathGroups(group_count, endpoint_count, unique_pins,
|
||||
path_groups_ = new PathGroups(group_path_count, endpoint_path_count,
|
||||
unique_pins,
|
||||
slack_min, slack_max,
|
||||
group_names,
|
||||
setup, hold,
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ private:
|
|||
|
||||
%inline %{
|
||||
|
||||
int group_count_max = PathGroup::group_count_max;
|
||||
int group_path_count_max = PathGroup::group_path_count_max;
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -154,6 +154,7 @@ init_sta()
|
|||
initSta();
|
||||
}
|
||||
|
||||
// Clear all state except network.
|
||||
void
|
||||
clear_sta()
|
||||
{
|
||||
|
|
@ -217,7 +218,7 @@ endpoints()
|
|||
}
|
||||
|
||||
size_t
|
||||
endpoint_count()
|
||||
endpoint_path_count()
|
||||
{
|
||||
return Sta::sta()->endpointPins().size();
|
||||
}
|
||||
|
|
@ -318,7 +319,7 @@ vertex_worst_slack_path(Vertex *vertex,
|
|||
}
|
||||
|
||||
int
|
||||
tag_group_count()
|
||||
tag_group_path_count()
|
||||
{
|
||||
return Sta::sta()->tagGroupCount();
|
||||
}
|
||||
|
|
@ -429,8 +430,8 @@ find_path_ends(ExceptionFrom *from,
|
|||
bool unconstrained,
|
||||
Corner *corner,
|
||||
const MinMaxAll *delay_min_max,
|
||||
int group_count,
|
||||
int endpoint_count,
|
||||
int group_path_count,
|
||||
int endpoint_path_count,
|
||||
bool unique_pins,
|
||||
float slack_min,
|
||||
float slack_max,
|
||||
|
|
@ -447,7 +448,8 @@ find_path_ends(ExceptionFrom *from,
|
|||
Sta *sta = Sta::sta();
|
||||
PathEndSeq ends = sta->findPathEnds(from, thrus, to, unconstrained,
|
||||
corner, delay_min_max,
|
||||
group_count, endpoint_count, unique_pins,
|
||||
group_path_count, endpoint_path_count,
|
||||
unique_pins,
|
||||
slack_min, slack_max,
|
||||
sort_by_slack,
|
||||
groups->size() ? groups : nullptr,
|
||||
|
|
|
|||
|
|
@ -91,8 +91,8 @@ define_cmd_args "find_timing_paths" \
|
|||
[-path_delay min|min_rise|min_fall|max|max_rise|max_fall|min_max]\
|
||||
[-unconstrained]
|
||||
[-corner corner]\
|
||||
[-group_count path_count] \
|
||||
[-endpoint_count path_count]\
|
||||
[-group_path_count path_count] \
|
||||
[-endpoint_path_count path_count]\
|
||||
[-unique_paths_to_endpoint]\
|
||||
[-slack_max slack_max]\
|
||||
[-slack_min slack_min]\
|
||||
|
|
@ -111,6 +111,7 @@ proc find_timing_paths_cmd { cmd args_var } {
|
|||
parse_key_args $cmd args \
|
||||
keys {-from -rise_from -fall_from -to -rise_to -fall_to \
|
||||
-path_delay -corner -group_count -endpoint_count \
|
||||
-group_path_count -endpoint_path_count \
|
||||
-slack_max -slack_min -path_group} \
|
||||
flags {-unconstrained -sort_by_slack -unique_paths_to_endpoint} 0
|
||||
|
||||
|
|
@ -158,21 +159,31 @@ proc find_timing_paths_cmd { cmd args_var } {
|
|||
|
||||
set corner [parse_corner_or_all keys]
|
||||
|
||||
set endpoint_count 1
|
||||
if [info exists keys(-endpoint_count)] {
|
||||
set endpoint_count $keys(-endpoint_count)
|
||||
if { $endpoint_count < 1 } {
|
||||
sta_error 512 "-endpoint_count must be a positive integer."
|
||||
set endpoint_path_count 1
|
||||
if { [info exists keys(-endpoint_count)] } {
|
||||
# deprecated 2024-11-22
|
||||
sta_warn 502 "$cmd -endpoint_count is deprecated. Use -endpoint_path_count instead."
|
||||
set endpoint_path_count $keys(-endpoint_count)
|
||||
}
|
||||
if [info exists keys(-endpoint_path_count)] {
|
||||
set endpoint_path_count $keys(-endpoint_path_count)
|
||||
}
|
||||
if { $endpoint_path_count < 1 } {
|
||||
sta_error 512 "-endpoint_path_count must be a positive integer."
|
||||
}
|
||||
|
||||
set group_count $endpoint_count
|
||||
if [info exists keys(-group_count)] {
|
||||
set group_count $keys(-group_count)
|
||||
check_positive_integer "-group_count" $group_count
|
||||
if { $group_count < 1 } {
|
||||
sta_error 513 "-group_count must be >= 1."
|
||||
set group_path_count $endpoint_path_count
|
||||
if { [info exists keys(-group_count)] } {
|
||||
# deprecated 2024-11-22
|
||||
sta_warn 503 "$cmd -group_count is deprecated. Use -group_path_count instead."
|
||||
set group_path_count $keys(-group_count)
|
||||
}
|
||||
if [info exists keys(-group_path_count)] {
|
||||
set group_path_count $keys(-group_path_count)
|
||||
}
|
||||
check_positive_integer "-group_path_count" $group_path_count
|
||||
if { $group_path_count < 1 } {
|
||||
sta_error 513 "-group_path_count must be >= 1."
|
||||
}
|
||||
|
||||
set unique_pins [info exists flags(-unique_paths_to_endpoint)]
|
||||
|
|
@ -210,7 +221,7 @@ proc find_timing_paths_cmd { cmd args_var } {
|
|||
|
||||
set path_ends [find_path_ends $from $thrus $to $unconstrained \
|
||||
$corner $min_max \
|
||||
$group_count $endpoint_count $unique_pins \
|
||||
$group_path_count $endpoint_path_count $unique_pins \
|
||||
$slack_min $slack_max \
|
||||
$sort_by_slack $groups \
|
||||
1 1 1 1 1 1]
|
||||
|
|
@ -394,8 +405,8 @@ define_cmd_args "report_checks" \
|
|||
[-unconstrained]\
|
||||
[-path_delay min|min_rise|min_fall|max|max_rise|max_fall|min_max]\
|
||||
[-corner corner]\
|
||||
[-group_count path_count] \
|
||||
[-endpoint_count path_count]\
|
||||
[-group_path_count path_count] \
|
||||
[-endpoint_path_count path_count]\
|
||||
[-unique_paths_to_endpoint]\
|
||||
[-slack_max slack_max]\
|
||||
[-slack_min slack_min]\
|
||||
|
|
@ -551,16 +562,16 @@ proc_redirect report_check_types {
|
|||
set path_min_max "min"
|
||||
}
|
||||
if { $violators } {
|
||||
set group_count $sta::group_count_max
|
||||
set group_path_count $sta::group_path_count_max
|
||||
set slack_min [expr -$sta::float_inf]
|
||||
set slack_max 0.0
|
||||
} else {
|
||||
set group_count 1
|
||||
set group_path_count 1
|
||||
set slack_min [expr -$sta::float_inf]
|
||||
set slack_max $sta::float_inf
|
||||
}
|
||||
set path_ends [find_path_ends "NULL" {} "NULL" 0 \
|
||||
$corner $path_min_max $group_count 1 0 \
|
||||
$corner $path_min_max $group_path_count 1 0 \
|
||||
$slack_min $slack_max \
|
||||
0 {} \
|
||||
$setup $hold \
|
||||
|
|
|
|||
|
|
@ -2422,8 +2422,8 @@ Sta::findPathEnds(ExceptionFrom *from,
|
|||
bool unconstrained,
|
||||
const Corner *corner,
|
||||
const MinMaxAll *min_max,
|
||||
int group_count,
|
||||
int endpoint_count,
|
||||
int group_path_count,
|
||||
int endpoint_path_count,
|
||||
bool unique_pins,
|
||||
float slack_min,
|
||||
float slack_max,
|
||||
|
|
@ -2438,7 +2438,7 @@ Sta::findPathEnds(ExceptionFrom *from,
|
|||
{
|
||||
searchPreamble();
|
||||
return search_->findPathEnds(from, thrus, to, unconstrained,
|
||||
corner, min_max, group_count, endpoint_count,
|
||||
corner, min_max, group_path_count, endpoint_path_count,
|
||||
unique_pins, slack_min, slack_max,
|
||||
sort_by_slack, group_names,
|
||||
setup, hold,
|
||||
|
|
@ -2678,7 +2678,7 @@ Sta::findGroupPathPins(const char *group_path_name)
|
|||
nullptr, nullptr, nullptr, false,
|
||||
// corner, min_max,
|
||||
nullptr, MinMaxAll::max(),
|
||||
// group_count, endpoint_count, unique_pins
|
||||
// group_path_count, endpoint_path_count, unique_pins
|
||||
1, 1, false,
|
||||
-INF, INF, // slack_min, slack_max,
|
||||
false, // sort_by_slack
|
||||
|
|
|
|||
|
|
@ -607,7 +607,7 @@ tagStateEqual(ExceptionStateSet *states1,
|
|||
return false;
|
||||
}
|
||||
|
||||
// Match false, loop exception states only for crpr min/max paths.
|
||||
// Match loop exception states only for crpr min/max paths.
|
||||
static bool
|
||||
tagStateEqualCrpr(const Tag *tag1,
|
||||
const Tag *tag2)
|
||||
|
|
@ -622,8 +622,7 @@ tagStateEqualCrpr(const Tag *tag1,
|
|||
while (state_iter1.hasNext()) {
|
||||
state1 = state_iter1.next();
|
||||
ExceptionPath *exception1 = state1->exception();
|
||||
if (exception1->isFalse()
|
||||
|| exception1->isLoop())
|
||||
if (exception1->isLoop())
|
||||
break;
|
||||
else
|
||||
state1 = nullptr;
|
||||
|
|
@ -632,8 +631,7 @@ tagStateEqualCrpr(const Tag *tag1,
|
|||
while (state_iter2.hasNext()) {
|
||||
state2 = state_iter2.next();
|
||||
ExceptionPath *exception2 = state2->exception();
|
||||
if (exception2->isFalse()
|
||||
|| exception2->isLoop())
|
||||
if (exception2->isLoop())
|
||||
break;
|
||||
else
|
||||
state2 = nullptr;
|
||||
|
|
|
|||
|
|
@ -726,6 +726,33 @@ proc get_instances_error { arg_name arglist } {
|
|||
return $insts
|
||||
}
|
||||
|
||||
proc get_libcells_error { arg_name arglist } {
|
||||
set libcells {}
|
||||
# Copy backslashes that will be removed by foreach.
|
||||
set arglist [string map {\\ \\\\} $arglist]
|
||||
foreach arg $arglist {
|
||||
if {[llength $arg] > 1} {
|
||||
# Embedded list.
|
||||
set libcells [concat $libcells [get_libcells_error $arg_name $arg]]
|
||||
} elseif { [is_object $arg] } {
|
||||
set object_type [object_type $arg]
|
||||
if { $object_type == "LibertyCell" } {
|
||||
lappend libcells $arg
|
||||
} else {
|
||||
sta_error 128 "$arg_name type '$object_type' is not a liberty cell."
|
||||
}
|
||||
} elseif { $arg != {} } {
|
||||
set arg_libcells [get_lib_cells -quiet $arg]
|
||||
if { $arg_libcells != {} } {
|
||||
set libcells [concat $libcells $arg_libcells]
|
||||
} else {
|
||||
sta_error 129 "liberty cell '$arg' not found."
|
||||
}
|
||||
}
|
||||
}
|
||||
return $libcells
|
||||
}
|
||||
|
||||
proc get_port_pin_warn { arg_name arg } {
|
||||
return [get_port_pin_arg $arg_name $arg "warn"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
[get_cells -filter is_memory]
|
||||
sram_inst
|
||||
[get_lib_cells -filter is_memory]
|
||||
gf180mcu_fd_ip_sram__sram128x8m8wm1__ff_125C_1v98/gf180mcu_fd_ip_sram__sram128x8m8wm1
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
# Tests whether the is_memory attribute works for cells and libcells
|
||||
read_liberty gf180mcu_sram.lib.gz
|
||||
read_liberty asap7_small.lib.gz
|
||||
read_verilog get_is_memory.v
|
||||
link get_is_memory
|
||||
|
||||
# Test that the is_memory attribute is set correctly for cells
|
||||
puts {[get_cells -filter is_memory]}
|
||||
report_object_full_names [get_cells -filter is_memory]
|
||||
puts {[get_lib_cells -filter is_memory]}
|
||||
report_object_full_names [get_lib_cells -filter is_memory]
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
module get_is_memory (
|
||||
input CLK,
|
||||
input CEN,
|
||||
input GWEN,
|
||||
input [7:0] WEN,
|
||||
input [6:0] A,
|
||||
input [7:0] D,
|
||||
output [7:0] Q
|
||||
);
|
||||
|
||||
wire CEN_buf;
|
||||
wire GWEN_reg;
|
||||
|
||||
BUFx2_ASAP7_75t_R buf_inst (
|
||||
.A(CEN),
|
||||
.Y(CEN_buf)
|
||||
);
|
||||
|
||||
DFFHQx4_ASAP7_75t_R dff_inst (
|
||||
.CLK(CLK),
|
||||
.D(GWEN),
|
||||
.Q(GWEN_reg)
|
||||
);
|
||||
|
||||
gf180mcu_fd_ip_sram__sram128x8m8wm1 sram_inst (
|
||||
.CLK(CLK),
|
||||
.CEN(CEN_buf),
|
||||
.GWEN(GWEN_reg),
|
||||
.WEN(WEN),
|
||||
.A(A),
|
||||
.D(D),
|
||||
.Q(Q)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
[get_lib_pins -of_objects [get_lib_cells asap7_small/AND2x2_ASAP7_75t_R]]
|
||||
A
|
||||
B
|
||||
Y
|
||||
[get_lib_pins -of_objects [get_lib_cells *]]
|
||||
A
|
||||
A
|
||||
B
|
||||
CLK
|
||||
D
|
||||
IQ
|
||||
IQN
|
||||
Q
|
||||
Y
|
||||
Y
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
# Tests whether get_lib_pins -of_objects command works correctly
|
||||
|
||||
# Read in design and libraries
|
||||
read_liberty asap7_small.lib.gz
|
||||
read_verilog reg1_asap7.v
|
||||
link_design top
|
||||
|
||||
# Get the pins of the library cells
|
||||
puts {[get_lib_pins -of_objects [get_lib_cells asap7_small/AND2x2_ASAP7_75t_R]]}
|
||||
report_object_full_names [get_lib_pins -of_objects [get_lib_cells asap7_small/AND2x2_ASAP7_75t_R]]
|
||||
puts {[get_lib_pins -of_objects [get_lib_cells *]]}
|
||||
report_object_full_names [get_lib_pins -of_objects [get_lib_cells *]]
|
||||
Binary file not shown.
|
|
@ -309,7 +309,7 @@ proc run_test_valgrind { test cmd_file log_file } {
|
|||
}
|
||||
file delete $vg_cmd_file
|
||||
cleanse_logfile $test $log_file
|
||||
lappend error_msg [cleanse_valgrind_logfile $test $log_file]
|
||||
set error_msg [concat $error_msg [cleanse_valgrind_logfile $test $log_file]]
|
||||
return $error_msg
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -126,9 +126,11 @@ record_sta_tests {
|
|||
verilog_attribute
|
||||
liberty_arcs_one2one_1
|
||||
liberty_arcs_one2one_2
|
||||
get_is_memory
|
||||
get_filter
|
||||
get_noargs
|
||||
get_objrefs
|
||||
get_lib_pins_of_objects
|
||||
report_checks_src_attr
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,13 +19,17 @@
|
|||
#include <limits>
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
#include <cstdlib> // exit
|
||||
#include <array>
|
||||
#include <algorithm>
|
||||
|
||||
#include "Machine.hh"
|
||||
#include "Mutex.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
using std::max;
|
||||
|
||||
static void
|
||||
stringPrintTmp(const char *fmt,
|
||||
va_list args,
|
||||
|
|
@ -158,7 +162,6 @@ stringPrintTmp(const char *fmt,
|
|||
|
||||
if (tmp_length >= tmp_length1) {
|
||||
tmp_length1 = tmp_length + 1;
|
||||
stringDelete(tmp);
|
||||
tmp = makeTmpString(tmp_length1);
|
||||
va_copy(args_copy, args);
|
||||
tmp_length = vsnprint(tmp, tmp_length1, fmt, args_copy);
|
||||
|
|
@ -200,9 +203,10 @@ makeTmpString(size_t length)
|
|||
if (tmp_length < length) {
|
||||
// String isn't long enough. Make a new one.
|
||||
delete [] tmp_str;
|
||||
tmp_str = new char[length];
|
||||
tmp_length = max(tmp_string_initial_length, length);
|
||||
tmp_str = new char[tmp_length];
|
||||
tmp_strings[tmp_string_next] = tmp_str;
|
||||
tmp_string_lengths[tmp_string_next] = length;
|
||||
tmp_string_lengths[tmp_string_next] = tmp_length;
|
||||
}
|
||||
tmp_string_next++;
|
||||
return tmp_str;
|
||||
|
|
|
|||
Loading…
Reference in New Issue