issue1879 overlapping path delay exceptions

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2022-08-08 21:33:58 -07:00
parent 1aa348f6fe
commit 6002e66cba
5 changed files with 61 additions and 26 deletions

View File

@ -439,6 +439,9 @@ public:
bool matches(const Pin *pin,
const RiseFall *end_rf) const;
bool matches(const Clock *clk) const;
bool matches(const Pin *pin,
const RiseFall *end_rf,
const Network *network) const;
bool matchesFilter(const Pin *pin,
const ClockEdge *clk_edge,
const RiseFall *end_rf,

View File

@ -976,6 +976,10 @@ public:
const MinMax *min_max,
bool match_min_max_exactly,
bool require_to_pin) const;
bool isCompleteTo(ExceptionState *state,
const Pin *pin,
const RiseFall *rf,
const MinMax *min_max) const;
bool isPathDelayInternalStartpoint(const Pin *pin) const;
PinSet *pathDelayInternalStartpoints() const;
bool isPathDelayInternalEndpoint(const Pin *pin) const;

View File

@ -1465,6 +1465,23 @@ ExceptionTo::matches(const Pin *pin,
&& end_rf_->matches(end_rf));
}
bool
ExceptionTo::matches(const Pin *pin,
const RiseFall *end_rf,
const Network *network) const
{
return (pins_
&& pins_->hasKey(const_cast<Pin*>(pin))
&& rf_->matches(end_rf)
&& end_rf_->matches(end_rf))
|| (insts_
&& insts_->hasKey(network->instance(pin))
&& (network->direction(pin)->isAnyInput()
|| network->direction(pin)->isInternal())
&& rf_->matches(end_rf)
&& end_rf_->matches(end_rf));
}
bool
ExceptionTo::matches(const Pin *pin,
const RiseFall *end_rf) const

View File

@ -5620,6 +5620,20 @@ Sdc::isCompleteTo(ExceptionState *state,
min_max, match_min_max_exactly, require_to_pin);
}
bool
Sdc::isCompleteTo(ExceptionState *state,
const Pin *pin,
const RiseFall *rf,
const MinMax *min_max) const
{
ExceptionPath *exception = state->exception();
ExceptionTo *to = exception->to();
return state->nextThru() == nullptr
&& to
&& exception->matches(min_max, true)
&& to->matches(pin, rf, network_);
}
////////////////////////////////////////////////////////////////
Wireload *

View File

@ -1134,11 +1134,9 @@ ArrivalVisitor::visit(Vertex *vertex)
&& network->isLatchData(pin))
search->enqueueLatchDataOutputs(vertex);
}
if ((!search->arrivalsAtEndpointsExist()
|| always_to_endpoints_
|| arrivals_changed)
&& (network->isRegClkPin(pin)
|| !sdc->isPathDelayInternalEndpoint(pin)))
if (!search->arrivalsAtEndpointsExist()
|| always_to_endpoints_
|| arrivals_changed)
search->arrivalIterator()->enqueueAdjacentVertices(vertex, adj_pred_);
if (arrivals_changed) {
debugPrint(debug, "search", 4, "arrival changed");
@ -2033,27 +2031,22 @@ PathVisitor::visitEdge(const Pin *from_pin,
VertexPathIterator from_iter(from_vertex, search);
while (from_iter.hasNext()) {
PathVertex *from_path = from_iter.next();
Tag *from_tag = from_path->tag(sta_);
// Only propagate seeded paths from segment startpoint.
if (!search->isSegmentStart(from_pin)
|| from_tag->isSegmentStart()) {
PathAnalysisPt *path_ap = from_path->pathAnalysisPt(sta_);
const MinMax *min_max = path_ap->pathMinMax();
const RiseFall *from_rf = from_path->transition(sta_);
// Do not propagate paths from a clock source unless they are
// defined on the from pin.
if (!search->pathPropagatedToClkSrc(from_pin, from_path)) {
TimingArc *arc1, *arc2;
arc_set->arcsFrom(from_rf, arc1, arc2);
if (!visitArc(from_pin, from_vertex, from_rf, from_path,
edge, arc1, to_pin, to_vertex,
min_max, path_ap))
return false;
if (!visitArc(from_pin, from_vertex, from_rf, from_path,
edge, arc2, to_pin, to_vertex,
min_max, path_ap))
return false;
}
PathAnalysisPt *path_ap = from_path->pathAnalysisPt(sta_);
const MinMax *min_max = path_ap->pathMinMax();
const RiseFall *from_rf = from_path->transition(sta_);
// Do not propagate paths from a clock source unless they are
// defined on the from pin.
if (!search->pathPropagatedToClkSrc(from_pin, from_path)) {
TimingArc *arc1, *arc2;
arc_set->arcsFrom(from_rf, arc1, arc2);
if (!visitArc(from_pin, from_vertex, from_rf, from_path,
edge, arc1, to_pin, to_vertex,
min_max, path_ap))
return false;
if (!visitArc(from_pin, from_vertex, from_rf, from_path,
edge, arc2, to_pin, to_vertex,
min_max, path_ap))
return false;
}
}
}
@ -2565,6 +2558,10 @@ Search::mutateTag(Tag *from_tag,
// Don't propagate a completed false path -thru unless it is a
// clock (which ignores exceptions).
return nullptr;
// Don't propagate path delay tags past the -to pin.
if (exception->isPathDelay()
&& sdc_->isCompleteTo(state, from_pin, from_rf, min_max))
return nullptr;
if (state->matchesNextThru(from_pin,to_pin,to_rf,min_max,network_)) {
// Found a -thru that we've been waiting for.
if (state->nextState()->isComplete()