set_min/max_delay illegal endpoint warning

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2025-07-04 16:43:21 -07:00
parent 6df4cdc794
commit 1c45b89879
5 changed files with 40 additions and 41 deletions

View File

@ -186,7 +186,7 @@ proc edge_disable_reason { edge } {
}
if { [$edge is_disabled_preset_clear] } {
if { $disables != "" } { append disables ", " }
append disables "timing_enable_preset_clear_arcs"
append disables "sta_preset_clear_arcs_enabled"
}
return $disables
}

View File

@ -777,7 +777,7 @@ public:
NetSet *nets,
InstanceSet *insts,
const RiseFallBoth *rf);
bool exceptionToInvalid(const Pin *pin);
bool isExceptionEndpoint(const Pin *pin);
// Make an exception -to specification.
ExceptionTo *makeExceptionTo(PinSet *pins,
ClockSet *clks,

View File

@ -3799,6 +3799,22 @@ Sdc::makeExceptionFrom(PinSet *from_pins,
return nullptr;
}
bool
Sdc::isExceptionStartpoint(const Pin *pin) const
{
Net *net = network_->net(pin);
const LibertyPort *port = network_->libertyPort(pin);
return ((network_->isTopLevelPort(pin)
&& network_->direction(pin)->isAnyInput())
|| (port && port->isRegClk())
|| (port && port->isLatchData()))
// Pins connected to power/ground are invalid.
&& !(net
&& (network_->isPower(net)
|| network_->isGround(net)))
&& !network_->isHierarchical(pin);
}
ExceptionThru *
Sdc::makeExceptionThru(PinSet *pins,
NetSet *nets,
@ -3833,31 +3849,31 @@ Sdc::makeExceptionTo(PinSet *pins,
// Valid endpoints include gated clock enables which are not
// known until clock arrivals are determined.
bool
Sdc::exceptionToInvalid(const Pin *pin)
Sdc::isExceptionEndpoint(const Pin *pin)
{
Net *net = network_->net(pin);
// Floating pins are invalid.
if ((net == nullptr
&& !(network_->isTopLevelPort(pin)
|| network_->direction(pin)->isInternal()))
|| (net
// Pins connected to power/ground are invalid.
&& (network_->isPower(net)
|| network_->isGround(net)))
// Hierarchical pins are invalid.
|| network_->isHierarchical(pin))
return true;
// Register/latch Q pins are invalid.
LibertyPort *port = network_->libertyPort(pin);
bool has_checks = false;
const LibertyPort *port = network_->libertyPort(pin);
if (port) {
// Look for timing checks to the pin witihout using the graph because
// it may not exist.
LibertyCell *cell = port->libertyCell();
for (TimingArcSet *arc_set : cell->timingArcSets(nullptr, port)) {
const TimingRole *role = arc_set->role();
if (role->genericRole() == TimingRole::regClkToQ())
return true;
if (arc_set->role()->isTimingCheck()) {
has_checks = true;
break;
}
}
}
return false;
return ((network_->isTopLevelPort(pin)
&& network_->direction(pin)->isAnyOutput())
|| has_checks
|| (port && port->isLatchData()))
// Pins connected to power/ground are invalid.
&& !(net
&& (network_->isPower(net)
|| network_->isGround(net)))
&& !network_->isHierarchical(pin);
}
void
@ -3941,21 +3957,6 @@ Sdc::unrecordPathDelayInternalFrom(ExceptionPath *exception)
}
}
bool
Sdc::isExceptionStartpoint(const Pin *pin) const
{
Net *net = network_->net(pin);
const LibertyPort *port = network_->libertyPort(pin);
return ((network_->isTopLevelPort(pin)
&& network_->direction(pin)->isAnyInput())
|| (port && port->isRegClk())
|| (port && port->isLatchData()))
// Pins connected to power/ground are invalid.
&& !(net
&& (network_->isPower(net)
|| network_->isGround(net)));
}
bool
Sdc::pathDelayFrom(const Pin *pin)
{

View File

@ -2085,7 +2085,7 @@ Sta::checkExceptionToPins(ExceptionTo *to,
PinSet::Iterator pin_iter(to->pins());
while (pin_iter.hasNext()) {
const Pin *pin = pin_iter.next();
if (sdc_->exceptionToInvalid(pin)) {
if (!sdc_->isExceptionEndpoint(pin)) {
if (line)
report_->fileWarn(1551, file, line, "'%s' is not a valid endpoint.",
cmd_network_->pathName(pin));

View File

@ -113,9 +113,8 @@ VisitPathEnds::visitClkedPathEnds(const Pin *pin,
else if (vertex->hasChecks())
visitCheckEnd(pin, vertex, path, end_rf, path_ap, filtered, visitor,
is_constrained);
else if (!sdc_->exceptionToInvalid(pin)
&& (!filtered
|| search_->matchesFilter(path, nullptr))) {
else if (!filtered
|| search_->matchesFilter(path, nullptr)) {
PathDelay *path_delay = pathDelayTo(path, pin, end_rf, path_min_max);
if (path_delay) {
PathEndPathDelay path_end(path_delay, path, this);
@ -231,8 +230,7 @@ VisitPathEnds::visitCheckEnd(const Pin *pin,
}
}
}
if (!check_clked
&& !sdc_->exceptionToInvalid(pin))
if (!check_clked)
visitCheckEndUnclked(pin, vertex, path, end_rf, path_ap, filtered,
visitor, is_constrained);
}