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