diff --git a/CMakeLists.txt b/CMakeLists.txt index 3bd50074..43b627b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/dcalc/CcsCeffDelayCalc.cc b/dcalc/CcsCeffDelayCalc.cc index fbd331a4..cab8e115 100644 --- a/dcalc/CcsCeffDelayCalc.cc +++ b/dcalc/CcsCeffDelayCalc.cc @@ -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,9 +452,9 @@ 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 &y, - double &dy) { + double time = findRoot([&] (double t, + double &y, + double &dy) { vl(t, elmore, y, dy); y -= v; }, t_init, t_final + elmore * 3.0, .001, 20, root_fail); diff --git a/dcalc/DmpCeff.cc b/dcalc/DmpCeff.cc index c75b4990..0d3c8e91 100644 --- a/dcalc/DmpCeff.cc +++ b/dcalc/DmpCeff.cc @@ -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, diff --git a/dcalc/FindRoot.cc b/dcalc/FindRoot.cc index a6bdde60..78826d62 100644 --- a/dcalc/FindRoot.cc +++ b/dcalc/FindRoot.cc @@ -16,7 +16,7 @@ #include "FindRoot.hh" -#include // abs +#include // abs namespace sta { diff --git a/dcalc/ParallelDelayCalc.cc b/dcalc/ParallelDelayCalc.cc index 2648797c..a27f65b9 100644 --- a/dcalc/ParallelDelayCalc.cc +++ b/dcalc/ParallelDelayCalc.cc @@ -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)); } diff --git a/doc/ChangeLog.txt b/doc/ChangeLog.txt index 7ede9219..f4b323a7 100644 --- a/doc/ChangeLog.txt +++ b/doc/ChangeLog.txt @@ -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 ------------------------- diff --git a/doc/OpenSTA.odt b/doc/OpenSTA.odt index adfee96a..99fdb8ae 100644 Binary files a/doc/OpenSTA.odt and b/doc/OpenSTA.odt differ diff --git a/doc/OpenSTA.pdf b/doc/OpenSTA.pdf index 5c1a51e6..733d32d0 100644 Binary files a/doc/OpenSTA.pdf and b/doc/OpenSTA.pdf differ diff --git a/doc/messages.txt b/doc/messages.txt index 97d1a06a..95adafbe 100644 --- a/doc/messages.txt +++ b/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 diff --git a/include/sta/Clock.hh b/include/sta/Clock.hh index b5568e3d..841dfed8 100644 --- a/include/sta/Clock.hh +++ b/include/sta/Clock.hh @@ -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, diff --git a/include/sta/ConcreteLibrary.hh b/include/sta/ConcreteLibrary.hh index bacd91a0..7cf72ee6 100644 --- a/include/sta/ConcreteLibrary.hh +++ b/include/sta/ConcreteLibrary.hh @@ -38,7 +38,7 @@ class LibertyCell; class LibertyPort; typedef Map ConcreteCellMap; -typedef Map AttributeMap; +typedef std::map AttributeMap; typedef Vector ConcretePortSeq; typedef Map ConcretePortMap; typedef ConcreteCellMap::ConstIterator ConcreteLibraryCellIterator; diff --git a/include/sta/ConcreteNetwork.hh b/include/sta/ConcreteNetwork.hh index 7c62a4f7..69b7d188 100644 --- a/include/sta/ConcreteNetwork.hh +++ b/include/sta/ConcreteNetwork.hh @@ -38,7 +38,7 @@ class ConcreteBindingTbl; class ConcreteLibertyLibraryIterator; typedef Vector ConcreteLibrarySeq; -typedef Map AttributeMap; +typedef std::map AttributeMap; typedef Map ConcreteLibraryMap; typedef ConcreteLibrarySeq::ConstIterator ConcreteLibraryIterator; typedef Map ClockNameMap; typedef UnorderedMap ClockPinMap; typedef Set InputDelaySet; @@ -149,8 +161,8 @@ typedef Map PinCapLimitMap; typedef Map PortFanoutLimitMap; typedef Map CellFanoutLimitMap; typedef Map PortExtCapMap; -typedef Map NetWireCapMap; -typedef Map PinWireCapMap; +typedef Map NetWireCapMap; +typedef Map PinWireCapMap; typedef Map InstancePvtMap; typedef Map EdgeClockLatencyMap; typedef Map 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, diff --git a/include/sta/Search.hh b/include/sta/Search.hh index 5828f7ba..2c1f2504 100644 --- a/include/sta/Search.hh +++ b/include/sta/Search.hh @@ -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 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 tag_group_free_indices_; diff --git a/include/sta/Sta.hh b/include/sta/Sta.hh index f42fe4e2..7400399d 100644 --- a/include/sta/Sta.hh +++ b/include/sta/Sta.hh @@ -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 diff --git a/include/sta/Units.hh b/include/sta/Units.hh index c9e5baa6..541a8162 100644 --- a/include/sta/Units.hh +++ b/include/sta/Units.hh @@ -16,13 +16,16 @@ #pragma once +#include + 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) }; diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index 5c69c36d..d03e4a5b 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -2139,6 +2139,25 @@ LibertyPort::setScanSignalType(ScanSignalType type) scan_signal_type_ = type; } +static EnumNameMap 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 { diff --git a/liberty/Liberty.i b/liberty/Liberty.i index ec1ddec0..5bba029e 100644 --- a/liberty/Liberty.i +++ b/liberty/Liberty.i @@ -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 { diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc index e845792e..c9c796cd 100644 --- a/liberty/LibertyReader.cc +++ b/liberty/LibertyReader.cc @@ -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) { diff --git a/liberty/LibertyReaderPvt.hh b/liberty/LibertyReaderPvt.hh index 3c149df2..a750c3ad 100644 --- a/liberty/LibertyReaderPvt.hh +++ b/liberty/LibertyReaderPvt.hh @@ -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); diff --git a/liberty/LibertyWriter.cc b/liberty/LibertyWriter.cc index 63889584..5360ef0f 100644 --- a/liberty/LibertyWriter.cc +++ b/liberty/LibertyWriter.cc @@ -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", diff --git a/liberty/Units.cc b/liberty/Units.cc index 9b24173c..4874c19b 100644 --- a/liberty/Units.cc +++ b/liberty/Units.cc @@ -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(); } diff --git a/network/ConcreteLibrary.cc b/network/ConcreteLibrary.cc index 820f9206..9cfca944 100644 --- a/network/ConcreteLibrary.cc +++ b/network/ConcreteLibrary.cc @@ -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 ""; } diff --git a/network/ConcreteNetwork.cc b/network/ConcreteNetwork.cc index c6c3cd00..456c3bca 100644 --- a/network/ConcreteNetwork.cc +++ b/network/ConcreteNetwork.cc @@ -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 ""; } diff --git a/parasitics/ConcreteParasitics.cc b/parasitics/ConcreteParasitics.cc index d636ea05..5a78c154 100644 --- a/parasitics/ConcreteParasitics.cc +++ b/parasitics/ConcreteParasitics.cc @@ -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]; diff --git a/parasitics/SpefReader.cc b/parasitics/SpefReader.cc index 2c9c05a6..2eba572e 100644 --- a/parasitics/SpefReader.cc +++ b/parasitics/SpefReader.cc @@ -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); diff --git a/power/Power.cc b/power/Power.cc index f68c903c..da8261ea 100644 --- a/power/Power.cc +++ b/power/Power.cc @@ -20,6 +20,7 @@ #include // 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; } } diff --git a/power/VcdReader.cc b/power/VcdReader.cc index 92fc981c..75778080 100644 --- a/power/VcdReader.cc +++ b/power/VcdReader.cc @@ -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); diff --git a/sdc/Sdc.cc b/sdc/Sdc.cc index f02b9d6a..99db7c8a 100644 --- a/sdc/Sdc.cc +++ b/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 diff --git a/sdc/Sdc.tcl b/sdc/Sdc.tcl index b5cf3d65..f538bcfd 100644 --- a/sdc/Sdc.tcl +++ b/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,48 +674,58 @@ proc get_lib_pins { args } { set port_regexp1 [port_regexp_hsc $divider] set port_regexp2 [cell_regexp_hsc $divider] set ports {} - foreach pattern $patterns { - if { [is_object $pattern] } { - if { [object_type $pattern] != "LibertyPort" } { - sta_error 329 "object '$pattern' is not a liberty pin." - } - set ports [concat $ports $pattern] - } else { - # match library/cell/port - set libs {} - if { [regexp $port_regexp1 $pattern ignore lib_name cell_name port_pattern] } { - set libs [get_libs -quiet $lib_name] - # match cell/port - } elseif { [regexp $port_regexp2 $pattern ignore cell_name port_pattern] } { - set libs [get_libs *] - } else { - if { !$quiet } { - sta_warn 355 "library/cell/port '$pattern' not found." + 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" } { + sta_error 329 "object '$pattern' is not a liberty pin." } - return {} - } - if { $libs != {} } { - set found_match 0 - set cells {} - foreach lib $libs { - set cells [$lib find_liberty_cells_matching $cell_name $regexp $nocase] - foreach cell $cells { - set matches [$cell find_liberty_ports_matching $port_pattern \ - $regexp $nocase] - foreach match $matches { - lappend ports $match - set found_match 1 + set ports [concat $ports $pattern] + } else { + # match library/cell/port + set libs {} + if { [regexp $port_regexp1 $pattern ignore lib_name cell_name port_pattern] } { + set libs [get_libs -quiet $lib_name] + # match cell/port + } elseif { [regexp $port_regexp2 $pattern ignore cell_name port_pattern] } { + set libs [get_libs *] + } else { + if { !$quiet } { + sta_warn 355 "library/cell/port '$pattern' not found." + } + return {} + } + if { $libs != {} } { + set found_match 0 + set cells {} + foreach lib $libs { + set cells [$lib find_liberty_cells_matching $cell_name $regexp $nocase] + foreach cell $cells { + set matches [$cell find_liberty_ports_matching $port_pattern \ + $regexp $nocase] + foreach match $matches { + lappend ports $match + set found_match 1 + } } } - } - if { !$found_match } { - if { !$quiet } { - sta_warn 356 "port '$port_pattern' not found." + if { !$found_match } { + if { !$quiet } { + sta_warn 356 "port '$port_pattern' not found." + } + } + } else { + if { !$quiet } { + sta_warn 357 "library '$lib_name' not found." } - } - } else { - if { !$quiet } { - sta_warn 357 "library '$lib_name' not found." } } } diff --git a/search/Bfs.cc b/search/Bfs.cc index cdb6d3a7..eced2dd3 100644 --- a/search/Bfs.cc +++ b/search/Bfs.cc @@ -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); } } diff --git a/search/CheckSlewLimits.cc b/search/CheckSlewLimits.cc index 656b9a72..9ad90c05 100644 --- a/search/CheckSlewLimits.cc +++ b/search/CheckSlewLimits.cc @@ -87,6 +87,34 @@ 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, @@ -94,86 +122,121 @@ CheckSlewLimits::checkSlew(const Pin *pin, bool check_clks, // Return values. const Corner *&corner1, - const RiseFall *&rf, - Slew &slew, - float &limit, - float &slack) const + const RiseFall *&rf1, + Slew &slew1, + float &limit1, + float &slack1) 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); + 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) + checkSlew1(pin, vertex, corner, min_max, check_clks, + corner1, rf1, slew1, limit1, slack1); + if (bidirect_drvr_vertex) + checkSlew1(pin, bidirect_drvr_vertex, corner, min_max, check_clks, + corner1, rf1, slew1, limit1, slack1); +} + +void +CheckSlewLimits::checkSlew1(const Pin *pin, + const Vertex *vertex, + const Corner *corner, + const MinMax *min_max, + bool check_clks, + // Return values. + const Corner *&corner1, + const RiseFall *&rf1, + Slew &slew1, + float &limit1, + float &slack1) const +{ + if (!vertex->isDisabledConstraint() + && !vertex->isConstant() + && !sta_->clkNetwork()->isIdealClock(pin)) { + 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::checkSlews1(const Pin *pin, - const Corner *corner, - const MinMax *min_max, - bool check_clks, - // Return values. - const Corner *&corner1, - const RiseFall *&rf1, - Slew &slew1, - float &limit1, - float &slack1) const +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 { - Vertex *vertex, *bidirect_drvr_vertex; - sta_->graph()->pinVertices(pin, vertex, bidirect_drvr_vertex); - if (vertex) - checkSlews1(vertex, corner, min_max, check_clks, - corner1, rf1, slew1, limit1, slack1); - if (bidirect_drvr_vertex) - checkSlews1(bidirect_drvr_vertex, corner, min_max, check_clks, - corner1, rf1, slew1, limit1, slack1); -} - -void -CheckSlewLimits::checkSlews1(Vertex *vertex, - const Corner *corner, - const MinMax *min_max, - bool check_clks, - // Return values. - const Corner *&corner1, - const RiseFall *&rf1, - Slew &slew1, - float &limit1, - float &slack1) const -{ - const Pin *pin = vertex->pin(); - if (!vertex->isDisabledConstraint() - && !vertex->isConstant() - && !sta_->clkNetwork()->isIdealClock(pin)) { - for (auto rf : RiseFall::range()) { - float limit; - bool exists; - findLimit(pin, vertex, corner, rf, min_max, check_clks, - limit, exists); - if (exists) { - checkSlew(vertex, corner, rf, min_max, limit, - corner1, rf1, slew1, slack1, limit1); - } + for (const RiseFall *rf : RiseFall::range()) { + float limit; + bool exists; + findLimit(pin, corner, rf, min_max, clks, + limit, exists); + if (exists) { + 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), 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(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 diff --git a/search/CheckSlewLimits.hh b/search/CheckSlewLimits.hh index 9e70d69b..d0a8c3c2 100644 --- a/search/CheckSlewLimits.hh +++ b/search/CheckSlewLimits.hh @@ -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,43 +60,44 @@ public: bool &exists) const; protected: - void checkSlews1(const Pin *pin, - const Corner *corner, - const MinMax *min_max, - bool check_clks, - // Return values. - const Corner *&corner1, - const RiseFall *&rf1, - Slew &slew1, - float &limit1, - float &slack1) const; - void checkSlews1(Vertex *vertex, - const Corner *corner, - const MinMax *min_max, - bool check_clks, - // Return values. - const Corner *&corner1, - const RiseFall *&rf1, - Slew &slew1, - float &limit1, - float &slack1) const; - void checkSlew(Vertex *vertex, - const Corner *corner1, - const RiseFall *rf1, - const MinMax *min_max, - float limit1, - // Return values. - const Corner *&corner, - const RiseFall *&rf, - Slew &slew, - float &slack, - float &limit) const; + void checkSlew1(const Pin *pin, + const Vertex *vertex, + const Corner *corner, + const MinMax *min_max, + bool check_clks, + // Return values. + const Corner *&corner1, + const RiseFall *&rf1, + Slew &slew1, + float &limit1, + float &slack1) const; + void 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; + void checkSlew3(const Vertex *vertex, + const Corner *corner1, + const RiseFall *rf1, + const MinMax *min_max, + float limit1, + // Return values. + const Corner *&corner, + const RiseFall *&rf, + Slew &slew, + 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_; }; diff --git a/search/MakeTimingModel.cc b/search/MakeTimingModel.cc index 235b8920..0b75e964 100644 --- a/search/MakeTimingModel.cc +++ b/search/MakeTimingModel.cc @@ -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()) { diff --git a/search/MakeTimingModelPvt.hh b/search/MakeTimingModelPvt.hh index 7e3b83e4..c22ad730 100644 --- a/search/MakeTimingModelPvt.hh +++ b/search/MakeTimingModelPvt.hh @@ -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, diff --git a/search/PathEnd.cc b/search/PathEnd.cc index c62e640b..02fb39a2 100644 --- a/search/PathEnd.cc +++ b/search/PathEnd.cc @@ -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)); } diff --git a/search/PathEnum.cc b/search/PathEnum.cc index c41cef63..77621ffa 100644 --- a/search/PathEnum.cc +++ b/search/PathEnum.cc @@ -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(div_queue_.size()) > group_count_ * 2) + if (static_cast(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++; diff --git a/search/PathEnum.hh b/search/PathEnum.hh index 0c777260..b7dab956 100644 --- a/search/PathEnum.hh +++ b/search/PathEnum.hh @@ -52,8 +52,8 @@ private: class PathEnum : public Iterator, 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_; diff --git a/search/PathGroup.cc b/search/PathGroup.cc index 0b61358e..4efd309f 100644 --- a/search/PathGroup.cc +++ b/search/PathGroup.cc @@ -38,36 +38,36 @@ namespace sta { -int PathGroup::group_count_max = std::numeric_limits::max(); +int PathGroup::group_path_count_max = std::numeric_limits::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(path_ends_.size()) > group_count_ * 2) + if (group_path_count_ != group_path_count_max + && static_cast(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(path_ends_.size()) > group_count_) + if (static_cast(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(path_ends.size()) > group_count_) - path_ends.resize(group_count_); + if (static_cast(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); } diff --git a/search/Property.cc b/search/Property.cc index 568ec68c..764fc2e4 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -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)); diff --git a/search/ReportPath.cc b/search/ReportPath.cc index 04e9d71b..1eec5327 100644 --- a/search/ReportPath.cc +++ b/search/ReportPath.cc @@ -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(); } diff --git a/search/Search.cc b/search/Search.cc index 1a358e54..0a22323e 100644 --- a/search/Search.cc +++ b/search/Search.cc @@ -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,10 +2162,8 @@ 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, - from_path, path_ap); + 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, path_ap); @@ -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, diff --git a/search/Search.i b/search/Search.i index af12f7ea..f5af17c3 100644 --- a/search/Search.i +++ b/search/Search.i @@ -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, diff --git a/search/Search.tcl b/search/Search.tcl index 381da541..8e2db458 100644 --- a/search/Search.tcl +++ b/search/Search.tcl @@ -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 \ diff --git a/search/Sta.cc b/search/Sta.cc index 1253b2ca..05bd3dcc 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -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 diff --git a/search/Tag.cc b/search/Tag.cc index 81942b88..9cb73b5f 100644 --- a/search/Tag.cc +++ b/search/Tag.cc @@ -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; diff --git a/tcl/CmdArgs.tcl b/tcl/CmdArgs.tcl index aeed59f1..3cab4a07 100644 --- a/tcl/CmdArgs.tcl +++ b/tcl/CmdArgs.tcl @@ -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"] } diff --git a/test/get_is_memory.ok b/test/get_is_memory.ok new file mode 100644 index 00000000..e86527e2 --- /dev/null +++ b/test/get_is_memory.ok @@ -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 diff --git a/test/get_is_memory.tcl b/test/get_is_memory.tcl new file mode 100644 index 00000000..23080a99 --- /dev/null +++ b/test/get_is_memory.tcl @@ -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] diff --git a/test/get_is_memory.v b/test/get_is_memory.v new file mode 100644 index 00000000..face8af1 --- /dev/null +++ b/test/get_is_memory.v @@ -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 diff --git a/test/get_lib_pins_of_objects.ok b/test/get_lib_pins_of_objects.ok new file mode 100644 index 00000000..8c8489b9 --- /dev/null +++ b/test/get_lib_pins_of_objects.ok @@ -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 diff --git a/test/get_lib_pins_of_objects.tcl b/test/get_lib_pins_of_objects.tcl new file mode 100644 index 00000000..6e037d14 --- /dev/null +++ b/test/get_lib_pins_of_objects.tcl @@ -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 *]] diff --git a/test/gf180mcu_sram.lib.gz b/test/gf180mcu_sram.lib.gz new file mode 100644 index 00000000..b4ab4b9f Binary files /dev/null and b/test/gf180mcu_sram.lib.gz differ diff --git a/test/regression.tcl b/test/regression.tcl index 93da0b77..260c6cec 100755 --- a/test/regression.tcl +++ b/test/regression.tcl @@ -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 } diff --git a/test/regression_vars.tcl b/test/regression_vars.tcl index c97102f1..c2e27144 100644 --- a/test/regression_vars.tcl +++ b/test/regression_vars.tcl @@ -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 } diff --git a/util/StringUtil.cc b/util/StringUtil.cc index a20ac4a8..685ae389 100644 --- a/util/StringUtil.cc +++ b/util/StringUtil.cc @@ -19,13 +19,17 @@ #include #include #include +#include // exit #include +#include #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;