issue1879 overlapping path delay exceptions
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
1aa348f6fe
commit
6002e66cba
|
|
@ -439,6 +439,9 @@ public:
|
||||||
bool matches(const Pin *pin,
|
bool matches(const Pin *pin,
|
||||||
const RiseFall *end_rf) const;
|
const RiseFall *end_rf) const;
|
||||||
bool matches(const Clock *clk) 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,
|
bool matchesFilter(const Pin *pin,
|
||||||
const ClockEdge *clk_edge,
|
const ClockEdge *clk_edge,
|
||||||
const RiseFall *end_rf,
|
const RiseFall *end_rf,
|
||||||
|
|
|
||||||
|
|
@ -976,6 +976,10 @@ public:
|
||||||
const MinMax *min_max,
|
const MinMax *min_max,
|
||||||
bool match_min_max_exactly,
|
bool match_min_max_exactly,
|
||||||
bool require_to_pin) const;
|
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;
|
bool isPathDelayInternalStartpoint(const Pin *pin) const;
|
||||||
PinSet *pathDelayInternalStartpoints() const;
|
PinSet *pathDelayInternalStartpoints() const;
|
||||||
bool isPathDelayInternalEndpoint(const Pin *pin) const;
|
bool isPathDelayInternalEndpoint(const Pin *pin) const;
|
||||||
|
|
|
||||||
|
|
@ -1465,6 +1465,23 @@ ExceptionTo::matches(const Pin *pin,
|
||||||
&& end_rf_->matches(end_rf));
|
&& 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
|
bool
|
||||||
ExceptionTo::matches(const Pin *pin,
|
ExceptionTo::matches(const Pin *pin,
|
||||||
const RiseFall *end_rf) const
|
const RiseFall *end_rf) const
|
||||||
|
|
|
||||||
14
sdc/Sdc.cc
14
sdc/Sdc.cc
|
|
@ -5620,6 +5620,20 @@ Sdc::isCompleteTo(ExceptionState *state,
|
||||||
min_max, match_min_max_exactly, require_to_pin);
|
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 *
|
Wireload *
|
||||||
|
|
|
||||||
|
|
@ -1134,11 +1134,9 @@ ArrivalVisitor::visit(Vertex *vertex)
|
||||||
&& network->isLatchData(pin))
|
&& network->isLatchData(pin))
|
||||||
search->enqueueLatchDataOutputs(vertex);
|
search->enqueueLatchDataOutputs(vertex);
|
||||||
}
|
}
|
||||||
if ((!search->arrivalsAtEndpointsExist()
|
if (!search->arrivalsAtEndpointsExist()
|
||||||
|| always_to_endpoints_
|
|| always_to_endpoints_
|
||||||
|| arrivals_changed)
|
|| arrivals_changed)
|
||||||
&& (network->isRegClkPin(pin)
|
|
||||||
|| !sdc->isPathDelayInternalEndpoint(pin)))
|
|
||||||
search->arrivalIterator()->enqueueAdjacentVertices(vertex, adj_pred_);
|
search->arrivalIterator()->enqueueAdjacentVertices(vertex, adj_pred_);
|
||||||
if (arrivals_changed) {
|
if (arrivals_changed) {
|
||||||
debugPrint(debug, "search", 4, "arrival changed");
|
debugPrint(debug, "search", 4, "arrival changed");
|
||||||
|
|
@ -2033,10 +2031,6 @@ PathVisitor::visitEdge(const Pin *from_pin,
|
||||||
VertexPathIterator from_iter(from_vertex, search);
|
VertexPathIterator from_iter(from_vertex, search);
|
||||||
while (from_iter.hasNext()) {
|
while (from_iter.hasNext()) {
|
||||||
PathVertex *from_path = from_iter.next();
|
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_);
|
PathAnalysisPt *path_ap = from_path->pathAnalysisPt(sta_);
|
||||||
const MinMax *min_max = path_ap->pathMinMax();
|
const MinMax *min_max = path_ap->pathMinMax();
|
||||||
const RiseFall *from_rf = from_path->transition(sta_);
|
const RiseFall *from_rf = from_path->transition(sta_);
|
||||||
|
|
@ -2056,7 +2050,6 @@ PathVisitor::visitEdge(const Pin *from_pin,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2565,6 +2558,10 @@ Search::mutateTag(Tag *from_tag,
|
||||||
// Don't propagate a completed false path -thru unless it is a
|
// Don't propagate a completed false path -thru unless it is a
|
||||||
// clock (which ignores exceptions).
|
// clock (which ignores exceptions).
|
||||||
return nullptr;
|
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_)) {
|
if (state->matchesNextThru(from_pin,to_pin,to_rf,min_max,network_)) {
|
||||||
// Found a -thru that we've been waiting for.
|
// Found a -thru that we've been waiting for.
|
||||||
if (state->nextState()->isComplete()
|
if (state->nextState()->isComplete()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue