diff --git a/app/Main.cc b/app/Main.cc index 8957cd90..dfcb242c 100644 --- a/app/Main.cc +++ b/app/Main.cc @@ -117,11 +117,14 @@ staTclAppInit(int argc, Tcl_Eval(interp, "sta::show_splash"); if (!findCmdLineFlag(argc, argv, "-no_init")) { - string init_path = getenv("HOME"); - init_path += "/"; - init_path += init_filename; - if (is_regular_file(init_path.c_str())) - sourceTclFile(init_path.c_str(), true, true, interp); + const char *home = getenv("HOME"); + if (home) { + string init_path = home; + init_path += "/"; + init_path += init_filename; + if (is_regular_file(init_path.c_str())) + sourceTclFile(init_path.c_str(), true, true, interp); + } } bool exit_after_cmd_file = findCmdLineFlag(argc, argv, "-exit"); diff --git a/doc/OpenSTA.odt b/doc/OpenSTA.odt index 6502fdf6..f84199b4 100644 Binary files a/doc/OpenSTA.odt and b/doc/OpenSTA.odt differ diff --git a/doc/OpenSTA.pdf b/doc/OpenSTA.pdf index 56202108..2cb0cef1 100644 Binary files a/doc/OpenSTA.pdf and b/doc/OpenSTA.pdf differ diff --git a/include/sta/TimingArc.hh b/include/sta/TimingArc.hh index 776c456e..8e377fe7 100644 --- a/include/sta/TimingArc.hh +++ b/include/sta/TimingArc.hh @@ -146,6 +146,7 @@ public: LibertyCell *libertyCell() const; LibertyPort *from() const { return from_; } LibertyPort *to() const { return to_; } + bool isWire() const; LibertyPort *relatedOut() const { return related_out_; } TimingRole *role() const { return role_; }; TimingSense sense() const; diff --git a/liberty/TimingArc.cc b/liberty/TimingArc.cc index 8f84655c..8d232955 100644 --- a/liberty/TimingArc.cc +++ b/liberty/TimingArc.cc @@ -227,6 +227,12 @@ TimingArcSet::~TimingArcSet() arcs_.deleteContents(); } +bool +TimingArcSet::isWire() const +{ + return this == wire_timing_arc_set_; +} + LibertyCell * TimingArcSet::libertyCell() const { diff --git a/messages.txt b/messages.txt index 64eff74d..6f8a1670 100644 --- a/messages.txt +++ b/messages.txt @@ -1,62 +1,64 @@ -0001 DmpCeff.cc:1589 cell %s delay model not supported on SPF parasitics by DMP delay calculator +0001 DmpCeff.cc:1595 cell %s delay model not supported on SPF parasitics by DMP delay calculator 0002 Liberty.cc:729 cell %s/%s port %s not found in cell %s/%s. 0003 Liberty.cc:752 cell %s/%s %s -> %s timing group %s not found in cell %s/%s. 0004 Liberty.cc:1649 cell %s/%s %s -> %s latch enable %s_edge timing arc is inconsistent with %s -> %s setup_%s check. 0005 Liberty.cc:1664 cell %s/%s %s -> %s latch enable %s_edge is inconsistent with latch group enable function positive sense. 0006 Liberty.cc:1672 cell %s/%s %s -> %s latch enable %s_edge is inconsistent with latch group enable function negative sense. -0007 LibertyExpr.cc:76 %s references unknown port %s. -0008 ConcreteNetwork.cc:1869 cell type %s can not be linked. -0009 Sdc.cc:2465 No common period was found between clocks %s and %s. -0010 Genclks.cc:289 no master clock found for generated clock %s. -0011 Genclks.cc:331 generated clock %s is in the fanout of multiple clocks. -0013 Genclks.cc:990 generated clock %s source pin %s missing paths from master clock %s. -0015 Sim.cc:869 propagated logic value %c differs from constraint value of %c on pin %s. -0016 Sta.cc:2016 '%s' is not a valid startoint. -0017 Sta.cc:2091 '%s' is not a valid endpoint. +0007 LibertyExpr.cc:78 %s references unknown port %s. +0008 ConcreteNetwork.cc:1873 cell type %s can not be linked. +0009 CycleAccting.cc:87 No common period was found between clocks %s and %s. +0010 Genclks.cc:292 no master clock found for generated clock %s. +0011 Genclks.cc:334 generated clock %s is in the fanout of multiple clocks. +0013 Genclks.cc:1001 generated clock %s source pin %s missing paths from master clock %s. +0015 Sim.cc:871 propagated logic value %c differs from constraint value of %c on pin %s. +0016 Sta.cc:2013 '%s' is not a valid startoint. +0017 Sta.cc:2089 '%s' is not a valid endpoint. 0021 SpefParse.yy:805 %d is not positive. 0022 SpefParse.yy:814 %.4f is not positive. 0023 SpefParse.yy:820 %.4f is not positive. 0024 WritePathSpice.cc:425 pg_pin %s/%s voltage %s not found, 0025 WritePathSpice.cc:432 Liberty pg_port %s/%s missing voltage_name attribute, 0026 WritePathSpice.cc:962 %s pg_port %s not found, -0027 WritePathSpice.cc:1016 no register/latch found for path from %s to %s, -0028 WritePathSpice.cc:1383 The following subkcts are missing from %s -0029 WritePathSpice.cc:1441 subckt %s port %s has no corresponding liberty port, pg_port and is not power or ground. -0160 Sta.cc:2013 '%s' is not a valid startpoint. -0161 Sta.cc:2088 '%s' is not a valid endpoint. -0162 VerilogReader.cc:1744 %s is not a verilog module. -0163 VerilogReader.cc:1749 %s is not a verilog module. -0179 SpefReader.cc:725 %s. +0027 WritePathSpice.cc:1017 no register/latch found for path from %s to %s, +0028 WritePathSpice.cc:1384 The following subkcts are missing from %s +0029 WritePathSpice.cc:1442 subckt %s port %s has no corresponding liberty port, pg_port and is not power or ground. +0160 Sta.cc:2010 '%s' is not a valid startpoint. +0161 Sta.cc:2086 '%s' is not a valid endpoint. +0162 VerilogReader.cc:1746 %s is not a verilog module. +0163 VerilogReader.cc:1751 %s is not a verilog module. +0179 SpefReader.cc:728 %s. 0201 StaTcl.i:128 no network has been linked. 0202 StaTcl.i:142 network does not support edits. -0204 StaTcl.i:4158 POCV support requires compilation with SSTA=1. -0206 LibertyExpr.cc:169 %s %s. -0207 GraphDelayCalc1.cc:750 port not found in cell +0204 StaTcl.i:4172 POCV support requires compilation with SSTA=1. +0206 LibertyExpr.cc:171 %s %s. +0207 GraphDelayCalc1.cc:743 port not found in cell 0208 Graph.cc:796 arc_delay_annotated array bounds exceeded 0209 Graph.cc:811 arc_delay_annotated array bounds exceeded 0210 Graph.cc:823 arc_delay_annotated array bounds exceeded 0211 SdcNetwork.cc:1026 inst path string lenth estimate busted 0212 SdcNetwork.cc:1098 inst path string lenth estimate exceeded -0213 Sdc.cc:4181 group path name and is_default are mutually exclusive. -0214 WriteSdc.cc:1339 unknown exception type -0215 WriteSdc.cc:1910 illegal set_logic value -0216 WriteSdc.cc:1954 invalid set_case_analysis value +0213 Sdc.cc:4126 group path name and is_default are mutually exclusive. +0214 WriteSdc.cc:1334 unknown exception type +0215 WriteSdc.cc:1905 illegal set_logic value +0216 WriteSdc.cc:1949 invalid set_case_analysis value 0228 Graph.cc:836 arc_delay_annotated array bounds exceeded 0251 PathEnumed.cc:126 enumerated path required time 0252 PathEnumed.cc:135 enumerated path required time 0253 PathGroup.cc:402 unknown path end type -0254 PathVertexRep.cc:144 tag group missing tag -0255 ReportPath.cc:287 unsupported path type -0256 ReportPath.cc:308 unsupported path type -0257 ReportPath.cc:347 unsupported path type -0258 ReportPath.cc:2224 generated clock pll source path too short. -0259 ReportPath.cc:2387 unsupported path type -0260 Search.cc:2666 max tag group index exceeded -0261 Search.cc:2898 max tag index exceeded -0262 Search.cc:3586 unexpected filter path -0263 Search.cc:3754 tns incr existing vertex -0264 Sta.cc:4101 corresponding timing arc set not found in equiv cells -0265 TagGroup.cc:321 tag group missing tag +0254 PathVertexRep.cc:145 tag group missing tag +0255 ReportPath.cc:289 unsupported path type +0256 ReportPath.cc:310 unsupported path type +0257 ReportPath.cc:349 unsupported path type +0258 ReportPath.cc:2228 generated clock pll source path too short. +0259 ReportPath.cc:2392 unsupported path type +0260 Search.cc:2667 max tag group index exceeded +0261 Search.cc:2899 max tag index exceeded +0262 Search.cc:3594 unexpected filter path +0263 Search.cc:3762 tns incr existing vertex +0264 Sta.cc:4102 corresponding timing arc set not found in equiv cells +0265 TagGroup.cc:297 tag group missing tag +0272 StaTcl.i:4158 unknown common clk pessimism mode. +0273 StaTcl.i:5088 unknown clock sense 0300 Util.tcl:218 no commands match '$pattern'. 0301 Power.tcl:207 activity should be 0.0 to 1.0 or 2.0 0302 Power.tcl:215 duty should be 0.0 to 1.0 @@ -68,59 +70,60 @@ 0315 Cmds.tcl:856 $arg_name '$object_type' is not a net. 0316 Cmds.tcl:861 $arg_name '$arg' not found. 0318 Search.tcl:1045 unknown path group '$name'. -0319 Sdc.tcl:277 $unit scale [format %.0e $scale] does not match library scale [format %.0e $unit_scale]. -0320 Sdc.tcl:478 current_design for other than top cell not supported. -0321 Sdc.tcl:515 patterns argument not supported with -of_objects. -0322 Sdc.tcl:550 instance '$pattern' not found. -0323 Sdc.tcl:611 clock '$pattern' not found. -0324 Sdc.tcl:638 positional arguments not supported with -of_objects. -0325 Sdc.tcl:664 library '$lib_name' not found. -0326 Sdc.tcl:676 cell '$cell_pattern' not found. -0327 Sdc.tcl:723 library/cell/port '$pattern' not found. -0328 Sdc.tcl:743 port '$port_pattern' not found. -0329 Sdc.tcl:748 library '$lib_name' not found. -0330 Sdc.tcl:758 -nocase ignored without -regexp. -0331 Sdc.tcl:784 library '$pattern' not found. -0332 Sdc.tcl:847 patterns argument not supported with -of_objects. -0333 Sdc.tcl:871 net '$pattern' not found. -0334 Sdc.tcl:900 patterns argument not supported with -of_objects. -0335 Sdc.tcl:937 pin '$pattern' not found. -0336 Sdc.tcl:994 patterns argument not supported with -of_objects. -0337 Sdc.tcl:1008 port '$pattern' not found. -0338 Sdc.tcl:1106 non-increasing clock -waveform edge times. -0339 Sdc.tcl:1109 -waveform time greater than two periods. -0341 Sdc.tcl:1467 extra positional argument $arg. -0342 Sdc.tcl:1500 -clock ignored for clock objects. -0343 Sdc.tcl:1546 set_sense -type data not supported. -0344 Sdc.tcl:1561 set_clock_sense is deprecated as of SDC 2.1. Use set_sense -type clock. -0345 Sdc.tcl:1573 -pulse argument not supported. -0346 Sdc.tcl:1582 -positive, -negative, -stop_propagation and -pulse are mutually exclusive. -0347 Sdc.tcl:1595 hierarchical pin '[get_full_name $pin]' not supported. -0348 Sdc.tcl:1797 -from/-to keywords ignored for lib_pin, port and pin arguments. -0349 Sdc.tcl:1465 unknown keyword argument $arg. -0350 Sdc.tcl:1945 -from, -through or -to required. -0351 Sdc.tcl:2024 -source_latency_included ignored with -reference_pin. -0352 Sdc.tcl:2027 -network_latency_included ignored with -reference_pin. -0353 Sdc.tcl:2046 $cmd not allowed on [pin_direction $pin] port '[get_full_name $pin]'. -0354 Sdc.tcl:2048 $cmd relative to a clock defined on the same port/pin not allowed. -0355 Sdc.tcl:2091 '$args' ignored. -0356 Sdc.tcl:2221 '$args' ignored. -0357 Sdc.tcl:2268 virtual clock [get_name $clk] can not be propagated. -0358 Sdc.tcl:2417 -multiply_by ignored. -0359 Sdc.tcl:2420 -dont_scale ignored. -0360 Sdc.tcl:2423 -no_design_rule ignored. -0361 Sdc.tcl:2464 -clock not supported. -0362 Sdc.tcl:2467 -clock_fall not supported. -0363 Sdc.tcl:2513 -pin_load not allowed for net objects. -0364 Sdc.tcl:2516 -wire_load not allowed for net objects. -0365 Sdc.tcl:2519 -rise/-fall not allowed for net objects. -0366 Sdc.tcl:2652 -data_path, -clock_path, -rise, -fall ignored for ports and designs. -0367 Sdc.tcl:2722 derating factor greater than 2.0. -0368 Sdc.tcl:2759 -cell_delay and -cell_check flags ignored for net objects. -0369 Sdc.tcl:2818 no valid objects specified for $key. -0370 Sdc.tcl:2851 no valid objects specified for $key -0371 Sdc.tcl:3012 set_wire_load_min_block_size not supported. +0319 Sdc.tcl:278 $unit scale [format %.0e $scale] does not match library scale [format %.0e $unit_scale]. +0320 Sdc.tcl:479 current_design for other than top cell not supported. +0321 Sdc.tcl:516 patterns argument not supported with -of_objects. +0322 Sdc.tcl:551 instance '$pattern' not found. +0323 Sdc.tcl:612 clock '$pattern' not found. +0324 Sdc.tcl:639 positional arguments not supported with -of_objects. +0325 Sdc.tcl:665 library '$lib_name' not found. +0326 Sdc.tcl:677 cell '$cell_pattern' not found. +0327 Sdc.tcl:724 library/cell/port '$pattern' not found. +0328 Sdc.tcl:744 port '$port_pattern' not found. +0329 Sdc.tcl:749 library '$lib_name' not found. +0330 Sdc.tcl:759 -nocase ignored without -regexp. +0331 Sdc.tcl:785 library '$pattern' not found. +0332 Sdc.tcl:848 patterns argument not supported with -of_objects. +0333 Sdc.tcl:872 net '$pattern' not found. +0334 Sdc.tcl:901 patterns argument not supported with -of_objects. +0335 Sdc.tcl:938 pin '$pattern' not found. +0336 Sdc.tcl:995 patterns argument not supported with -of_objects. +0337 Sdc.tcl:1009 port '$pattern' not found. +0338 Sdc.tcl:1107 non-increasing clock -waveform edge times. +0339 Sdc.tcl:1110 -waveform time greater than two periods. +0341 Sdc.tcl:1468 extra positional argument $arg. +0342 Sdc.tcl:1501 -clock ignored for clock objects. +0343 Sdc.tcl:1547 set_sense -type data not supported. +0344 Sdc.tcl:1562 set_clock_sense is deprecated as of SDC 2.1. Use set_sense -type clock. +0345 Sdc.tcl:1574 -pulse argument not supported. +0346 Sdc.tcl:1583 -positive, -negative, -stop_propagation and -pulse are mutually exclusive. +0347 Sdc.tcl:1596 hierarchical pin '[get_full_name $pin]' not supported. +0348 Sdc.tcl:1798 -from/-to keywords ignored for lib_pin, port and pin arguments. +0349 Sdc.tcl:1466 unknown keyword argument $arg. +0350 Sdc.tcl:1946 -from, -through or -to required. +0351 Sdc.tcl:2025 -source_latency_included ignored with -reference_pin. +0352 Sdc.tcl:2028 -network_latency_included ignored with -reference_pin. +0353 Sdc.tcl:2047 $cmd not allowed on [pin_direction $pin] port '[get_full_name $pin]'. +0354 Sdc.tcl:2049 $cmd relative to a clock defined on the same port/pin not allowed. +0355 Sdc.tcl:2092 '$args' ignored. +0356 Sdc.tcl:2222 '$args' ignored. +0357 Sdc.tcl:2269 virtual clock [get_name $clk] can not be propagated. +0358 Sdc.tcl:2418 -multiply_by ignored. +0359 Sdc.tcl:2421 -dont_scale ignored. +0360 Sdc.tcl:2424 -no_design_rule ignored. +0361 Sdc.tcl:2465 -clock not supported. +0362 Sdc.tcl:2468 -clock_fall not supported. +0363 Sdc.tcl:2514 -pin_load not allowed for net objects. +0364 Sdc.tcl:2517 -wire_load not allowed for net objects. +0365 Sdc.tcl:2520 -rise/-fall not allowed for net objects. +0366 Sdc.tcl:2653 -data_path, -clock_path, -rise, -fall ignored for ports and designs. +0367 Sdc.tcl:2723 derating factor greater than 2.0. +0368 Sdc.tcl:2760 -cell_delay and -cell_check flags ignored for net objects. +0369 Sdc.tcl:2819 no valid objects specified for $key. +0370 Sdc.tcl:2852 no valid objects specified for $key +0371 Sdc.tcl:3013 set_wire_load_min_block_size not supported. 0372 NetworkEdit.tcl:80 connect_pins is deprecated. Use connect_pin. +0373 Sdc.tcl:3163 define_corners must be called before read_liberty. 0400 Util.tcl:44 $cmd $key missing value. 0401 Util.tcl:61 $cmd $key missing value. 0402 Util.tcl:71 $cmd $arg is not a known keyword or flag. @@ -231,80 +234,80 @@ 0509 Search.tcl:814 pin '$pin_arg' is hierarchical. 0510 Search.tcl:880 -format $format not recognized. 0511 Sdc.tcl:64 cannot open '$filename'. -0512 Sdc.tcl:116 incomplete command at end of file. -0513 Sdc.tcl:202 hierarchy separator must be one of '$sdc_dividers'. -0514 Sdc.tcl:248 unknown unit $unit '$suffix'. -0515 Sdc.tcl:321 unknown $unit unit '$suffix'. -0516 Sdc.tcl:584 unsupported -filter expression. -0517 Sdc.tcl:969 unsupported -filter expression. -0518 Sdc.tcl:1045 unsupported -filter expression. -0519 Sdc.tcl:1078 -add requires -name. -0520 Sdc.tcl:1083 -name or port_pin_list must be specified. -0521 Sdc.tcl:1091 missing -period argument. -0522 Sdc.tcl:1097 -waveform edge_list must have an even number of edge times. -0523 Sdc.tcl:1150 empty ports/pins/nets argument. -0524 Sdc.tcl:1158 -add requires -name. -0525 Sdc.tcl:1163 name or port_pin_list must be specified. -0526 Sdc.tcl:1170 missing -source argument. -0527 Sdc.tcl:1187 -master_clock argument empty. -0528 Sdc.tcl:1190 -add requireds -master_clock. -0529 Sdc.tcl:1194 -multiply_by and -divide_by options are exclusive. -0530 Sdc.tcl:1198 -divide_by is not an integer greater than one. -0531 Sdc.tcl:1201 -combinational implies -divide_by 1. -0532 Sdc.tcl:1206 -multiply_by is not an integer greater than one. -0533 Sdc.tcl:1212 -duty_cycle is not a float between 0 and 100. -0534 Sdc.tcl:1218 -edges only supported for three edges. -0535 Sdc.tcl:1224 edges times are not monotonically increasing. -0536 Sdc.tcl:1233 -edge_shift length does not match -edges length. -0537 Sdc.tcl:1239 missing -multiply_by, -divide_by, -combinational or -edges argument. -0538 Sdc.tcl:1247 cannot specify -invert without -multiply_by, -divide_by or -combinational. -0539 Sdc.tcl:1253 -duty_cycle requires -multiply_by value. -0540 Sdc.tcl:1258 missing -pll_output argument. -0541 Sdc.tcl:1261 missing -pll_feedback argument. -0542 Sdc.tcl:1267 PLL output and feedback pins must be on the same instance. -0543 Sdc.tcl:1270 source pin must be on the same instance as the PLL output pin. -0544 Sdc.tcl:1273 PLL output must be one of the clock pins. -0545 Sdc.tcl:1311 group_path command failed. -0546 Sdc.tcl:1318 positional arguments not supported. -0547 Sdc.tcl:1322 -from, -through or -to required. -0548 Sdc.tcl:1328 -name and -default are mutually exclusive. -0549 Sdc.tcl:1330 -name or -default option is required. -0550 Sdc.tcl:1371 cannot specify both -high and -low. -0551 Sdc.tcl:1379 missing -setup or -hold argument. -0552 Sdc.tcl:1393 -high and -low only permitted for pins and instances. -0553 Sdc.tcl:1400 -high and -low only permitted for pins and instances. -0554 Sdc.tcl:1443 one of -logically_exclusive, -physically_exclusive or -asynchronous is required. -0555 Sdc.tcl:1446 the keywords -logically_exclusive, -physically_exclusive and -asynchronous are mutually exclusive. -0556 Sdc.tcl:1514 -source '[get_full_name $pin]' is not a clock pin. -0557 Sdc.tcl:1521 -early/-late is only allowed with -source. -0558 Sdc.tcl:1550 set_sense -type clock|data -0559 Sdc.tcl:1619 transition time can not be specified for virtual clocks. -0560 Sdc.tcl:1640 missing uncertainty value. -0561 Sdc.tcl:1682 -from/-to must be used together. -0562 Sdc.tcl:1702 -rise, -fall options not allowed for single clock uncertainty. -0563 Sdc.tcl:1743 missing -from, -rise_from or -fall_from argument. -0564 Sdc.tcl:1755 missing -to, -rise_to or -fall_to argument. -0565 Sdc.tcl:1827 -from/-to hierarchical instance not supported. -0566 Sdc.tcl:1859 pin '[get_full_name $inst]${hierarchy_separator}${port_name}' not found. -0567 Sdc.tcl:1900 pin '[get_name $cell]${hierarchy_separator}${port_name}' not found. -0568 Sdc.tcl:2085 missing delay argument. -0569 Sdc.tcl:2216 missing path multiplier argument. -0570 Sdc.tcl:2228 cannot use -start with -end. -0571 Sdc.tcl:2296 value must be 0, zero, 1, one, rise, rising, fall, or falling. -0572 Sdc.tcl:2354 cell '$lib_name:$cell_name' not found. -0573 Sdc.tcl:2360 '$cell_name' not found. -0574 Sdc.tcl:2364 missing -lib_cell argument. -0575 Sdc.tcl:2372 port '$to_port_name' not found. -0576 Sdc.tcl:2384 -pin argument required for cells with multiple outputs. -0577 Sdc.tcl:2399 port '$from_port_name' not found. -0578 Sdc.tcl:2606 port '[get_name $port]' is not an input. -0579 Sdc.tcl:2968 operating condition '$op_cond_name' not found. -0580 Sdc.tcl:2986 operating condition '$op_cond_name' not found. -0581 Sdc.tcl:3000 -analysis_type must be single, bc_wc or on_chip_variation. -0582 Sdc.tcl:3025 mode must be top, enclosed or segmented. -0583 Sdc.tcl:3040 no wire load model specified. -0584 Sdc.tcl:3101 wire load selection group '$selection_name' not found. -0585 Sdc.tcl:3229 no default operating conditions found. +0512 Sdc.tcl:119 incomplete command at end of file. +0513 Sdc.tcl:203 hierarchy separator must be one of '$sdc_dividers'. +0514 Sdc.tcl:249 unknown unit $unit '$suffix'. +0515 Sdc.tcl:322 unknown $unit unit '$suffix'. +0516 Sdc.tcl:585 unsupported -filter expression. +0517 Sdc.tcl:970 unsupported -filter expression. +0518 Sdc.tcl:1046 unsupported -filter expression. +0519 Sdc.tcl:1079 -add requires -name. +0520 Sdc.tcl:1084 -name or port_pin_list must be specified. +0521 Sdc.tcl:1092 missing -period argument. +0522 Sdc.tcl:1098 -waveform edge_list must have an even number of edge times. +0523 Sdc.tcl:1151 empty ports/pins/nets argument. +0524 Sdc.tcl:1159 -add requires -name. +0525 Sdc.tcl:1164 name or port_pin_list must be specified. +0526 Sdc.tcl:1171 missing -source argument. +0527 Sdc.tcl:1188 -master_clock argument empty. +0528 Sdc.tcl:1191 -add requireds -master_clock. +0529 Sdc.tcl:1195 -multiply_by and -divide_by options are exclusive. +0530 Sdc.tcl:1199 -divide_by is not an integer greater than one. +0531 Sdc.tcl:1202 -combinational implies -divide_by 1. +0532 Sdc.tcl:1207 -multiply_by is not an integer greater than one. +0533 Sdc.tcl:1213 -duty_cycle is not a float between 0 and 100. +0534 Sdc.tcl:1219 -edges only supported for three edges. +0535 Sdc.tcl:1225 edges times are not monotonically increasing. +0536 Sdc.tcl:1234 -edge_shift length does not match -edges length. +0537 Sdc.tcl:1240 missing -multiply_by, -divide_by, -combinational or -edges argument. +0538 Sdc.tcl:1248 cannot specify -invert without -multiply_by, -divide_by or -combinational. +0539 Sdc.tcl:1254 -duty_cycle requires -multiply_by value. +0540 Sdc.tcl:1259 missing -pll_output argument. +0541 Sdc.tcl:1262 missing -pll_feedback argument. +0542 Sdc.tcl:1268 PLL output and feedback pins must be on the same instance. +0543 Sdc.tcl:1271 source pin must be on the same instance as the PLL output pin. +0544 Sdc.tcl:1274 PLL output must be one of the clock pins. +0545 Sdc.tcl:1312 group_path command failed. +0546 Sdc.tcl:1319 positional arguments not supported. +0547 Sdc.tcl:1323 -from, -through or -to required. +0548 Sdc.tcl:1329 -name and -default are mutually exclusive. +0549 Sdc.tcl:1331 -name or -default option is required. +0550 Sdc.tcl:1372 cannot specify both -high and -low. +0551 Sdc.tcl:1380 missing -setup or -hold argument. +0552 Sdc.tcl:1394 -high and -low only permitted for pins and instances. +0553 Sdc.tcl:1401 -high and -low only permitted for pins and instances. +0554 Sdc.tcl:1444 one of -logically_exclusive, -physically_exclusive or -asynchronous is required. +0555 Sdc.tcl:1447 the keywords -logically_exclusive, -physically_exclusive and -asynchronous are mutually exclusive. +0556 Sdc.tcl:1515 -source '[get_full_name $pin]' is not a clock pin. +0557 Sdc.tcl:1522 -early/-late is only allowed with -source. +0558 Sdc.tcl:1551 set_sense -type clock|data +0559 Sdc.tcl:1620 transition time can not be specified for virtual clocks. +0560 Sdc.tcl:1641 missing uncertainty value. +0561 Sdc.tcl:1683 -from/-to must be used together. +0562 Sdc.tcl:1703 -rise, -fall options not allowed for single clock uncertainty. +0563 Sdc.tcl:1744 missing -from, -rise_from or -fall_from argument. +0564 Sdc.tcl:1756 missing -to, -rise_to or -fall_to argument. +0565 Sdc.tcl:1828 -from/-to hierarchical instance not supported. +0566 Sdc.tcl:1860 pin '[get_full_name $inst]${hierarchy_separator}${port_name}' not found. +0567 Sdc.tcl:1901 pin '[get_name $cell]${hierarchy_separator}${port_name}' not found. +0568 Sdc.tcl:2086 missing delay argument. +0569 Sdc.tcl:2217 missing path multiplier argument. +0570 Sdc.tcl:2229 cannot use -start with -end. +0571 Sdc.tcl:2297 value must be 0, zero, 1, one, rise, rising, fall, or falling. +0572 Sdc.tcl:2355 cell '$lib_name:$cell_name' not found. +0573 Sdc.tcl:2361 '$cell_name' not found. +0574 Sdc.tcl:2365 missing -lib_cell argument. +0575 Sdc.tcl:2373 port '$to_port_name' not found. +0576 Sdc.tcl:2385 -pin argument required for cells with multiple outputs. +0577 Sdc.tcl:2400 port '$from_port_name' not found. +0578 Sdc.tcl:2607 port '[get_name $port]' is not an input. +0579 Sdc.tcl:2969 operating condition '$op_cond_name' not found. +0580 Sdc.tcl:2987 operating condition '$op_cond_name' not found. +0581 Sdc.tcl:3001 -analysis_type must be single, bc_wc or on_chip_variation. +0582 Sdc.tcl:3026 mode must be top, enclosed or segmented. +0583 Sdc.tcl:3041 no wire load model specified. +0584 Sdc.tcl:3102 wire load selection group '$selection_name' not found. +0585 Sdc.tcl:3233 no default operating conditions found. 0586 NetworkEdit.tcl:50 unsupported object type $object_type. 0587 NetworkEdit.tcl:119 unsupported object type $object_type. 0588 NetworkEdit.tcl:135 unsupported object type $object_type. @@ -317,18 +320,25 @@ 0595 DelayNormal2.cc:378 unknown early/late value. 0596 Sim.cc:205 unknown function operator 0597 EstimateParasitics.cc:188 load pin not leaf or top level -0600 Sdc.tcl:1941 '$args' ignored. -0601 Sdc.tcl:2440 set_fanout_load not supported. -0602 Sdc.tcl:2900 no valid objects specified for $key. +0600 Sdc.tcl:1942 '$args' ignored. +0601 Sdc.tcl:2441 set_fanout_load not supported. +0602 Sdc.tcl:2901 no valid objects specified for $key. 0603 NetworkEdit.tcl:172 disconnect_pins is deprecated. Use disconnect_pin. -0604 Sdc.tcl:270 unknown $unit prefix '$prefix'. -0605 Sdc.tcl:3062 wire load model '$model_name' not found. +0604 Sdc.tcl:271 unknown $unit prefix '$prefix'. +0605 Sdc.tcl:3063 wire load model '$model_name' not found. 0606 Sta.tcl:1136 get_property unsupported object type $object_type. -0607 StaTcl.i:4394 unknown report path field %s -0608 StaTcl.i:4406 unknown report path field %s +0607 StaTcl.i:4408 unknown report path field %s +0608 StaTcl.i:4420 unknown report path field %s 0609 Search.tcl:427 -all_violators is deprecated. Use -violators 0610 Search.tcl:507 -max_transition deprecated. Use -max_slew. 0611 Search.tcl:512 -min_transition deprecated. Use -min_slew. 0612 Sdf.tcl:41 -cond_use must be min, max or min_max. 0616 Search.tcl:1024 specify one of -setup and -hold. 0617 Sdf.tcl:50 -analysis_type is deprecated. Use set_operating_conditions -analysis_type. +0618 DmpCeff.cc:1579 parasitic Pi model has NaNs. +0619 PathEnum.cc:481 path diversion missing edge. +0620 PathVertex.cc:237 missing arrivals. +0621 PathVertex.cc:251 missing arrivals. +0622 PathVertex.cc:280 missing requireds. +0623 PathVertexRep.cc:153 missing arrivals. +0624 PathVertexRep.cc:150 missing arrivals diff --git a/network/ConcreteNetwork.cc b/network/ConcreteNetwork.cc index 1b1de998..2a399f42 100644 --- a/network/ConcreteNetwork.cc +++ b/network/ConcreteNetwork.cc @@ -1189,8 +1189,10 @@ ConcreteNetwork::replaceCell(Instance *inst, if (cpin) { ConcretePort *pin_cport = reinterpret_cast(cpin->port()); ConcretePort *cport = ccell->findPort(pin_cport->name()); - rpins[cport->pinIndex()] = cpin; - cpin->port_ = cport; + if (cport) { + rpins[cport->pinIndex()] = cpin; + cpin->port_ = cport; + } } } delete [] pins; @@ -1438,7 +1440,9 @@ void ConcreteNetwork::addConstantNet(Net *net, LogicValue value) { - constant_nets_[int(value)].insert(net); + if (value == LogicValue::zero + || value == LogicValue::one) + constant_nets_[int(value)].insert(net); } ConstantPinIterator * diff --git a/parasitics/ConcreteParasitics.cc b/parasitics/ConcreteParasitics.cc index 123f5118..9556ab9d 100644 --- a/parasitics/ConcreteParasitics.cc +++ b/parasitics/ConcreteParasitics.cc @@ -1197,7 +1197,7 @@ ConcreteParasitics::findPiPoleResidue(const Pin *drvr_pin, ap_rf_index = parasiticAnalysisPtIndex(ap, RiseFall::rise()); parasitic = parasitics[ap_rf_index]; } - if (parasitic->isPiPoleResidue()) + if (parasitic && parasitic->isPiPoleResidue()) return parasitic; } } diff --git a/parasitics/SpefReader.cc b/parasitics/SpefReader.cc index 87d231c4..b6eb8aeb 100644 --- a/parasitics/SpefReader.cc +++ b/parasitics/SpefReader.cc @@ -314,7 +314,7 @@ SpefReader::nameMapLookup(char *name) return mapped_name; else { warn(169, "no name map entry for %d.", index); - return 0; + return nullptr; } } else @@ -351,17 +351,19 @@ SpefReader::findPin(char *name) if (delim) { *delim = '\0'; name = nameMapLookup(name); - Instance *inst = findInstanceRelative(name); - // Replace delimiter for error messages. - *delim = delimiter_; - const char *port_name = delim + 1; - if (inst) { - pin = network_->findPin(inst, port_name); - if (pin == nullptr) - warn(171, "pin %s not found.", name); + if (name) { + Instance *inst = findInstanceRelative(name); + // Replace delimiter for error messages. + *delim = delimiter_; + const char *port_name = delim + 1; + if (inst) { + pin = network_->findPin(inst, port_name); + if (pin == nullptr) + warn(171, "pin %s not found.", name); + } + else + warn(172, "instance %s not found.", name); } - else - warn(172, "instance %s not found.", name); } else { pin = findPortPinRelative(name); diff --git a/sdc/CycleAccting.cc b/sdc/CycleAccting.cc index 18bc64ca..d3451a17 100644 --- a/sdc/CycleAccting.cc +++ b/sdc/CycleAccting.cc @@ -142,10 +142,9 @@ CycleAccting::findDelays(StaState *sta) } bool tgt_past_src = false; bool src_past_tgt = false; - int tgt_cycle, src_cycle; - for (tgt_cycle = firstCycle(tgt_); - tgt_cycle <= tgt_max_cycle; - tgt_cycle++) { + int tgt_cycle = firstCycle(tgt_); + int src_cycle = 0; + while (tgt_cycle <= tgt_max_cycle) { double tgt_cycle_start = tgt_cycle * tgt_period; double tgt_time = tgt_cycle_start + tgt_->time(); double tgt_opp_time = tgt_cycle_start + tgt_opp_time1; @@ -266,6 +265,7 @@ CycleAccting::findDelays(StaState *sta) } } } + tgt_cycle++; } max_cycles_exceeded_ = true; debugPrint(debug, "cycle_acct", 1, diff --git a/sdc/Sdc.cc b/sdc/Sdc.cc index 2223c110..ba1eed9f 100644 --- a/sdc/Sdc.cc +++ b/sdc/Sdc.cc @@ -284,14 +284,14 @@ Sdc::deleteConstraints() delete checks; } - for (auto input_delay : input_delays_) + for (InputDelay *input_delay : input_delays_) delete input_delay; input_delay_pin_map_.deleteContents(); input_delay_leaf_pin_map_.deleteContents(); input_delay_ref_pin_map_.deleteContents(); input_delay_internal_pin_map_.deleteContents(); - for (auto output_delay : output_delays_) + for (OutputDelay *output_delay : output_delays_) delete output_delay; output_delay_pin_map_.deleteContents(); output_delay_ref_pin_map_.deleteContents(); @@ -2071,7 +2071,7 @@ Sdc::removeClockGroupsLogicallyExclusive(const char *name) { if (name) { ClockGroups *groups = clk_groups_name_map_.findKey(name); - if (groups->logicallyExclusive()) + if (groups && groups->logicallyExclusive()) removeClockGroups(groups); } else { @@ -2089,7 +2089,7 @@ Sdc::removeClockGroupsPhysicallyExclusive(const char *name) { if (name) { ClockGroups *groups = clk_groups_name_map_.findKey(name); - if (groups->physicallyExclusive()) + if (groups && groups->physicallyExclusive()) removeClockGroups(groups); } else { @@ -2107,7 +2107,7 @@ Sdc::removeClockGroupsAsynchronous(const char *name) { if (name) { ClockGroups *groups = clk_groups_name_map_.findKey(name); - if (groups->asynchronous()) + if (groups && groups->asynchronous()) removeClockGroups(groups); } else { diff --git a/sdf/SdfReader.cc b/sdf/SdfReader.cc index 43a3da14..8c740263 100644 --- a/sdf/SdfReader.cc +++ b/sdf/SdfReader.cc @@ -363,54 +363,56 @@ SdfReader::iopath(SdfPortSpec *from_edge, // instance may not have the pin. if (from_pin && to_pin) { Vertex *to_vertex = graph_->pinDrvrVertex(to_pin); - size_t triple_count = triples->size(); - bool matched = false; - // Fanin < fanout, so search for driver from load. - // Search for multiple matching edges because of - // tristate enable/disable. - VertexInEdgeIterator edge_iter(to_vertex, graph_); - while (edge_iter.hasNext()) { - Edge *edge = edge_iter.next(); - TimingArcSet *arc_set = edge->timingArcSet(); - const char *lib_cond = arc_set->sdfCond(); - const TimingRole *edge_role = arc_set->role(); - bool cond_use_flag = cond_use_ && cond && lib_cond == nullptr - && !(!is_incremental_only_ && in_incremental_); - if (edge->from(graph_)->pin() == from_pin - && edge_role->sdfRole() == TimingRole::sdfIopath() - && (cond_use_flag - || (!condelse && condMatch(cond, lib_cond)) - // condelse matches the default (unconditional) arc. - || (condelse && lib_cond == nullptr))) { - matched = true; - TimingArcSetArcIterator arc_iter(arc_set); - while (arc_iter.hasNext()) { - TimingArc *arc = arc_iter.next(); - if ((from_edge->transition() == Transition::riseFall()) - || (arc->fromTrans() == from_edge->transition())) { - size_t triple_index = arc->toTrans()->sdfTripleIndex(); - SdfTriple *triple = nullptr; - if (triple_index < triple_count) - triple = (*triples)[triple_index]; - if (triple_count == 1) - triple = (*triples)[0]; - // Rules for matching when triple is missing not implemented. - // See SDF pg 3-17. - if (triple) { - if (cond_use_flag) - setEdgeArcDelaysCondUse(edge, arc, triple); - else - setEdgeArcDelays(edge, arc, triple); - } - } - } - } - } - if (!matched) - sdfWarn(191, "cell %s IOPATH %s -> %s not found.", - network_->cellName(instance_), - from_port_name, - to_port_name); + if (to_vertex) { + size_t triple_count = triples->size(); + bool matched = false; + // Fanin < fanout, so search for driver from load. + // Search for multiple matching edges because of + // tristate enable/disable. + VertexInEdgeIterator edge_iter(to_vertex, graph_); + while (edge_iter.hasNext()) { + Edge *edge = edge_iter.next(); + TimingArcSet *arc_set = edge->timingArcSet(); + const char *lib_cond = arc_set->sdfCond(); + const TimingRole *edge_role = arc_set->role(); + bool cond_use_flag = cond_use_ && cond && lib_cond == nullptr + && !(!is_incremental_only_ && in_incremental_); + if (edge->from(graph_)->pin() == from_pin + && edge_role->sdfRole() == TimingRole::sdfIopath() + && (cond_use_flag + || (!condelse && condMatch(cond, lib_cond)) + // condelse matches the default (unconditional) arc. + || (condelse && lib_cond == nullptr))) { + matched = true; + TimingArcSetArcIterator arc_iter(arc_set); + while (arc_iter.hasNext()) { + TimingArc *arc = arc_iter.next(); + if ((from_edge->transition() == Transition::riseFall()) + || (arc->fromTrans() == from_edge->transition())) { + size_t triple_index = arc->toTrans()->sdfTripleIndex(); + SdfTriple *triple = nullptr; + if (triple_index < triple_count) + triple = (*triples)[triple_index]; + if (triple_count == 1) + triple = (*triples)[0]; + // Rules for matching when triple is missing not implemented. + // See SDF pg 3-17. + if (triple) { + if (cond_use_flag) + setEdgeArcDelaysCondUse(edge, arc, triple); + else + setEdgeArcDelays(edge, arc, triple); + } + } + } + } + } + if (!matched) + sdfWarn(191, "cell %s IOPATH %s -> %s not found.", + network_->cellName(instance_), + from_port_name, + to_port_name); + } } } } @@ -699,11 +701,13 @@ SdfReader::setDevicePinDelays(Pin *to_pin, SdfTripleSeq *triples) { Vertex *vertex = graph_->pinDrvrVertex(to_pin); - VertexInEdgeIterator edge_iter(vertex, graph_); - while (edge_iter.hasNext()) { - Edge *edge = edge_iter.next(); - if (edge->role()->sdfRole() == TimingRole::sdfIopath()) - setEdgeDelays(edge, triples, "DEVICE"); + if (vertex) { + VertexInEdgeIterator edge_iter(vertex, graph_); + while (edge_iter.hasNext()) { + Edge *edge = edge_iter.next(); + if (edge->role()->sdfRole() == TimingRole::sdfIopath()) + setEdgeDelays(edge, triples, "DEVICE"); + } } } diff --git a/sdf/SdfWriter.cc b/sdf/SdfWriter.cc index 7d4c93b2..61d2a96b 100644 --- a/sdf/SdfWriter.cc +++ b/sdf/SdfWriter.cc @@ -306,16 +306,18 @@ void SdfWriter::writeInterconnectFromPin(Pin *drvr_pin) { Vertex *drvr_vertex = graph_->pinDrvrVertex(drvr_pin); - VertexOutEdgeIterator edge_iter(drvr_vertex, graph_); - while (edge_iter.hasNext()) { - Edge *edge = edge_iter.next(); - if (edge->isWire()) { - Pin *load_pin = edge->to(graph_)->pin(); - gzprintf(stream_, " (INTERCONNECT %s %s ", - sdfPathName(drvr_pin), - sdfPathName(load_pin)); - writeArcDelays(edge); - gzprintf(stream_, ")\n"); + if (drvr_vertex) { + VertexOutEdgeIterator edge_iter(drvr_vertex, graph_); + while (edge_iter.hasNext()) { + Edge *edge = edge_iter.next(); + if (edge->isWire()) { + Pin *load_pin = edge->to(graph_)->pin(); + gzprintf(stream_, " (INTERCONNECT %s %s ", + sdfPathName(drvr_pin), + sdfPathName(load_pin)); + writeArcDelays(edge); + gzprintf(stream_, ")\n"); + } } } } diff --git a/search/CheckTiming.cc b/search/CheckTiming.cc index 01497ab6..615c4429 100644 --- a/search/CheckTiming.cc +++ b/search/CheckTiming.cc @@ -204,13 +204,15 @@ CheckTiming::checkLoops() error->push_back(pin_name); last_edge = edge; } - error->push_back(stringCopy("| loop cut point")); - const Pin *pin = last_edge->to(graph_)->pin(); - const char *pin_name = stringCopy(sdc_network_->pathName(pin)); - error->push_back(pin_name); + if (last_edge) { + error->push_back(stringCopy("| loop cut point")); + const Pin *pin = last_edge->to(graph_)->pin(); + const char *pin_name = stringCopy(sdc_network_->pathName(pin)); + error->push_back(pin_name); - // Separator between loops. - error->push_back(stringCopy("--------------------------------")); + // Separator between loops. + error->push_back(stringCopy("--------------------------------")); + } } } errors_.push_back(error); diff --git a/search/Crpr.cc b/search/Crpr.cc index 20d22d3c..dc55d15f 100644 --- a/search/Crpr.cc +++ b/search/Crpr.cc @@ -161,7 +161,8 @@ CheckCrpr::checkCrpr1(const Path *src_path, src_clk_path1.isNull() ? nullptr : &src_clk_path1; const MinMax *src_clk_min_max = src_clk_path ? src_clk_path->minMax(this) : src_path->minMax(this); - if (crprPossible(src_clk, tgt_clk) + if (src_clk && tgt_clk + && crprPossible(src_clk, tgt_clk) && src_clk_info->isPropagated() && tgt_clk_info->isPropagated() // Note that crpr clk min/max is NOT the same as the path min max. @@ -374,7 +375,8 @@ CheckCrpr::outputDelayCrpr1(const Path *src_path, ClkInfo *src_clk_info = src_path->tag(this)->clkInfo(); Clock *tgt_clk = tgt_clk_edge->clock(); Clock *src_clk = src_path->clock(this); - if (src_clk_info->isPropagated() + if (src_clk && tgt_clk + && src_clk_info->isPropagated() && tgt_clk->isGenerated() && tgt_clk->isPropagated() && crprPossible(src_clk, tgt_clk)) { diff --git a/search/Genclks.cc b/search/Genclks.cc index df80365f..b925dd7f 100644 --- a/search/Genclks.cc +++ b/search/Genclks.cc @@ -135,7 +135,10 @@ VertexSet * Genclks::fanins(const Clock *clk) { GenclkInfo *genclk_info = genclkInfo(clk); - return genclk_info->fanins(); + if (genclk_info) + return genclk_info->fanins(); + else + return nullptr; } Vertex * @@ -616,14 +619,18 @@ EdgeSet * Genclks::latchFdbkEdges(const Clock *clk) { GenclkInfo *genclk_info = genclkInfo(clk); - return genclk_info->fdbkEdges(); + if (genclk_info) + return genclk_info->fdbkEdges(); + else + return nullptr; } void Genclks::findLatchFdbkEdges(const Clock *clk) { GenclkInfo *genclk_info = genclkInfo(clk); - if (!genclk_info->foundLatchFdbkEdges()) + if (genclk_info + && !genclk_info->foundLatchFdbkEdges()) findLatchFdbkEdges(clk, genclk_info); } @@ -716,24 +723,26 @@ Genclks::seedSrcPins(Clock *gclk, Clock *master_clk = gclk->masterClk(); for (Pin *master_pin : master_clk->leafPins()) { Vertex *vertex = graph_->pinDrvrVertex(master_pin); - debugPrint(debug_, "genclk", 2, " seed src pin %s", - network_->pathName(master_pin)); - TagGroupBldr tag_bldr(true, this); - tag_bldr.init(vertex); - copyGenClkSrcPaths(vertex, &tag_bldr); - for (auto path_ap : corners_->pathAnalysisPts()) { - const MinMax *min_max = path_ap->pathMinMax(); - const EarlyLate *early_late = min_max; - for (auto tr : RiseFall::range()) { - Tag *tag = makeTag(gclk, master_clk, master_pin, tr, src_filter, - path_ap); - Arrival insert = search_->clockInsertion(master_clk, master_pin, tr, - min_max, early_late, path_ap); - tag_bldr.setArrival(tag, insert, nullptr); + if (vertex) { + debugPrint(debug_, "genclk", 2, " seed src pin %s", + network_->pathName(master_pin)); + TagGroupBldr tag_bldr(true, this); + tag_bldr.init(vertex); + copyGenClkSrcPaths(vertex, &tag_bldr); + for (auto path_ap : corners_->pathAnalysisPts()) { + const MinMax *min_max = path_ap->pathMinMax(); + const EarlyLate *early_late = min_max; + for (auto tr : RiseFall::range()) { + Tag *tag = makeTag(gclk, master_clk, master_pin, tr, src_filter, + path_ap); + Arrival insert = search_->clockInsertion(master_clk, master_pin, tr, + min_max, early_late, path_ap); + tag_bldr.setArrival(tag, insert, nullptr); + } } + search_->setVertexArrivals(vertex, &tag_bldr); + insert_iter.enqueueAdjacentVertices(vertex); } - search_->setVertexArrivals(vertex, &tag_bldr); - insert_iter.enqueueAdjacentVertices(vertex); } } @@ -903,17 +912,19 @@ Genclks::copyGenClkSrcPaths(Vertex *vertex, if (arrivals) { PathVertexRep *prev_paths = graph_->prevPaths(vertex); TagGroup *tag_group = search_->tagGroup(vertex); - ArrivalMap::Iterator arrival_iter(tag_group->arrivalMap()); - while (arrival_iter.hasNext()) { - Tag *tag; - int arrival_index; - arrival_iter.next(tag, arrival_index); - if (tag->isGenClkSrcPath()) { - Arrival arrival = arrivals[arrival_index]; - PathVertexRep *prev_path = prev_paths - ? &prev_paths[arrival_index] - : nullptr; - tag_bldr->setArrival(tag, arrival, prev_path); + if (tag_group) { + ArrivalMap::Iterator arrival_iter(tag_group->arrivalMap()); + while (arrival_iter.hasNext()) { + Tag *tag; + int arrival_index; + arrival_iter.next(tag, arrival_index); + if (tag->isGenClkSrcPath()) { + Arrival arrival = arrivals[arrival_index]; + PathVertexRep *prev_path = prev_paths + ? &prev_paths[arrival_index] + : nullptr; + tag_bldr->setArrival(tag, arrival, prev_path); + } } } } @@ -1100,13 +1111,15 @@ Genclks::findPllDelays(Clock *gclk) gclk->name()); FilterPath *pll_filter = makePllFilter(gclk); GenclkInfo *genclk_info = genclkInfo(gclk); - genclk_info->setPllFilter(pll_filter); - ClkTreeSearchPred srch_pred(this); - BfsFwdIterator pll_iter(BfsIndex::other, &srch_pred, this); - seedPllPin(gclk, pll_filter, pll_iter); - // Propagate arrivals to pll feedback pin level. - findPllArrivals(gclk, pll_iter); - sdc_->unrecordException(pll_filter); + if (genclk_info) { + genclk_info->setPllFilter(pll_filter); + ClkTreeSearchPred srch_pred(this); + BfsFwdIterator pll_iter(BfsIndex::other, &srch_pred, this); + seedPllPin(gclk, pll_filter, pll_iter); + // Propagate arrivals to pll feedback pin level. + findPllArrivals(gclk, pll_iter); + sdc_->unrecordException(pll_filter); + } } FilterPath * @@ -1131,19 +1144,21 @@ Genclks::seedPllPin(const Clock *gclk, { Pin *pll_out_pin = gclk->pllOut(); Vertex *vertex = graph_->pinDrvrVertex(pll_out_pin); - debugPrint(debug_, "genclk", 2, " seed pllout pin %s", - network_->pathName(pll_out_pin)); - TagGroupBldr tag_bldr(true, this); - tag_bldr.init(vertex); - copyGenClkSrcPaths(vertex, &tag_bldr); - for (auto path_ap : corners_->pathAnalysisPts()) { - for (auto tr : RiseFall::range()) { - Tag *tag = makeTag(gclk, gclk, pll_out_pin, tr, pll_filter, path_ap); - tag_bldr.setArrival(tag, 0.0, nullptr); + if (vertex) { + debugPrint(debug_, "genclk", 2, " seed pllout pin %s", + network_->pathName(pll_out_pin)); + TagGroupBldr tag_bldr(true, this); + tag_bldr.init(vertex); + copyGenClkSrcPaths(vertex, &tag_bldr); + for (auto path_ap : corners_->pathAnalysisPts()) { + for (auto tr : RiseFall::range()) { + Tag *tag = makeTag(gclk, gclk, pll_out_pin, tr, pll_filter, path_ap); + tag_bldr.setArrival(tag, 0.0, nullptr); + } } + search_->setVertexArrivals(vertex, &tag_bldr); + pll_iter.enqueueAdjacentVertices(vertex); } - search_->setVertexArrivals(vertex, &tag_bldr); - pll_iter.enqueueAdjacentVertices(vertex); } class PllEvalPred : public EvalPred diff --git a/search/Latches.cc b/search/Latches.cc index cebae405..0dfd5c2c 100644 --- a/search/Latches.cc +++ b/search/Latches.cc @@ -155,42 +155,52 @@ Latches::latchBorrowInfo(const Path *data_path, Delay &max_borrow, bool &borrow_limit_exists) { - const ClockEdge *data_clk_edge = data_path->clkEdge(this); - const ClockEdge *enable_clk_edge = enable_path->clkEdge(this); - const ClockEdge *disable_clk_edge = disable_path->clkEdge(this); - bool is_pulse_clk = enable_path->clkInfo(this)->isPulseClk(); - nom_pulse_width = is_pulse_clk ? 0.0F : enable_clk_edge->pulseWidth(); - open_uncertainty = PathEnd::checkClkUncertainty(data_clk_edge, enable_clk_edge, - enable_path, - TimingRole::latchSetup(), this); - if (ignore_clk_latency) { + if (data_path && enable_path && disable_path) { + const ClockEdge *data_clk_edge = data_path->clkEdge(this); + const ClockEdge *enable_clk_edge = enable_path->clkEdge(this); + const ClockEdge *disable_clk_edge = disable_path->clkEdge(this); + bool is_pulse_clk = enable_path->clkInfo(this)->isPulseClk(); + nom_pulse_width = is_pulse_clk ? 0.0F : enable_clk_edge->pulseWidth(); + open_uncertainty = PathEnd::checkClkUncertainty(data_clk_edge, enable_clk_edge, + enable_path, + TimingRole::latchSetup(), this); + if (ignore_clk_latency) { open_latency = 0.0; latency_diff = 0.0; open_crpr = 0.0; crpr_diff = 0.0; + } + else { + CheckCrpr *check_crpr = search_->checkCrpr(); + open_crpr = check_crpr->checkCrpr(data_path, enable_path); + Crpr close_crpr = check_crpr->checkCrpr(data_path, disable_path); + crpr_diff = open_crpr - close_crpr; + open_latency = PathEnd::checkTgtClkDelay(enable_path, enable_clk_edge, + TimingRole::setup(), this); + Arrival close_latency = PathEnd::checkTgtClkDelay(disable_path, + disable_clk_edge, + TimingRole::latchSetup(), + this); + latency_diff = open_latency - close_latency; + } + float borrow_limit; + sdc_->latchBorrowLimit(data_path->pin(this), disable_path->pin(this), + enable_clk_edge->clock(), + borrow_limit, borrow_limit_exists); + if (borrow_limit_exists) + max_borrow = borrow_limit; + else + max_borrow = nom_pulse_width - delayAsFloat(latency_diff) + - delayAsFloat(crpr_diff) - delayAsFloat(margin); } else { - CheckCrpr *check_crpr = search_->checkCrpr(); - open_crpr = check_crpr->checkCrpr(data_path, enable_path); - Crpr close_crpr = check_crpr->checkCrpr(data_path, disable_path); - crpr_diff = open_crpr - close_crpr; - open_latency = PathEnd::checkTgtClkDelay(enable_path, enable_clk_edge, - TimingRole::setup(), this); - Arrival close_latency = PathEnd::checkTgtClkDelay(disable_path, - disable_clk_edge, - TimingRole::latchSetup(), - this); - latency_diff = open_latency - close_latency; + nom_pulse_width = 0.0; + open_uncertainty = 0.0; + open_latency = 0.0; + latency_diff = 0.0; + open_crpr = 0.0; + crpr_diff = 0.0; } - float borrow_limit; - sdc_->latchBorrowLimit(data_path->pin(this), disable_path->pin(this), - enable_clk_edge->clock(), - borrow_limit, borrow_limit_exists); - if (borrow_limit_exists) - max_borrow = borrow_limit; - else - max_borrow = nom_pulse_width - delayAsFloat(latency_diff) - - delayAsFloat(crpr_diff) - delayAsFloat(margin); } void diff --git a/search/PathEnd.cc b/search/PathEnd.cc index 70f19b8c..e9366492 100644 --- a/search/PathEnd.cc +++ b/search/PathEnd.cc @@ -1243,8 +1243,9 @@ PathEndLatchCheck::targetClkWidth(const StaState *sta) const return disable_arrival - enable_arrival; else { if (delayGreater(enable_arrival, disable_arrival, sta)) { - float period = enable_clk_info->clock()->period(); - disable_arrival += period; + Clock *disable_clk = enable_clk_info->clock(); + if (disable_clk) + disable_arrival += disable_clk->period(); } return disable_arrival - enable_arrival; } diff --git a/search/PathEnum.cc b/search/PathEnum.cc index a9ce14e2..68d9b1e4 100644 --- a/search/PathEnum.cc +++ b/search/PathEnum.cc @@ -470,11 +470,17 @@ PathEnum::divSlack(Path *before_div, { Arrival arc_arrival = before_div->arrival(this); Edge *div_edge = divEdge(before_div, div_arc); - ArcDelay div_delay = search_->deratedDelay(div_edge->from(graph_), - div_arc, div_edge, - false, path_ap); - Arrival div_arrival = search_->clkPathArrival(after_div) + div_delay; - return div_arrival - arc_arrival; + if (div_edge) { + ArcDelay div_delay = search_->deratedDelay(div_edge->from(graph_), + div_arc, div_edge, + false, path_ap); + Arrival div_arrival = search_->clkPathArrival(after_div) + div_delay; + return div_arrival - arc_arrival; + } + else { + report()->error(619, "path diversion missing edge."); + return 0.0; + } } Edge * @@ -586,28 +592,30 @@ PathEnum::updatePathHeadDelays(PathEnumedSeq &paths, PathEnumed *path = paths[i]; TimingArc *arc = path->prevArc(this); Edge *edge = path->prevEdge(arc, this); - PathAnalysisPt *path_ap = path->pathAnalysisPt(this); - ArcDelay arc_delay = search_->deratedDelay(edge->from(graph_), - arc, edge, false, path_ap); - Arrival arrival = prev_arrival + arc_delay; - debugPrint(debug_, "path_enum", 3, "update arrival %s %s -> %s", - path->name(this), - delayAsString(path->arrival(this), this), - delayAsString(arrival, this)); - path->setArrival(arrival, this); - prev_arrival = arrival; - if (sdc_->crprActive()) { - // When crpr is enabled the diverion may be from another crpr clk pin, - // so update the tags to use the corresponding ClkInfo. - Tag *tag = path->tag(this); - Tag *updated_tag = search_->findTag(path->transition(this), - path_ap, - clk_info, - tag->isClock(), - tag->inputDelay(), - tag->isSegmentStart(), - tag->states(), false); - path->setTag(updated_tag); + if (edge) { + PathAnalysisPt *path_ap = path->pathAnalysisPt(this); + ArcDelay arc_delay = search_->deratedDelay(edge->from(graph_), + arc, edge, false, path_ap); + Arrival arrival = prev_arrival + arc_delay; + debugPrint(debug_, "path_enum", 3, "update arrival %s %s -> %s", + path->name(this), + delayAsString(path->arrival(this), this), + delayAsString(arrival, this)); + path->setArrival(arrival, this); + prev_arrival = arrival; + if (sdc_->crprActive()) { + // When crpr is enabled the diverion may be from another crpr clk pin, + // so update the tags to use the corresponding ClkInfo. + Tag *tag = path->tag(this); + Tag *updated_tag = search_->findTag(path->transition(this), + path_ap, + clk_info, + tag->isClock(), + tag->inputDelay(), + tag->isSegmentStart(), + tag->states(), false); + path->setTag(updated_tag); + } } } } diff --git a/search/PathExpanded.cc b/search/PathExpanded.cc index 985f21e8..76b8b600 100644 --- a/search/PathExpanded.cc +++ b/search/PathExpanded.cc @@ -73,7 +73,7 @@ PathExpanded::expand(const Path *path, } else if (prev_role == TimingRole::latchDtoQ()) { Edge *prev_edge = p.prevEdge(prev_arc, sta_); - if (latches->isLatchDtoQ(prev_edge)) { + if (prev_edge && latches->isLatchDtoQ(prev_edge)) { start_index_ = i; found_start = true; @@ -195,21 +195,24 @@ PathExpanded::clkPath(PathRef &clk_path) const Latches *latches = sta_->latches(); PathRef *start = startPath(); TimingArc *prev_arc = startPrevArc(); - if (prev_arc) { + if (start && prev_arc) { TimingRole *role = prev_arc->role(); if (role == TimingRole::latchDtoQ()) { Edge *prev_edge = start->prevEdge(prev_arc, sta_); - if (latches->isLatchDtoQ(prev_edge)) { + if (prev_edge && latches->isLatchDtoQ(prev_edge)) { PathVertex enable_path; latches->latchEnablePath(start, prev_edge, enable_path); clk_path.init(enable_path); } } else if (role == TimingRole::regClkToQ() - || role == TimingRole::latchEnToQ()) - clk_path.init(startPrevPath()); + || role == TimingRole::latchEnToQ()) { + PathRef *start_prev = startPrevPath(); + if (start_prev) + clk_path.init(start_prev); + } } - else if (start->isClock(sta_)) + else if (start && start->isClock(sta_)) clk_path.init(start); } @@ -224,11 +227,13 @@ PathExpanded::latchPaths(// Return values. d_q_edge = nullptr; PathRef *start = startPath(); TimingArc *prev_arc = startPrevArc(); - if (prev_arc + if (start + && prev_arc && prev_arc->role() == TimingRole::latchDtoQ()) { Edge *prev_edge = start->prevEdge(prev_arc, sta_); // This breaks latch loop paths. - if (sta_->latches()->isLatchDtoQ(prev_edge)) { + if (prev_edge + && sta_->latches()->isLatchDtoQ(prev_edge)) { d_path = startPrevPath(); q_path = start; d_q_edge = prev_edge; diff --git a/search/PathVertex.cc b/search/PathVertex.cc index 977849ee..8a933c16 100644 --- a/search/PathVertex.cc +++ b/search/PathVertex.cc @@ -231,7 +231,12 @@ Arrival PathVertex::arrival(const StaState *sta) const { Arrival *arrivals = sta->graph()->arrivals(vertex_); - return arrivals[arrival_index_]; + if (arrivals) + return arrivals[arrival_index_]; + else { + sta->report()->error(620, "missing arrivals."); + return 0.0; + } } void @@ -240,7 +245,10 @@ PathVertex::setArrival(Arrival arrival, { if (tag_) { Arrival *arrivals = sta->graph()->arrivals(vertex_); - arrivals[arrival_index_] = arrival; + if (arrivals) + arrivals[arrival_index_] = arrival; + else + sta->report()->error(621, "missing arrivals."); } } @@ -264,8 +272,12 @@ PathVertex::setRequired(const Required &required, if (requireds == nullptr) { const Search *search = sta->search(); TagGroup *tag_group = search->tagGroup(vertex_); - int arrival_count = tag_group->arrivalCount(); - requireds = graph->makeRequireds(vertex_, arrival_count); + if (tag_group) { + int arrival_count = tag_group->arrivalCount(); + requireds = graph->makeRequireds(vertex_, arrival_count); + } + else + sta->report()->error(622, "missing requireds."); } requireds[arrival_index_] = required; } diff --git a/search/PathVertexRep.cc b/search/PathVertexRep.cc index 5ae271bf..8bc572d1 100644 --- a/search/PathVertexRep.cc +++ b/search/PathVertexRep.cc @@ -137,13 +137,21 @@ PathVertexRep::arrival(const StaState *sta) const Tag *tag = search->tag(tag_index_); Vertex *vertex = graph->vertex(vertex_id_); TagGroup *tag_group = search->tagGroup(vertex); - int arrival_index; - bool arrival_exists; - tag_group->arrivalIndex(tag, arrival_index, arrival_exists); - if (!arrival_exists) - sta->report()->critical(254, "tag group missing tag"); - Arrival *arrivals = graph->arrivals(vertex); - return arrivals[arrival_index]; + if (tag_group) { + int arrival_index; + bool arrival_exists; + tag_group->arrivalIndex(tag, arrival_index, arrival_exists); + if (!arrival_exists) + sta->report()->critical(254, "tag group missing tag"); + Arrival *arrivals = graph->arrivals(vertex); + if (arrivals) + return arrivals[arrival_index]; + else + sta->report()->critical(624, "missing arrivals"); + } + else + sta->report()->error(623, "missing arrivals."); + return 0.0; } void diff --git a/search/Power.cc b/search/Power.cc index a88fbbb2..50174366 100644 --- a/search/Power.cc +++ b/search/Power.cc @@ -544,14 +544,14 @@ Power::seedRegOutputActivities(const Instance *inst, LibertyPort *port = network_->libertyPort(pin); if (port) { FuncExpr *func = port->function(); - if (func) { - Vertex *vertex = graph_->pinDrvrVertex(pin); - if (func->port() == seq->output() - || func->port() == seq->outputInv()) { - debugPrint(debug_, "power_activity", 3, "enqueue reg output %s", - vertex->name(network_)); - bfs.enqueue(vertex); - } + Vertex *vertex = graph_->pinDrvrVertex(pin); + if (vertex + && func + && (func->port() == seq->output() + || func->port() == seq->outputInv())) { + debugPrint(debug_, "power_activity", 3, "enqueue reg output %s", + vertex->name(network_)); + bfs.enqueue(vertex); } } } @@ -637,60 +637,64 @@ Power::findInputInternalPower(const Pin *pin, int lib_ap_index = corner->libertyIndex(MinMax::max()); LibertyCell *corner_cell = cell->cornerCell(lib_ap_index); const LibertyPort *corner_port = port->cornerPort(lib_ap_index); - InternalPowerSeq *internal_pwrs = corner_cell->internalPowers(corner_port); - if (!internal_pwrs->empty()) { - debugPrint(debug_, "power", 2, "internal input %s/%s (%s)", - network_->pathName(inst), - port->name(), - corner_cell->name()); - const DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(MinMax::max()); - const Pvt *pvt = dcalc_ap->operatingConditions(); - Vertex *vertex = graph_->pinLoadVertex(pin); - debugPrint(debug_, "power", 2, " cap = %s", - units_->capacitanceUnit()->asString(load_cap)); - debugPrint(debug_, "power", 2, " when act/ns duty energy power"); - float internal = 0.0; - for (InternalPower *pwr : *internal_pwrs) { - const char *related_pg_pin = pwr->relatedPgPin(); - float energy = 0.0; - int rf_count = 0; - for (RiseFall *rf : RiseFall::range()) { - float slew = getSlew(vertex, rf, corner); - if (!delayInf(slew)) { - float table_energy = pwr->power(rf, pvt, slew, load_cap); - energy += table_energy; - rf_count++; - } - } - if (rf_count) - energy /= rf_count; // average non-inf energies - float duty = 1.0; // fallback default - FuncExpr *when = pwr->when(); - if (when) { - LibertyPort *out_corner_port = findExprOutPort(when); - if (out_corner_port) { - const LibertyPort *out_port = findLinkPort(cell, out_corner_port); - FuncExpr *func = out_port->function(); - if (func && func->hasPort(port)) - duty = evalActivityDifference(func, inst, port).duty(); - else - duty = evalActivity(when, inst).duty(); - } - else - duty = evalActivity(when, inst).duty(); - } - float port_internal = energy * duty * activity.activity(); - debugPrint(debug_, "power", 2, " %3s %6s %.2f %.2f %9.2e %9.2e %s", + if (corner_cell && corner_port) { + InternalPowerSeq *internal_pwrs = corner_cell->internalPowers(corner_port); + if (!internal_pwrs->empty()) { + debugPrint(debug_, "power", 2, "internal input %s/%s (%s)", + network_->pathName(inst), port->name(), - when ? when->asString() : "", - activity.activity() * 1e-9, - duty, - energy, - port_internal, - related_pg_pin ? related_pg_pin : "no pg_pin"); - internal += port_internal; + corner_cell->name()); + const DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(MinMax::max()); + const Pvt *pvt = dcalc_ap->operatingConditions(); + Vertex *vertex = graph_->pinLoadVertex(pin); + debugPrint(debug_, "power", 2, " cap = %s", + units_->capacitanceUnit()->asString(load_cap)); + debugPrint(debug_, "power", 2, " when act/ns duty energy power"); + float internal = 0.0; + for (InternalPower *pwr : *internal_pwrs) { + const char *related_pg_pin = pwr->relatedPgPin(); + float energy = 0.0; + int rf_count = 0; + for (RiseFall *rf : RiseFall::range()) { + float slew = getSlew(vertex, rf, corner); + if (!delayInf(slew)) { + float table_energy = pwr->power(rf, pvt, slew, load_cap); + energy += table_energy; + rf_count++; + } + } + if (rf_count) + energy /= rf_count; // average non-inf energies + float duty = 1.0; // fallback default + FuncExpr *when = pwr->when(); + if (when) { + LibertyPort *out_corner_port = findExprOutPort(when); + if (out_corner_port) { + const LibertyPort *out_port = findLinkPort(cell, out_corner_port); + if (out_port) { + FuncExpr *func = out_port->function(); + if (func && func->hasPort(port)) + duty = evalActivityDifference(func, inst, port).duty(); + else + duty = evalActivity(when, inst).duty(); + } + } + else + duty = evalActivity(when, inst).duty(); + } + float port_internal = energy * duty * activity.activity(); + debugPrint(debug_, "power", 2, " %3s %6s %.2f %.2f %9.2e %9.2e %s", + port->name(), + when ? when->asString() : "", + activity.activity() * 1e-9, + duty, + energy, + port_internal, + related_pg_pin ? related_pg_pin : "no pg_pin"); + internal += port_internal; + } + result.internal() += internal; } - result.internal() += internal; } } @@ -714,7 +718,7 @@ Power::findExprOutPort(FuncExpr *expr) switch (expr->op()) { case FuncExpr::op_port: port = expr->port(); - if (port->direction()->isAnyOutput()) + if (port && port->direction()->isAnyOutput()) return expr->port(); return nullptr; case FuncExpr::op_not: @@ -830,7 +834,7 @@ Power::findOutputInternalPower(const Pin *to_pin, } float port_internal = weight * energy * to_activity.activity(); debugPrint(debug_, "power", 2, "%3s -> %-3s %6s %.2f %.2f %.2f %9.2e %9.2e %s", - from_corner_port->name(), + from_corner_port ? from_corner_port->name() : "-" , to_port->name(), when ? when->asString() : "", to_activity.activity() * 1e-9, diff --git a/search/Property.cc b/search/Property.cc index 4afd04a0..777363f1 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -933,12 +933,16 @@ getProperty(TimingArcSet *arc_set, { if (stringEqual(property, "name") || stringEqual(property, "full_name")) { - auto from = arc_set->from()->name(); - auto to = arc_set->to()->name(); - auto cell_name = arc_set->libertyCell()->name(); - string name; - stringPrint(name, "%s %s -> %s", cell_name, from, to); - return PropertyValue(name); + if (arc_set->isWire()) + return PropertyValue("wire"); + else { + auto from = arc_set->from()->name(); + auto to = arc_set->to()->name(); + auto cell_name = arc_set->libertyCell()->name(); + string name; + stringPrint(name, "%s %s -> %s", cell_name, from, to); + return PropertyValue(name); + } } else throw PropertyUnknown("timing arc", property); diff --git a/search/ReportPath.cc b/search/ReportPath.cc index 7b5834ff..31c47140 100644 --- a/search/ReportPath.cc +++ b/search/ReportPath.cc @@ -199,8 +199,10 @@ ReportPath::setReportFieldOrder(StringSeq *field_names) while (name_iter.hasNext()) { const char *field_name = name_iter.next(); ReportField *field = findField(field_name); - next_fields.push_back(field); - field->setEnabled(true); + if (field) { + next_fields.push_back(field); + field->setEnabled(true); + } } // Push remaining disabled fields on the end. ReportFieldSeq::Iterator field_iter2(fields_); @@ -373,7 +375,7 @@ ReportPath::reportEndpointHeader(PathEnd *end, if (prev_end) prev_group = search_->pathGroup(prev_end); PathGroup *group = search_->pathGroup(end); - if (group != prev_group) { + if (group && group != prev_group) { if (prev_group) reportBlankLine(); const char *setup_hold = (end->minMax(this) == MinMax::min()) @@ -1746,7 +1748,8 @@ ReportPath::reportGroup(const PathEnd *end) { string line; line = "Path Group: "; - line += search_->pathGroup(end)->name(); + PathGroup *group = search_->pathGroup(end); + line += group ? group->name() : "(none)"; report_->reportLineString(line); line = "Path Type: "; @@ -2196,43 +2199,45 @@ ReportPath::reportGenClkSrcPath1(Clock *clk, ClkInfo *src_clk_info = src_path.clkInfo(search_); ClockEdge *src_clk_edge = src_clk_info->clkEdge(); Clock *src_clk = src_clk_info->clock(); - bool skip_first_path = false; - const RiseFall *src_clk_rf = src_clk_edge->transition(); - const Pin *src_clk_pin = src_clk_info->clkSrc(); - if (src_clk->isGeneratedWithPropagatedMaster() - && src_clk_info->isPropagated()) { - skip_first_path = reportGenClkSrcPath1(src_clk, src_clk_pin, - src_clk_rf, early_late, path_ap, - gclk_time, time_offset, - clk_used_as_data); + if (src_clk) { + bool skip_first_path = false; + const RiseFall *src_clk_rf = src_clk_edge->transition(); + const Pin *src_clk_pin = src_clk_info->clkSrc(); + if (src_clk->isGeneratedWithPropagatedMaster() + && src_clk_info->isPropagated()) { + skip_first_path = reportGenClkSrcPath1(src_clk, src_clk_pin, + src_clk_rf, early_late, path_ap, + gclk_time, time_offset, + clk_used_as_data); + } + else { + const Arrival insertion = search_->clockInsertion(src_clk, src_clk_pin, + src_clk_rf, + path_ap->pathMinMax(), + early_late, path_ap); + reportClkSrcLatency(insertion, gclk_time, early_late); + } + PathExpanded src_expanded(&src_path, this); + if (clk->pllOut()) { + reportPath4(&src_path, src_expanded, skip_first_path, true, + clk_used_as_data, gclk_time); + PathAnalysisPt *pll_ap=path_ap->insertionAnalysisPt(min_max->opposite()); + Arrival pll_delay = search_->genclks()->pllDelay(clk, clk_rf, pll_ap); + size_t path_length = src_expanded.size(); + if (path_length < 2) + report_->critical(258, "generated clock pll source path too short."); + PathRef *path0 = src_expanded.path(path_length - 2); + Arrival time0 = path0->arrival(this) + gclk_time; + PathRef *path1 = src_expanded.path(path_length - 1); + reportPathLine(path1, -pll_delay, time0 - pll_delay, "pll_delay"); + } + else + reportPath4(&src_path, src_expanded, skip_first_path, false, + clk_used_as_data, gclk_time); + if (!clk->isPropagated()) + reportLine("clock network delay (ideal)", 0.0, + src_path.arrival(this), min_max); } - else { - const Arrival insertion = search_->clockInsertion(src_clk, src_clk_pin, - src_clk_rf, - path_ap->pathMinMax(), - early_late, path_ap); - reportClkSrcLatency(insertion, gclk_time, early_late); - } - PathExpanded src_expanded(&src_path, this); - if (clk->pllOut()) { - reportPath4(&src_path, src_expanded, skip_first_path, true, - clk_used_as_data, gclk_time); - PathAnalysisPt *pll_ap=path_ap->insertionAnalysisPt(min_max->opposite()); - Arrival pll_delay = search_->genclks()->pllDelay(clk, clk_rf, pll_ap); - size_t path_length = src_expanded.size(); - if (path_length < 2) - report_->critical(258, "generated clock pll source path too short."); - PathRef *path0 = src_expanded.path(path_length - 2); - Arrival time0 = path0->arrival(this) + gclk_time; - PathRef *path1 = src_expanded.path(path_length - 1); - reportPathLine(path1, -pll_delay, time0 - pll_delay, "pll_delay"); - } - else - reportPath4(&src_path, src_expanded, skip_first_path, false, - clk_used_as_data, gclk_time); - if (!clk->isPropagated()) - reportLine("clock network delay (ideal)", 0.0, - src_path.arrival(this), min_max); } else { if (clk->isPropagated()) @@ -2832,15 +2837,17 @@ ReportPath::pathInputDelayRefPath(const Path *path, Pin *ref_pin = input_delay->refPin(); RiseFall *ref_rf = input_delay->refTransition(); Vertex *ref_vertex = graph_->pinDrvrVertex(ref_pin); - const PathAnalysisPt *path_ap = path->pathAnalysisPt(this); - const ClockEdge *clk_edge = path->clkEdge(this); - VertexPathIterator path_iter(ref_vertex, ref_rf, path_ap, this); - while (path_iter.hasNext()) { - PathVertex *path = path_iter.next(); - if (path->isClock(this) - && path->clkEdge(this) == clk_edge) { - ref_path.init(path); - break; + if (ref_vertex) { + const PathAnalysisPt *path_ap = path->pathAnalysisPt(this); + const ClockEdge *clk_edge = path->clkEdge(this); + VertexPathIterator path_iter(ref_vertex, ref_rf, path_ap, this); + while (path_iter.hasNext()) { + PathVertex *path = path_iter.next(); + if (path->isClock(this) + && path->clkEdge(this) == clk_edge) { + ref_path.init(path); + break; + } } } } @@ -2851,8 +2858,7 @@ ReportPath::loadCap(Pin *drvr_pin, DcalcAnalysisPt *dcalc_ap) { Parasitic *parasitic = nullptr; - if (arc_delay_calc_) - parasitic = arc_delay_calc_->findParasitic(drvr_pin, rf, dcalc_ap); + parasitic = arc_delay_calc_->findParasitic(drvr_pin, rf, dcalc_ap); float load_cap = graph_delay_calc_->loadCap(drvr_pin, parasitic, rf, dcalc_ap); arc_delay_calc_->finishDrvrPin(); return load_cap; diff --git a/search/Search.cc b/search/Search.cc index e1148303..daf43498 100644 --- a/search/Search.cc +++ b/search/Search.cc @@ -23,7 +23,6 @@ #include "Mutex.hh" #include "Report.hh" #include "Debug.hh" -#include "Error.hh" #include "Stats.hh" #include "Fuzzy.hh" #include "TimingRole.hh" @@ -1192,7 +1191,8 @@ Search::arrivalsChanged(Vertex *vertex, Arrival *arrivals1 = graph_->arrivals(vertex); if (arrivals1) { TagGroup *tag_group = tagGroup(vertex); - if (tag_group->arrivalMap()->size() != tag_bldr->arrivalMap()->size()) + if (tag_group == nullptr + || tag_group->arrivalMap()->size() != tag_bldr->arrivalMap()->size()) return true; ArrivalMap::Iterator arrival_iter1(tag_group->arrivalMap()); while (arrival_iter1.hasNext()) { @@ -3373,9 +3373,13 @@ RequiredCmp::requiredsSave(Vertex *vertex, Graph *graph = sta->graph(); const Search *search = sta->search(); TagGroup *tag_group = search->tagGroup(vertex); - int arrival_count = tag_group->arrivalCount(); - graph->deleteRequireds(vertex, arrival_count); - requireds_changed = true; + if (tag_group == nullptr) + requireds_changed = true; + else { + int arrival_count = tag_group->arrivalCount(); + graph->deleteRequireds(vertex, arrival_count); + requireds_changed = true; + } } return requireds_changed; } diff --git a/search/Sim.cc b/search/Sim.cc index d7873a62..b49400e0 100644 --- a/search/Sim.cc +++ b/search/Sim.cc @@ -468,12 +468,14 @@ Sim::evalExpr(const FuncExpr *expr, { switch (expr->op()) { case FuncExpr::op_port: { - Pin *pin = network_->findPin(inst, expr->port()->name()); - if (pin) - return logicValue(pin); - else - // Internal ports don't have instance pins. - return LogicValue::unknown; + LibertyPort *port = expr->port(); + if (port) { + Pin *pin = network_->findPin(inst, port->name()); + if (pin) + return logicValue(pin); + } + // Internal ports don't have instance pins. + return LogicValue::unknown; } case FuncExpr::op_not: return logicNot(evalExpr(expr->left(), inst)); diff --git a/search/Sta.cc b/search/Sta.cc index 7e6c6445..79e5a666 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -4134,11 +4134,12 @@ Sta::replaceCellPinInvalidate(LibertyPort *from_port, LibertyCell *to_cell) { LibertyPort *to_port = to_cell->findLibertyPort(from_port->name()); - if (!libertyPortCapsEqual(to_port, from_port) - // If this is an ideal clock pin, do not invalidate - // arrivals and delay calc on the clock pin driver. - && !(to_port->isClock() - && idealClockMode())) + if (to_port == nullptr + || (!libertyPortCapsEqual(to_port, from_port) + // If this is an ideal clock pin, do not invalidate + // arrivals and delay calc on the clock pin driver. + && !(to_port->isClock() + && idealClockMode()))) // Input port capacitance changed, so invalidate delay // calculation from input driver. delaysInvalidFromFanin(vertex); diff --git a/search/WritePathSpice.cc b/search/WritePathSpice.cc index d2279464..96f8edb3 100644 --- a/search/WritePathSpice.cc +++ b/search/WritePathSpice.cc @@ -979,7 +979,8 @@ WritePathSpice::gatePortValues(Stage stage, Edge *gate_edge = stageGateEdge(stage); LibertyPort *drvr_port = stageDrvrPort(stage); - if (gate_edge->role()->genericRole() == TimingRole::regClkToQ()) + if (gate_edge + && gate_edge->role()->genericRole() == TimingRole::regClkToQ()) regPortValues(stage, port_values, clk, dcalc_ap_index); else if (drvr_port->function()) { Pin *input_pin = stageGateInputPin(stage); diff --git a/util/MachineLinux.cc b/util/MachineLinux.cc index 22498624..db00c5fe 100644 --- a/util/MachineLinux.cc +++ b/util/MachineLinux.cc @@ -78,11 +78,11 @@ memoryUsage() size_t memory = 0; FILE *status = fopen(proc_filename.c_str(), "r"); if (status) { - const size_t line_length = 128; + constexpr size_t line_length = 128; char line[line_length]; while (fgets(line, line_length, status) != nullptr) { char *field = strtok(line, " \t"); - if (stringEq(field, "VmRSS:")) { + if (field && stringEq(field, "VmRSS:")) { char *size = strtok(nullptr, " \t"); if (size) { char *ignore; diff --git a/util/Stats.cc b/util/Stats.cc index f928933f..4d1fc1c9 100644 --- a/util/Stats.cc +++ b/util/Stats.cc @@ -25,6 +25,10 @@ namespace sta { Stats::Stats(Debug *debug, Report *report) : + elapsed_begin_(0.0), + user_begin_(0.0), + system_begin_(0.0), + memory_begin_(0), debug_(debug), report_(report) { diff --git a/util/TokenParser.cc b/util/TokenParser.cc index d66655b9..3228bef5 100644 --- a/util/TokenParser.cc +++ b/util/TokenParser.cc @@ -21,9 +21,11 @@ namespace sta { -TokenParser::TokenParser(const char *str, const char *delimiters) : +TokenParser::TokenParser(const char *str, + const char *delimiters) : delimiters_(delimiters), token_(const_cast(str)), + token_delimiter_('\0'), first_(true) { // Skip leading spaces. diff --git a/verilog/VerilogReader.cc b/verilog/VerilogReader.cc index 93922ff8..f0b56145 100644 --- a/verilog/VerilogReader.cc +++ b/verilog/VerilogReader.cc @@ -808,35 +808,37 @@ VerilogModule::parseDcl(VerilogDcl *dcl, { for (VerilogDclArg *arg : *dcl->args()) { const char *net_name = arg->netName(); - VerilogDcl *existing_dcl = dcl_map_[net_name]; - if (existing_dcl) { - PortDirection *existing_dir = existing_dcl->direction(); - if (existing_dir->isInternal()) - // wire dcl can be used as modifier for input/inout dcls. - // Ignore the wire dcl. - dcl_map_[net_name] = dcl; - else if (dcl->direction()->isTristate()) { - if (existing_dir->isOutput()) - // tri dcl can be used as modifier for input/output/inout dcls. - // Keep the tristate dcl for outputs because it is more specific - // but ignore it for inputs and bidirs. - dcl_map_[net_name] = dcl; + if (net_name) { + VerilogDcl *existing_dcl = dcl_map_[net_name]; + if (existing_dcl) { + PortDirection *existing_dir = existing_dcl->direction(); + if (existing_dir->isInternal()) + // wire dcl can be used as modifier for input/inout dcls. + // Ignore the wire dcl. + dcl_map_[net_name] = dcl; + else if (dcl->direction()->isTristate()) { + if (existing_dir->isOutput()) + // tri dcl can be used as modifier for input/output/inout dcls. + // Keep the tristate dcl for outputs because it is more specific + // but ignore it for inputs and bidirs. + dcl_map_[net_name] = dcl; + } + else if (dcl->direction()->isPowerGround() + && (existing_dir->isOutput() + || existing_dir->isInput() + || existing_dir->isBidirect())) + // supply0/supply1 dcl can be used as modifier for + // input/output/inout dcls. + dcl_map_[net_name] = dcl; + else if (!dcl->direction()->isInternal()) + reader->warn(18, filename_, dcl->line(), + "signal %s previously declared on line %d.", + reader->netVerilogName(net_name), + existing_dcl->line()); } - else if (dcl->direction()->isPowerGround() - && (existing_dir->isOutput() - || existing_dir->isInput() - || existing_dir->isBidirect())) - // supply0/supply1 dcl can be used as modifier for - // input/output/inout dcls. - dcl_map_[net_name] = dcl; - else if (!dcl->direction()->isInternal()) - reader->warn(18, filename_, dcl->line(), - "signal %s previously declared on line %d.", - reader->netVerilogName(net_name), - existing_dcl->line()); + else + dcl_map_[net_name] = dcl; } - else - dcl_map_[net_name] = dcl; } } @@ -1840,7 +1842,8 @@ VerilogReader::makeModuleInstNetwork(VerilogModuleInst *mod_inst, } if (!is_leaf) { VerilogModule *module = this->module(cell); - makeModuleInstBody(module, inst, &bindings, make_black_boxes); + if (module) + makeModuleInstBody(module, inst, &bindings, make_black_boxes); } } }