diff --git a/include/sta/Sdc.hh b/include/sta/Sdc.hh index 622ca6b7..580303dc 100644 --- a/include/sta/Sdc.hh +++ b/include/sta/Sdc.hh @@ -1115,6 +1115,7 @@ protected: void recordMergeHash(ExceptionPath *exception, ExceptionPt *missing_pt); void recordMergeHashes(ExceptionPath *exception); void unrecordExceptionFirstPts(ExceptionPath *exception); + void unrecordExceptionPins(ExceptionPath *exception); void unrecordExceptionClks(ExceptionPath *exception, ClockSet *clks, ClockExceptionsMap &exception_map); diff --git a/sdc/Sdc.cc b/sdc/Sdc.cc index d44979a9..1522bbcf 100644 --- a/sdc/Sdc.cc +++ b/sdc/Sdc.cc @@ -4880,6 +4880,8 @@ Sdc::findMergeMatch(ExceptionPath *exception) void Sdc::deleteExceptions() { + for (ExceptionPath *exception : exceptions_) + delete exception; exceptions_.clear(); exception_id_ = 0; @@ -4964,6 +4966,7 @@ Sdc::unrecordException(ExceptionPath *exception) { unrecordMergeHashes(exception); unrecordExceptionFirstPts(exception); + unrecordExceptionPins(exception); exceptions_.erase(exception); } @@ -5022,6 +5025,22 @@ Sdc::unrecordExceptionFirstPts(ExceptionPath *exception) } } +void +Sdc::unrecordExceptionPins(ExceptionPath *exception) +{ + ExceptionFrom *from = exception->from(); + if (from) + unrecordExceptionPins(exception, from->pins(), pin_exceptions_); + ExceptionThruSeq *thrus = exception->thrus(); + if (thrus) { + for (ExceptionThru *thru : *thrus) + unrecordExceptionPins(exception, thru->pins(), pin_exceptions_); + } + ExceptionTo *to = exception->to(); + if (to) + unrecordExceptionPins(exception, to->pins(), pin_exceptions_); +} + void Sdc::unrecordExceptionClks(ExceptionPath *exception, ClockSet *clks, diff --git a/test/disconnect_mcp_pin.tcl b/test/disconnect_mcp_pin.tcl new file mode 100644 index 00000000..e1641f66 --- /dev/null +++ b/test/disconnect_mcp_pin.tcl @@ -0,0 +1,29 @@ +# disconnect/disconnect pin set_multicycle_path +read_liberty asap7_small.lib.gz +read_verilog disconnect_mcp_pin.v +link_design top + +create_clock -name clk -period 500 clk +set_input_delay -clock clk 10 data_in[*] + +# This SDC defines setup and hold time requirements for data pins +# relative to a clock, typical for a source-synchronous interface. +set_data_check -from clk -to [get_pins u0/A] -setup 10 +set_data_check -from clk -to [get_pins u0/A] -hold 10 +set_data_check -from clk -to [get_pins u1/A] -setup 10 +set_data_check -from clk -to [get_pins u1/A] -hold 10 +set_multicycle_path -end -setup 1 -to [get_pins u0/A] +set_multicycle_path -end -setup 1 -to [get_pins u1/A] +set_multicycle_path -start -hold 0 -to [get_pins u0/A] +set_multicycle_path -start -hold 0 -to [get_pins u1/A] + +report_checks -to u1/A + +disconnect_pin data_in[1] u1/A + +report_checks -to u1/A + +connect_pin data_in[1] u1/A + +report_checks -to u1/A + diff --git a/test/disconnect_mcp_pin.v b/test/disconnect_mcp_pin.v new file mode 100644 index 00000000..6608e8fb --- /dev/null +++ b/test/disconnect_mcp_pin.v @@ -0,0 +1,11 @@ +module top (clk, clkout, data_in, data_out); + input clk; + output clkout; + input [1:0] data_in; + output [1:0] data_out; + + // Anchor buffers on the source-synchronous interface IOs + BUFx2_ASAP7_75t_R clkbuf0 (.A(clk), .Y(clkout)); + BUFx2_ASAP7_75t_R u0 (.A(data_in[0]), .Y(data_out[0])); + BUFx2_ASAP7_75t_R u1 (.A(data_in[1]), .Y(data_out[1])); +endmodule // top diff --git a/test/regression_vars.tcl b/test/regression_vars.tcl index d7a46617..c8e662e7 100644 --- a/test/regression_vars.tcl +++ b/test/regression_vars.tcl @@ -138,6 +138,7 @@ record_example_tests { } record_sta_tests { + disconnect_mcp_pin get_filter get_is_memory get_lib_pins_of_objects