diff --git a/include/sta/Sdc.hh b/include/sta/Sdc.hh index 1ba41f91..a93569fe 100644 --- a/include/sta/Sdc.hh +++ b/include/sta/Sdc.hh @@ -577,6 +577,7 @@ public: const RiseFall *clk_rf, const MinMaxAll *min_max); void ensureInputDelayRefPinEdges(); + void inputDelayRefPinEdgesInvalid(); void setOutputDelay(const Pin *pin, const RiseFallBoth *rf, const Clock *clk, diff --git a/sdc/Sdc.cc b/sdc/Sdc.cc index 088cc967..9b30c470 100644 --- a/sdc/Sdc.cc +++ b/sdc/Sdc.cc @@ -2840,6 +2840,18 @@ Sdc::ensureInputDelayRefPinEdges() } } +// The ref_pin edges are owned by the graph. When the graph is deleted the +// edges go with it, so the existence flags must be reset to force them to be +// rebuilt by ensureInputDelayRefPinEdges() with the new graph. +void +Sdc::inputDelayRefPinEdgesInvalid() +{ + if (have_input_delay_ref_pins_) { + for (InputDelay *input_delay : input_delays_) + input_delay->setRefPinEdgesExist(false); + } +} + //////////////////////////////////////////////////////////////// void diff --git a/search/Sta.cc b/search/Sta.cc index 19f3d994..435b8867 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -544,6 +544,8 @@ Sta::clearNonSdc() for (Mode *mode : modes_) { mode->clkNetwork()->clkPinsInvalid(); mode->sim()->clear(); + // ref_pin edges are owned by the graph deleted below; force a rebuild. + mode->sdc()->inputDelayRefPinEdgesInvalid(); } search_->clear(); diff --git a/test/input_delay_ref_pin_rebuild.ok b/test/input_delay_ref_pin_rebuild.ok new file mode 100644 index 00000000..97a18d36 --- /dev/null +++ b/test/input_delay_ref_pin_rebuild.ok @@ -0,0 +1,112 @@ +=== before rebuild: in1 (ref_pin) === +Startpoint: in1 (input port clocked by clk) +Endpoint: r1 (rising edge-triggered flip-flop clocked by clk) +Path Group: clk +Path Type: max + + Delay Time Description +--------------------------------------------------------- + 0.00 0.00 clock clk (rise edge) + 0.00 0.00 clock network delay (ideal) + 100.00 100.00 ^ input external delay + 0.00 100.00 ^ in1 (in) + 0.00 100.00 ^ r1/D (DFFHQx4_ASAP7_75t_R) + 100.00 data arrival time + + 500.00 500.00 clock clk (rise edge) + 0.00 500.00 clock network delay (ideal) + 0.00 500.00 clock reconvergence pessimism + 500.00 ^ r1/CLK (DFFHQx4_ASAP7_75t_R) + -11.41 488.59 library setup time + 488.59 data required time +--------------------------------------------------------- + 488.59 data required time + -100.00 data arrival time +--------------------------------------------------------- + 388.59 slack (MET) + + +=== before rebuild: in2 (control) === +Startpoint: in2 (input port clocked by clk) +Endpoint: r2 (rising edge-triggered flip-flop clocked by clk) +Path Group: clk +Path Type: max + + Delay Time Description +--------------------------------------------------------- + 0.00 0.00 clock clk (rise edge) + 0.00 0.00 clock network delay (ideal) + 100.00 100.00 ^ input external delay + 0.00 100.00 ^ in2 (in) + 0.00 100.00 ^ r2/D (DFFHQx4_ASAP7_75t_R) + 100.00 data arrival time + + 500.00 500.00 clock clk (rise edge) + 0.00 500.00 clock network delay (ideal) + 0.00 500.00 clock reconvergence pessimism + 500.00 ^ r2/CLK (DFFHQx4_ASAP7_75t_R) + -13.11 486.89 library setup time + 486.89 data required time +--------------------------------------------------------- + 486.89 data required time + -100.00 data arrival time +--------------------------------------------------------- + 386.89 slack (MET) + + +=== after rebuild: in1 (ref_pin) === +Startpoint: in1 (input port clocked by clk) +Endpoint: r1 (rising edge-triggered flip-flop clocked by clk) +Path Group: clk +Path Type: max + + Delay Time Description +--------------------------------------------------------- + 0.00 0.00 clock clk (rise edge) + 0.00 0.00 clock network delay (ideal) + 100.00 100.00 ^ input external delay + 0.00 100.00 ^ in1 (in) + 0.00 100.00 ^ r1/D (DFFHQx4_ASAP7_75t_R) + 100.00 data arrival time + + 500.00 500.00 clock clk (rise edge) + 0.00 500.00 clock network delay (ideal) + 0.00 500.00 clock reconvergence pessimism + 500.00 ^ r1/CLK (DFFHQx4_ASAP7_75t_R) + -11.41 488.59 library setup time + 488.59 data required time +--------------------------------------------------------- + 488.59 data required time + -100.00 data arrival time +--------------------------------------------------------- + 388.59 slack (MET) + + +=== after rebuild: in2 (control) === +Startpoint: in2 (input port clocked by clk) +Endpoint: r2 (rising edge-triggered flip-flop clocked by clk) +Path Group: clk +Path Type: max + + Delay Time Description +--------------------------------------------------------- + 0.00 0.00 clock clk (rise edge) + 0.00 0.00 clock network delay (ideal) + 100.00 100.00 ^ input external delay + 0.00 100.00 ^ in2 (in) + 0.00 100.00 ^ r2/D (DFFHQx4_ASAP7_75t_R) + 100.00 data arrival time + + 500.00 500.00 clock clk (rise edge) + 0.00 500.00 clock network delay (ideal) + 0.00 500.00 clock reconvergence pessimism + 500.00 ^ r2/CLK (DFFHQx4_ASAP7_75t_R) + -13.11 486.89 library setup time + 486.89 data required time +--------------------------------------------------------- + 486.89 data required time + -100.00 data arrival time +--------------------------------------------------------- + 386.89 slack (MET) + + diff --git a/test/input_delay_ref_pin_rebuild.tcl b/test/input_delay_ref_pin_rebuild.tcl new file mode 100644 index 00000000..dcf0ac14 --- /dev/null +++ b/test/input_delay_ref_pin_rebuild.tcl @@ -0,0 +1,28 @@ +# set_input_delay -reference_pin must survive a graph rebuild that keeps SDC +# (resizer-like: sta::network_changed_non_sdc deletes the graph but not the +# constraints). The ref_pin->input graph edge is owned by the graph; its +# existence flag (PortDelay::ref_pin_edges_exist_) must be reset on graph +# teardown so ensureInputDelayRefPinEdges() rebuilds the edge. Otherwise in1 +# loses its arrival seeding and reports "No paths found" after the rebuild. +# in2 is a plain input delay (no ref_pin) used as a control. +read_liberty asap7_small.lib.gz +read_verilog reg1_asap7.v +link_design top + +create_clock -name clk -period 500 {clk1 clk2 clk3} +set_input_delay -clock clk 100 -reference_pin r2/CLK [get_ports in1] +set_input_delay -clock clk 100 [get_ports in2] +set_input_transition 10 {in1 in2 clk1 clk2 clk3} +set_output_delay -clock clk 1 [get_ports out] + +puts "=== before rebuild: in1 (ref_pin) ===" +report_checks -from in1 -path_delay max +puts "=== before rebuild: in2 (control) ===" +report_checks -from in2 -path_delay max + +sta::network_changed_non_sdc + +puts "=== after rebuild: in1 (ref_pin) ===" +report_checks -from in1 -path_delay max +puts "=== after rebuild: in2 (control) ===" +report_checks -from in2 -path_delay max diff --git a/test/regression_vars.tcl b/test/regression_vars.tcl index bf7e9faa..d1e30064 100644 --- a/test/regression_vars.tcl +++ b/test/regression_vars.tcl @@ -148,6 +148,7 @@ record_public_tests { get_lib_pins_of_objects get_noargs get_objrefs + input_delay_ref_pin_rebuild liberty_arcs_one2one_1 liberty_arcs_one2one_2 liberty_backslash_eol