set_min/max_delay -probe support
commit c7576dba7baa28cab4178faf159d365147d07061
Author: James Cherry <cherry@parallaxsw.com>
Date: Tue May 20 14:45:14 2025 -0700
set_min/max_delay -probe doc
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit fbaf5a63fc3323cc0b3bc72479081e30eda81116
Author: James Cherry <cherry@parallaxsw.com>
Date: Fri May 16 10:21:45 2025 -0700
break paths at internal endpoints
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit 7ed829dfe3ca930211d272856857cfc177fd5df0
Author: James Cherry <cherry@parallaxsw.com>
Date: Fri May 16 08:52:44 2025 -0700
internal startpoints break in PathVisitor::visitFromPath
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit 37eb1247c47773f74d37f683c48df0bb0c68432a
Author: James Cherry <cherry@parallaxsw.com>
Date: Thu May 15 12:35:34 2025 -0700
ExceptionPath::noBreak
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit f514f1a97c709416a0ccfab70b4a1047e6c8c501
Author: James Cherry <cherry@parallaxsw.com>
Date: Mon May 12 20:35:32 2025 -0700
ExceptionPath::noBreak virtual
Signed-off-by: James Cherry <cherry@parallaxsw.com>
commit b94eb1fe13d2c6ab8457f4a7b5ba5e0f98f41f90
Author: James Cherry <cherry@parallaxsw.com>
Date: Wed May 7 08:47:55 2025 -0700
set_max_path -probe arg parse
Signed-off-by: James Cherry <cherry@parallaxsw.com>
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
c416229106
commit
9c85946be0
|
|
@ -9,6 +9,9 @@ Release 2.7.0 2025/05/19
|
||||||
The OpenSTA library `libOpenSTA` and `sta` executable are now built in the
|
The OpenSTA library `libOpenSTA` and `sta` executable are now built in the
|
||||||
build directory instead of `app/`.
|
build directory instead of `app/`.
|
||||||
|
|
||||||
|
The set_max_delay and set_min_delay commands now support the -probe option.
|
||||||
|
With -probe these commands do not break paths at internal (non-startpoint) pins.
|
||||||
|
|
||||||
Release 2.6.1 2025/03/30
|
Release 2.6.1 2025/03/30
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
|
|
|
||||||
BIN
doc/OpenSTA.odt
BIN
doc/OpenSTA.odt
Binary file not shown.
BIN
doc/OpenSTA.pdf
BIN
doc/OpenSTA.pdf
Binary file not shown.
|
|
@ -126,6 +126,7 @@ public:
|
||||||
virtual const char *name() const { return nullptr; }
|
virtual const char *name() const { return nullptr; }
|
||||||
virtual bool isDefault() const { return false; }
|
virtual bool isDefault() const { return false; }
|
||||||
virtual bool ignoreClkLatency() const { return false; }
|
virtual bool ignoreClkLatency() const { return false; }
|
||||||
|
virtual bool breakPath() const { return false; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual const char *typeString() const = 0;
|
virtual const char *typeString() const = 0;
|
||||||
|
|
@ -194,6 +195,7 @@ public:
|
||||||
ExceptionTo *to,
|
ExceptionTo *to,
|
||||||
const MinMax *min_max,
|
const MinMax *min_max,
|
||||||
bool ignore_clk_latency,
|
bool ignore_clk_latency,
|
||||||
|
bool break_path,
|
||||||
float delay,
|
float delay,
|
||||||
bool own_pts,
|
bool own_pts,
|
||||||
const char *comment);
|
const char *comment);
|
||||||
|
|
@ -211,9 +213,11 @@ public:
|
||||||
virtual int typePriority() const;
|
virtual int typePriority() const;
|
||||||
virtual bool tighterThan(ExceptionPath *exception) const;
|
virtual bool tighterThan(ExceptionPath *exception) const;
|
||||||
virtual bool ignoreClkLatency() const { return ignore_clk_latency_; }
|
virtual bool ignoreClkLatency() const { return ignore_clk_latency_; }
|
||||||
|
virtual bool breakPath() const { return break_path_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool ignore_clk_latency_;
|
bool ignore_clk_latency_;
|
||||||
|
bool break_path_;
|
||||||
float delay_;
|
float delay_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -744,6 +744,7 @@ public:
|
||||||
ExceptionTo *to,
|
ExceptionTo *to,
|
||||||
const MinMax *min_max,
|
const MinMax *min_max,
|
||||||
bool ignore_clk_latency,
|
bool ignore_clk_latency,
|
||||||
|
bool break_path,
|
||||||
float delay,
|
float delay,
|
||||||
const char *comment);
|
const char *comment);
|
||||||
bool pathDelaysWithoutTo() const { return path_delays_without_to_; }
|
bool pathDelaysWithoutTo() const { return path_delays_without_to_; }
|
||||||
|
|
@ -1003,9 +1004,11 @@ public:
|
||||||
const Pin *pin,
|
const Pin *pin,
|
||||||
const RiseFall *rf,
|
const RiseFall *rf,
|
||||||
const MinMax *min_max) const;
|
const MinMax *min_max) const;
|
||||||
bool isPathDelayInternalStartpoint(const Pin *pin) const;
|
bool isPathDelayInternalFrom(const Pin *pin) const;
|
||||||
const PinSet &pathDelayInternalStartpoints() const;
|
bool isPathDelayInternalFromBreak(const Pin *pin) const;
|
||||||
bool isPathDelayInternalEndpoint(const Pin *pin) const;
|
const PinSet &pathDelayInternalFrom() const;
|
||||||
|
bool isPathDelayInternalTo(const Pin *pin) const;
|
||||||
|
bool isPathDelayInternalToBreak(const Pin *pin) const;
|
||||||
ExceptionPathSet *exceptions() { return &exceptions_; }
|
ExceptionPathSet *exceptions() { return &exceptions_; }
|
||||||
void deleteExceptions();
|
void deleteExceptions();
|
||||||
void deleteException(ExceptionPath *exception);
|
void deleteException(ExceptionPath *exception);
|
||||||
|
|
@ -1042,11 +1045,11 @@ protected:
|
||||||
ExceptionPath *findMergeMatch(ExceptionPath *exception);
|
ExceptionPath *findMergeMatch(ExceptionPath *exception);
|
||||||
void addException1(ExceptionPath *exception);
|
void addException1(ExceptionPath *exception);
|
||||||
void addException2(ExceptionPath *exception);
|
void addException2(ExceptionPath *exception);
|
||||||
void recordPathDelayInternalStartpoints(ExceptionPath *exception);
|
void recordPathDelayInternalFrom(ExceptionPath *exception);
|
||||||
void unrecordPathDelayInternalStartpoints(ExceptionFrom *from);
|
void unrecordPathDelayInternalFrom(ExceptionPath *exception);
|
||||||
bool pathDelayFrom(const Pin *pin);
|
bool pathDelayFrom(const Pin *pin);
|
||||||
void recordPathDelayInternalEndpoints(ExceptionPath *exception);
|
void recordPathDelayInternalTo(ExceptionPath *exception);
|
||||||
void unrecordPathDelayInternalEndpoints(ExceptionPath *exception);
|
void unrecordPathDelayInternalTo(ExceptionPath *exception);
|
||||||
bool pathDelayTo(const Pin *pin);
|
bool pathDelayTo(const Pin *pin);
|
||||||
bool hasLibertyCheckTo(const Pin *pin);
|
bool hasLibertyCheckTo(const Pin *pin);
|
||||||
void deleteMatchingExceptions(ExceptionPath *exception);
|
void deleteMatchingExceptions(ExceptionPath *exception);
|
||||||
|
|
@ -1355,9 +1358,13 @@ protected:
|
||||||
// Exception hash with one missing from/thru/to point, used for merging.
|
// Exception hash with one missing from/thru/to point, used for merging.
|
||||||
ExceptionPathPtHash exception_merge_hash_;
|
ExceptionPathPtHash exception_merge_hash_;
|
||||||
// Path delay -from pin internal startpoints.
|
// Path delay -from pin internal startpoints.
|
||||||
PinSet path_delay_internal_startpoints_;
|
PinSet path_delay_internal_from_;
|
||||||
// Path delay -to pin internal endpoints.
|
// Path delay -from pin internal -from w/o -probe.
|
||||||
PinSet path_delay_internal_endpoints_;
|
PinSet path_delay_internal_from_break_;
|
||||||
|
// Path delay -to pin internal -to.
|
||||||
|
PinSet path_delay_internal_to_;
|
||||||
|
// Path delay -to pin internal -to w/o -probe.
|
||||||
|
PinSet path_delay_internal_to_break_;
|
||||||
// There is a path delay exception without a -to.
|
// There is a path delay exception without a -to.
|
||||||
bool path_delays_without_to_;
|
bool path_delays_without_to_;
|
||||||
// Group path exception names.
|
// Group path exception names.
|
||||||
|
|
|
||||||
|
|
@ -508,6 +508,7 @@ public:
|
||||||
ExceptionTo *to,
|
ExceptionTo *to,
|
||||||
const MinMax *min_max,
|
const MinMax *min_max,
|
||||||
bool ignore_clk_latency,
|
bool ignore_clk_latency,
|
||||||
|
bool break_path,
|
||||||
float delay,
|
float delay,
|
||||||
const char *comment);
|
const char *comment);
|
||||||
void makeGroupPath(const char *name,
|
void makeGroupPath(const char *name,
|
||||||
|
|
|
||||||
|
|
@ -465,6 +465,7 @@ PathDelay::PathDelay(ExceptionFrom *from,
|
||||||
ExceptionTo *to,
|
ExceptionTo *to,
|
||||||
const MinMax *min_max,
|
const MinMax *min_max,
|
||||||
bool ignore_clk_latency,
|
bool ignore_clk_latency,
|
||||||
|
bool break_path,
|
||||||
float delay,
|
float delay,
|
||||||
bool own_pts,
|
bool own_pts,
|
||||||
const char *comment) :
|
const char *comment) :
|
||||||
|
|
@ -472,6 +473,7 @@ PathDelay::PathDelay(ExceptionFrom *from,
|
||||||
pathDelayPriority() + fromThruToPriority(from, thrus, to),
|
pathDelayPriority() + fromThruToPriority(from, thrus, to),
|
||||||
comment),
|
comment),
|
||||||
ignore_clk_latency_(ignore_clk_latency),
|
ignore_clk_latency_(ignore_clk_latency),
|
||||||
|
break_path_(break_path),
|
||||||
delay_(delay)
|
delay_(delay)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -483,8 +485,8 @@ PathDelay::clone(ExceptionFrom *from,
|
||||||
bool own_pts)
|
bool own_pts)
|
||||||
{
|
{
|
||||||
return new PathDelay(from, thrus, to, min_max_->asMinMax(),
|
return new PathDelay(from, thrus, to, min_max_->asMinMax(),
|
||||||
ignore_clk_latency_, delay_, own_pts,
|
ignore_clk_latency_, break_path_, delay_,
|
||||||
comment_);
|
own_pts, comment_);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
||||||
81
sdc/Sdc.cc
81
sdc/Sdc.cc
|
|
@ -122,8 +122,10 @@ Sdc::Sdc(StaState *sta) :
|
||||||
exception_id_(0),
|
exception_id_(0),
|
||||||
have_thru_hpin_exceptions_(false),
|
have_thru_hpin_exceptions_(false),
|
||||||
first_thru_edge_exceptions_(0, PinPairHash(network_), PinPairEqual()),
|
first_thru_edge_exceptions_(0, PinPairHash(network_), PinPairEqual()),
|
||||||
path_delay_internal_startpoints_(network_),
|
path_delay_internal_from_(network_),
|
||||||
path_delay_internal_endpoints_(network_)
|
path_delay_internal_from_break_(network_),
|
||||||
|
path_delay_internal_to_(network_),
|
||||||
|
path_delay_internal_to_break_(network_)
|
||||||
{
|
{
|
||||||
sdc_ = this;
|
sdc_ = this;
|
||||||
initVariables();
|
initVariables();
|
||||||
|
|
@ -3875,18 +3877,19 @@ Sdc::makePathDelay(ExceptionFrom *from,
|
||||||
ExceptionTo *to,
|
ExceptionTo *to,
|
||||||
const MinMax *min_max,
|
const MinMax *min_max,
|
||||||
bool ignore_clk_latency,
|
bool ignore_clk_latency,
|
||||||
|
bool break_path,
|
||||||
float delay,
|
float delay,
|
||||||
const char *comment)
|
const char *comment)
|
||||||
{
|
{
|
||||||
checkFromThrusTo(from, thrus, to);
|
checkFromThrusTo(from, thrus, to);
|
||||||
PathDelay *exception = new PathDelay(from, thrus, to, min_max,
|
PathDelay *exception = new PathDelay(from, thrus, to, min_max,
|
||||||
ignore_clk_latency, delay, true,
|
ignore_clk_latency, break_path,
|
||||||
comment);
|
delay, true, comment);
|
||||||
addException(exception);
|
addException(exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sdc::recordPathDelayInternalStartpoints(ExceptionPath *exception)
|
Sdc::recordPathDelayInternalFrom(ExceptionPath *exception)
|
||||||
{
|
{
|
||||||
ExceptionFrom *from = exception->from();
|
ExceptionFrom *from = exception->from();
|
||||||
if (from
|
if (from
|
||||||
|
|
@ -3894,23 +3897,29 @@ Sdc::recordPathDelayInternalStartpoints(ExceptionPath *exception)
|
||||||
for (const Pin *pin : *from->pins()) {
|
for (const Pin *pin : *from->pins()) {
|
||||||
if (!(network_->isRegClkPin(pin)
|
if (!(network_->isRegClkPin(pin)
|
||||||
|| network_->isTopLevelPort(pin))) {
|
|| network_->isTopLevelPort(pin))) {
|
||||||
path_delay_internal_startpoints_.insert(pin);
|
path_delay_internal_from_.insert(pin);
|
||||||
|
if (exception->breakPath())
|
||||||
|
path_delay_internal_from_break_.insert(pin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sdc::unrecordPathDelayInternalStartpoints(ExceptionFrom *from)
|
Sdc::unrecordPathDelayInternalFrom(ExceptionPath *exception)
|
||||||
{
|
{
|
||||||
|
ExceptionFrom *from = exception->from();
|
||||||
if (from
|
if (from
|
||||||
&& from->hasPins()
|
&& from->hasPins()
|
||||||
&& !path_delay_internal_startpoints_.empty()) {
|
&& !path_delay_internal_from_.empty()) {
|
||||||
for (const Pin *pin : *from->pins()) {
|
for (const Pin *pin : *from->pins()) {
|
||||||
if (!(network_->isRegClkPin(pin)
|
if (!(network_->isRegClkPin(pin)
|
||||||
|| network_->isTopLevelPort(pin))
|
|| network_->isTopLevelPort(pin))
|
||||||
&& !pathDelayFrom(pin))
|
&& !pathDelayFrom(pin)) {
|
||||||
path_delay_internal_startpoints_.erase(pin);
|
path_delay_internal_from_.erase(pin);
|
||||||
|
if (exception->breakPath())
|
||||||
|
path_delay_internal_from_break_.erase(pin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3927,19 +3936,25 @@ Sdc::pathDelayFrom(const Pin *pin)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Sdc::isPathDelayInternalStartpoint(const Pin *pin) const
|
Sdc::isPathDelayInternalFrom(const Pin *pin) const
|
||||||
{
|
{
|
||||||
return path_delay_internal_startpoints_.hasKey(pin);
|
return path_delay_internal_from_.hasKey(pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Sdc::isPathDelayInternalFromBreak(const Pin *pin) const
|
||||||
|
{
|
||||||
|
return path_delay_internal_from_break_.hasKey(pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
const PinSet &
|
const PinSet &
|
||||||
Sdc::pathDelayInternalStartpoints() const
|
Sdc::pathDelayInternalFrom() const
|
||||||
{
|
{
|
||||||
return path_delay_internal_startpoints_;
|
return path_delay_internal_from_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sdc::recordPathDelayInternalEndpoints(ExceptionPath *exception)
|
Sdc::recordPathDelayInternalTo(ExceptionPath *exception)
|
||||||
{
|
{
|
||||||
ExceptionTo *to = exception->to();
|
ExceptionTo *to = exception->to();
|
||||||
if (to
|
if (to
|
||||||
|
|
@ -3947,24 +3962,28 @@ Sdc::recordPathDelayInternalEndpoints(ExceptionPath *exception)
|
||||||
for (const Pin *pin : *to->pins()) {
|
for (const Pin *pin : *to->pins()) {
|
||||||
if (!(hasLibertyCheckTo(pin)
|
if (!(hasLibertyCheckTo(pin)
|
||||||
|| network_->isTopLevelPort(pin))) {
|
|| network_->isTopLevelPort(pin))) {
|
||||||
path_delay_internal_endpoints_.insert(pin);
|
path_delay_internal_to_.insert(pin);
|
||||||
|
if (exception->breakPath())
|
||||||
|
path_delay_internal_to_break_.insert(pin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sdc::unrecordPathDelayInternalEndpoints(ExceptionPath *exception)
|
Sdc::unrecordPathDelayInternalTo(ExceptionPath *exception)
|
||||||
{
|
{
|
||||||
ExceptionTo *to = exception->to();
|
ExceptionTo *to = exception->to();
|
||||||
if (to
|
if (to
|
||||||
&& to->hasPins()
|
&& to->hasPins()
|
||||||
&& !path_delay_internal_endpoints_.empty()) {
|
&& !path_delay_internal_to_.empty()) {
|
||||||
for (const Pin *pin : *to->pins()) {
|
for (const Pin *pin : *to->pins()) {
|
||||||
if (!(hasLibertyCheckTo(pin)
|
if (!(hasLibertyCheckTo(pin)
|
||||||
|| network_->isTopLevelPort(pin))
|
|| network_->isTopLevelPort(pin))
|
||||||
&& !pathDelayTo(pin))
|
&& !pathDelayTo(pin))
|
||||||
path_delay_internal_endpoints_.erase(pin);
|
path_delay_internal_to_.erase(pin);
|
||||||
|
if (exception->breakPath())
|
||||||
|
path_delay_internal_to_break_.erase(pin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3998,9 +4017,15 @@ Sdc::pathDelayTo(const Pin *pin)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Sdc::isPathDelayInternalEndpoint(const Pin *pin) const
|
Sdc::isPathDelayInternalTo(const Pin *pin) const
|
||||||
{
|
{
|
||||||
return path_delay_internal_endpoints_.hasKey(pin);
|
return path_delay_internal_to_.hasKey(pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Sdc::isPathDelayInternalToBreak(const Pin *pin) const
|
||||||
|
{
|
||||||
|
return path_delay_internal_to_break_.hasKey(pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
@ -4168,8 +4193,8 @@ Sdc::addException(ExceptionPath *exception)
|
||||||
exception->asString(network_));
|
exception->asString(network_));
|
||||||
|
|
||||||
if (exception->isPathDelay()) {
|
if (exception->isPathDelay()) {
|
||||||
recordPathDelayInternalStartpoints(exception);
|
recordPathDelayInternalFrom(exception);
|
||||||
recordPathDelayInternalEndpoints(exception);
|
recordPathDelayInternalTo(exception);
|
||||||
if (exception->to() == nullptr)
|
if (exception->to() == nullptr)
|
||||||
path_delays_without_to_ = true;
|
path_delays_without_to_ = true;
|
||||||
}
|
}
|
||||||
|
|
@ -4814,8 +4839,10 @@ Sdc::deleteExceptions()
|
||||||
first_thru_net_exceptions_.deleteContentsClear();
|
first_thru_net_exceptions_.deleteContentsClear();
|
||||||
first_thru_edge_exceptions_.deleteContentsClear();
|
first_thru_edge_exceptions_.deleteContentsClear();
|
||||||
first_thru_edge_exceptions_.clear();
|
first_thru_edge_exceptions_.clear();
|
||||||
path_delay_internal_startpoints_.clear();
|
path_delay_internal_from_.clear();
|
||||||
path_delay_internal_endpoints_.clear();
|
path_delay_internal_from_break_.clear();
|
||||||
|
path_delay_internal_to_.clear();
|
||||||
|
path_delay_internal_to_break_.clear();
|
||||||
|
|
||||||
deleteExceptionPtHashMapSets(exception_merge_hash_);
|
deleteExceptionPtHashMapSets(exception_merge_hash_);
|
||||||
exception_merge_hash_.clear();
|
exception_merge_hash_.clear();
|
||||||
|
|
@ -5097,8 +5124,8 @@ Sdc::resetPath(ExceptionFrom *from,
|
||||||
while (expand_iter.hasNext()) {
|
while (expand_iter.hasNext()) {
|
||||||
ExceptionPath *expand = expand_iter.next();
|
ExceptionPath *expand = expand_iter.next();
|
||||||
if (expand->resetMatch(from, thrus, to, min_max, network_)) {
|
if (expand->resetMatch(from, thrus, to, min_max, network_)) {
|
||||||
unrecordPathDelayInternalStartpoints(expand->from());
|
unrecordPathDelayInternalFrom(expand);
|
||||||
unrecordPathDelayInternalEndpoints(expand);
|
unrecordPathDelayInternalTo(expand);
|
||||||
delete expand;
|
delete expand;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -696,11 +696,13 @@ make_path_delay(ExceptionFrom *from,
|
||||||
ExceptionTo *to,
|
ExceptionTo *to,
|
||||||
const MinMax *min_max,
|
const MinMax *min_max,
|
||||||
bool ignore_clk_latency,
|
bool ignore_clk_latency,
|
||||||
|
bool break_path,
|
||||||
float delay,
|
float delay,
|
||||||
const char *comment)
|
const char *comment)
|
||||||
{
|
{
|
||||||
Sta::sta()->makePathDelay(from, thrus, to, min_max,
|
Sta::sta()->makePathDelay(from, thrus, to, min_max,
|
||||||
ignore_clk_latency, delay, comment);
|
ignore_clk_latency, break_path,
|
||||||
|
delay, comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
13
sdc/Sdc.tcl
13
sdc/Sdc.tcl
|
|
@ -2335,7 +2335,8 @@ proc unset_input_delay { args } {
|
||||||
################################################################
|
################################################################
|
||||||
|
|
||||||
define_cmd_args "set_max_delay" \
|
define_cmd_args "set_max_delay" \
|
||||||
{[-rise] [-fall] [-ignore_clock_latency] [-reset_path] [-comment comment]\
|
{[-rise] [-fall] [-ignore_clock_latency] [-reset_path]\
|
||||||
|
[-probe] [-comment comment]\
|
||||||
[-from from_list] [-rise_from from_list] [-fall_from from_list]\
|
[-from from_list] [-rise_from from_list] [-fall_from from_list]\
|
||||||
[-through through_list] [-rise_through through_list]\
|
[-through through_list] [-rise_through through_list]\
|
||||||
[-fall_through through_list]\
|
[-fall_through through_list]\
|
||||||
|
|
@ -2348,7 +2349,7 @@ proc set_max_delay { args } {
|
||||||
proc set_path_delay { cmd args min_max } {
|
proc set_path_delay { cmd args min_max } {
|
||||||
parse_key_args $cmd args \
|
parse_key_args $cmd args \
|
||||||
keys {-from -rise_from -fall_from -to -rise_to -fall_to -comment} \
|
keys {-from -rise_from -fall_from -to -rise_to -fall_to -comment} \
|
||||||
flags {-rise -fall -ignore_clock_latency -reset_path} 0
|
flags {-rise -fall -ignore_clock_latency -reset_path -probe} 0
|
||||||
|
|
||||||
set arg_error 0
|
set arg_error 0
|
||||||
set from [parse_from_arg keys arg_error]
|
set from [parse_from_arg keys arg_error]
|
||||||
|
|
@ -2370,6 +2371,7 @@ proc set_path_delay { cmd args min_max } {
|
||||||
}
|
}
|
||||||
|
|
||||||
set ignore_clk_latency [info exists flags(-ignore_clock_latency)]
|
set ignore_clk_latency [info exists flags(-ignore_clock_latency)]
|
||||||
|
set break_path [expr {![info exists flags(-probe)]}]
|
||||||
|
|
||||||
if [info exists flags(-reset_path)] {
|
if [info exists flags(-reset_path)] {
|
||||||
reset_path_cmd $from $thrus $to "all"
|
reset_path_cmd $from $thrus $to "all"
|
||||||
|
|
@ -2377,8 +2379,8 @@ proc set_path_delay { cmd args min_max } {
|
||||||
|
|
||||||
set comment [parse_comment_key keys]
|
set comment [parse_comment_key keys]
|
||||||
|
|
||||||
make_path_delay $from $thrus $to $min_max $ignore_clk_latency \
|
make_path_delay $from $thrus $to $min_max \
|
||||||
$delay $comment
|
$ignore_clk_latency $break_path $delay $comment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2404,7 +2406,8 @@ proc set_max_time_borrow { limit objects } {
|
||||||
################################################################
|
################################################################
|
||||||
|
|
||||||
define_cmd_args "set_min_delay" \
|
define_cmd_args "set_min_delay" \
|
||||||
{[-rise] [-fall] [-ignore_clock_latency] [-reset_path] [-comment comment]\
|
{[-rise] [-fall] [-ignore_clock_latency] [-reset_path]\
|
||||||
|
[-probe] [-comment comment]\
|
||||||
[-from from_list] [-rise_from from_list] [-fall_from from_list]\
|
[-from from_list] [-rise_from from_list] [-fall_from from_list]\
|
||||||
[-through through_list] [-rise_through through_list]\
|
[-through through_list] [-rise_through through_list]\
|
||||||
[-fall_through through_list]\
|
[-fall_through through_list]\
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ EvalPred::searchTo(const Vertex *to_vertex)
|
||||||
const Pin *pin = to_vertex->pin();
|
const Pin *pin = to_vertex->pin();
|
||||||
return SearchPred0::searchTo(to_vertex)
|
return SearchPred0::searchTo(to_vertex)
|
||||||
&& !(sdc->isLeafPinClock(pin)
|
&& !(sdc->isLeafPinClock(pin)
|
||||||
&& !sdc->isPathDelayInternalEndpoint(pin));
|
&& !sdc->isPathDelayInternalTo(pin));
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
@ -979,7 +979,7 @@ Search::visitStartpoints(VertexVisitor *visitor)
|
||||||
for (Vertex *vertex : *graph_->regClkVertices())
|
for (Vertex *vertex : *graph_->regClkVertices())
|
||||||
visitor->visit(vertex);
|
visitor->visit(vertex);
|
||||||
|
|
||||||
const PinSet &startpoints = sdc_->pathDelayInternalStartpoints();
|
const PinSet &startpoints = sdc_->pathDelayInternalFrom();
|
||||||
if (!startpoints.empty()) {
|
if (!startpoints.empty()) {
|
||||||
for (const Pin *pin : startpoints) {
|
for (const Pin *pin : startpoints) {
|
||||||
Vertex *vertex = graph_->pinDrvrVertex(pin);
|
Vertex *vertex = graph_->pinDrvrVertex(pin);
|
||||||
|
|
@ -995,7 +995,7 @@ Search::visitEndpoints(VertexVisitor *visitor)
|
||||||
Pin *pin = end->pin();
|
Pin *pin = end->pin();
|
||||||
// Filter register clock pins (fails on set_max_delay -from clk_src).
|
// Filter register clock pins (fails on set_max_delay -from clk_src).
|
||||||
if (!network_->isRegClkPin(pin)
|
if (!network_->isRegClkPin(pin)
|
||||||
|| sdc_->isPathDelayInternalEndpoint(pin))
|
|| sdc_->isPathDelayInternalTo(pin))
|
||||||
visitor->visit(end);
|
visitor->visit(end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1163,6 +1163,8 @@ ArrivalVisitor::visit(Vertex *vertex)
|
||||||
&& !has_fanin_one_)
|
&& !has_fanin_one_)
|
||||||
tag_bldr_no_crpr_->init(vertex);
|
tag_bldr_no_crpr_->init(vertex);
|
||||||
|
|
||||||
|
// Fanin paths are broken by path delays internal pin startpoints.
|
||||||
|
if (!sdc_->isPathDelayInternalFromBreak(pin)) {
|
||||||
visitFaninPaths(vertex);
|
visitFaninPaths(vertex);
|
||||||
if (crpr_active_
|
if (crpr_active_
|
||||||
&& search_->crprPathPruningEnabled()
|
&& search_->crprPathPruningEnabled()
|
||||||
|
|
@ -1171,13 +1173,14 @@ ArrivalVisitor::visit(Vertex *vertex)
|
||||||
&& tag_bldr_->hasPropagatedClk()
|
&& tag_bldr_->hasPropagatedClk()
|
||||||
&& !has_fanin_one_)
|
&& !has_fanin_one_)
|
||||||
pruneCrprArrivals();
|
pruneCrprArrivals();
|
||||||
|
}
|
||||||
|
|
||||||
// Insert paths that originate here.
|
// Insert paths that originate here.
|
||||||
if (!network_->isTopLevelPort(pin)
|
if (!network_->isTopLevelPort(pin)
|
||||||
&& sdc_->hasInputDelay(pin))
|
&& sdc_->hasInputDelay(pin))
|
||||||
// set_input_delay on internal pin.
|
// set_input_delay on internal pin.
|
||||||
search_->seedInputSegmentArrival(pin, vertex, tag_bldr_);
|
search_->seedInputSegmentArrival(pin, vertex, tag_bldr_);
|
||||||
if (sdc_->isPathDelayInternalStartpoint(pin))
|
if (sdc_->isPathDelayInternalFrom(pin))
|
||||||
// set_min/max_delay -from internal pin.
|
// set_min/max_delay -from internal pin.
|
||||||
search_->makeUnclkedPaths(vertex, false, true, tag_bldr_);
|
search_->makeUnclkedPaths(vertex, false, true, tag_bldr_);
|
||||||
if (sdc_->isLeafPinClock(pin))
|
if (sdc_->isLeafPinClock(pin))
|
||||||
|
|
@ -2263,12 +2266,15 @@ PathVisitor::visitFromPath(const Pin *from_pin,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if (!(sdc_->isPathDelayInternalFromBreak(to_pin)
|
||||||
|
|| sdc_->isPathDelayInternalToBreak(from_pin))) {
|
||||||
arc_delay = search_->deratedDelay(from_vertex, arc, edge, false, path_ap);
|
arc_delay = search_->deratedDelay(from_vertex, arc, edge, false, path_ap);
|
||||||
if (!delayInf(arc_delay)) {
|
if (!delayInf(arc_delay)) {
|
||||||
to_arrival = from_arrival + arc_delay;
|
to_arrival = from_arrival + arc_delay;
|
||||||
to_tag = search_->thruTag(from_tag, edge, to_rf, min_max, path_ap);
|
to_tag = search_->thruTag(from_tag, edge, to_rf, min_max, path_ap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (to_tag)
|
if (to_tag)
|
||||||
return visitFromToPath(from_pin, from_vertex, from_rf,
|
return visitFromToPath(from_pin, from_vertex, from_rf,
|
||||||
from_tag, from_path, from_arrival,
|
from_tag, from_path, from_arrival,
|
||||||
|
|
@ -2607,7 +2613,7 @@ Search::mutateTag(Tag *from_tag,
|
||||||
if (from_states) {
|
if (from_states) {
|
||||||
// Check for state changes in from_tag (but postpone copying state set).
|
// Check for state changes in from_tag (but postpone copying state set).
|
||||||
bool state_change = false;
|
bool state_change = false;
|
||||||
for (auto state : *from_states) {
|
for (ExceptionState *state : *from_states) {
|
||||||
ExceptionPath *exception = state->exception();
|
ExceptionPath *exception = state->exception();
|
||||||
// One edge may traverse multiple hierarchical thru pins.
|
// One edge may traverse multiple hierarchical thru pins.
|
||||||
while (state->matchesNextThru(from_pin,to_pin,to_rf,min_max,network_)) {
|
while (state->matchesNextThru(from_pin,to_pin,to_rf,min_max,network_)) {
|
||||||
|
|
@ -3294,7 +3300,7 @@ Search::isEndpoint(Vertex *vertex,
|
||||||
|| (variables_->gatedClkChecksEnabled()
|
|| (variables_->gatedClkChecksEnabled()
|
||||||
&& gated_clk_->isGatedClkEnable(vertex))
|
&& gated_clk_->isGatedClkEnable(vertex))
|
||||||
|| vertex->isConstrained()
|
|| vertex->isConstrained()
|
||||||
|| sdc_->isPathDelayInternalEndpoint(pin)
|
|| sdc_->isPathDelayInternalTo(pin)
|
||||||
|| !hasFanout(vertex, pred, graph_)
|
|| !hasFanout(vertex, pred, graph_)
|
||||||
// Unconstrained paths at register clk pins.
|
// Unconstrained paths at register clk pins.
|
||||||
|| (unconstrained_paths_
|
|| (unconstrained_paths_
|
||||||
|
|
|
||||||
|
|
@ -1965,12 +1965,13 @@ Sta::makePathDelay(ExceptionFrom *from,
|
||||||
ExceptionTo *to,
|
ExceptionTo *to,
|
||||||
const MinMax *min_max,
|
const MinMax *min_max,
|
||||||
bool ignore_clk_latency,
|
bool ignore_clk_latency,
|
||||||
|
bool break_path,
|
||||||
float delay,
|
float delay,
|
||||||
const char *comment)
|
const char *comment)
|
||||||
{
|
{
|
||||||
sdc_->makePathDelay(from, thrus, to, min_max,
|
sdc_->makePathDelay(from, thrus, to, min_max,
|
||||||
ignore_clk_latency, delay,
|
ignore_clk_latency, break_path,
|
||||||
comment);
|
delay, comment);
|
||||||
search_->endpointsInvalid();
|
search_->endpointsInvalid();
|
||||||
search_->arrivalsInvalid();
|
search_->arrivalsInvalid();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue