set_min/max_delay -from reg/D startpoint warning resolves #265
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
1c09954518
commit
606c666180
|
|
@ -489,7 +489,6 @@ public:
|
|||
// timing arcs.
|
||||
bool hasInferedRegTimingArcs() const { return has_infered_reg_timing_arcs_; }
|
||||
TestCell *testCell() const { return test_cell_; }
|
||||
bool isLatchData(LibertyPort *port);
|
||||
void latchEnable(const TimingArcSet *arc_set,
|
||||
// Return values.
|
||||
const LibertyPort *&enable_port,
|
||||
|
|
@ -803,6 +802,10 @@ public:
|
|||
// Has register/latch rise/fall edges from pin.
|
||||
bool isRegClk() const { return is_reg_clk_; }
|
||||
void setIsRegClk(bool is_clk);
|
||||
bool isRegOutput() const { return is_reg_output_; }
|
||||
void setIsRegOutput(bool is_reg_out);
|
||||
bool isLatchData() const { return is_latch_data_; }
|
||||
void setIsLatchData(bool is_latch_data);
|
||||
// Is the clock for timing checks.
|
||||
bool isCheckClk() const { return is_check_clk_; }
|
||||
void setIsCheckClk(bool is_clk);
|
||||
|
|
@ -899,6 +902,8 @@ protected:
|
|||
bool min_period_exists_:1;
|
||||
bool is_clk_:1;
|
||||
bool is_reg_clk_:1;
|
||||
bool is_reg_output_:1;
|
||||
bool is_latch_data_: 1;
|
||||
bool is_check_clk_:1;
|
||||
bool is_clk_gate_clk_:1;
|
||||
bool is_clk_gate_enable_:1;
|
||||
|
|
|
|||
|
|
@ -771,6 +771,7 @@ public:
|
|||
ClockSet *from_clks,
|
||||
InstanceSet *from_insts,
|
||||
const RiseFallBoth *from_rf);
|
||||
bool isExceptionStartpoint(const Pin *pin) const;
|
||||
// Make an exception -through specification.
|
||||
ExceptionThru *makeExceptionThru(PinSet *pins,
|
||||
NetSet *nets,
|
||||
|
|
@ -972,10 +973,11 @@ public:
|
|||
ExceptionStateSet *&states) const;
|
||||
// Return hierarchical -thru exceptions that start between
|
||||
// from_pin and to_pin.
|
||||
ExceptionStateSet *exceptionThruStates(const Pin *from_pin,
|
||||
void exceptionThruStates(const Pin *from_pin,
|
||||
const Pin *to_pin,
|
||||
const RiseFall *to_rf,
|
||||
const MinMax *min_max) const;
|
||||
const MinMax *min_max,
|
||||
ExceptionStateSet *&states) const;
|
||||
// Find the highest priority exception with first exception pt at
|
||||
// pin/clk end.
|
||||
void exceptionTo(ExceptionPathType type,
|
||||
|
|
|
|||
|
|
@ -531,7 +531,6 @@ public:
|
|||
void checkExceptionFromPins(ExceptionFrom *from,
|
||||
const char *file,
|
||||
int line) const;
|
||||
bool exceptionFromInvalid(const Pin *pin) const;
|
||||
void deleteExceptionFrom(ExceptionFrom *from);
|
||||
// Make an exception -through specification.
|
||||
ExceptionThru *makeExceptionThru(PinSet *pins,
|
||||
|
|
|
|||
|
|
@ -1244,10 +1244,13 @@ LibertyCell::addTimingArcSet(TimingArcSet *arc_set)
|
|||
timing_arc_sets_.push_back(arc_set);
|
||||
|
||||
LibertyPort *from = arc_set->from();
|
||||
LibertyPort *to = arc_set->to();
|
||||
const TimingRole *role = arc_set->role();
|
||||
if (role == TimingRole::regClkToQ()
|
||||
|| role == TimingRole::latchEnToQ())
|
||||
|| role == TimingRole::latchEnToQ()) {
|
||||
from->setIsRegClk(true);
|
||||
to->setIsRegOutput(true);
|
||||
}
|
||||
if (role->isTimingCheck())
|
||||
from->setIsCheckClk(true);
|
||||
return set_index;
|
||||
|
|
@ -1881,7 +1884,7 @@ LibertyCell::makeLatchEnable(LibertyPort *d,
|
|||
latch_enables_.push_back(latch_enable);
|
||||
latch_d_to_q_map_[d_to_q] = latch_enable;
|
||||
latch_check_map_[setup_check] = latch_enable;
|
||||
latch_data_ports_.insert(d);
|
||||
d->setIsLatchData(true);
|
||||
debugPrint(debug, "liberty_latch", 1,
|
||||
"latch %s -> %s | %s %s -> %s | %s %s -> %s setup",
|
||||
d->name(),
|
||||
|
|
@ -1933,12 +1936,6 @@ LibertyCell::inferLatchRoles(Report *report,
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
LibertyCell::isLatchData(LibertyPort *port)
|
||||
{
|
||||
return latch_data_ports_.hasKey(port);
|
||||
}
|
||||
|
||||
void
|
||||
LibertyCell::latchEnable(const TimingArcSet *d_to_q_set,
|
||||
// Return values.
|
||||
|
|
@ -2100,6 +2097,8 @@ LibertyPort::LibertyPort(LibertyCell *cell,
|
|||
min_period_exists_(false),
|
||||
is_clk_(false),
|
||||
is_reg_clk_(false),
|
||||
is_reg_output_(false),
|
||||
is_latch_data_(false),
|
||||
is_check_clk_(false),
|
||||
is_clk_gate_clk_(false),
|
||||
is_clk_gate_enable_(false),
|
||||
|
|
@ -2547,6 +2546,18 @@ LibertyPort::setIsRegClk(bool is_clk)
|
|||
is_reg_clk_ = is_clk;
|
||||
}
|
||||
|
||||
void
|
||||
LibertyPort::setIsRegOutput(bool is_reg_out)
|
||||
{
|
||||
is_reg_output_ = is_reg_out;
|
||||
}
|
||||
|
||||
void
|
||||
LibertyPort::setIsLatchData(bool is_latch_data)
|
||||
{
|
||||
is_latch_data_ = is_latch_data;
|
||||
}
|
||||
|
||||
void
|
||||
LibertyPort::setIsCheckClk(bool is_clk)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -655,7 +655,7 @@ Network::isLatchData(const Pin *pin) const
|
|||
{
|
||||
LibertyPort *port = libertyPort(pin);
|
||||
if (port)
|
||||
return port->libertyCell()->isLatchData(port);
|
||||
return port->isLatchData();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
28
sdc/Sdc.cc
28
sdc/Sdc.cc
|
|
@ -3914,8 +3914,7 @@ Sdc::recordPathDelayInternalFrom(ExceptionPath *exception)
|
|||
if (from
|
||||
&& from->hasPins()) {
|
||||
for (const Pin *pin : *from->pins()) {
|
||||
if (!(network_->isRegClkPin(pin)
|
||||
|| network_->isTopLevelPort(pin))) {
|
||||
if (!isExceptionStartpoint(pin)) {
|
||||
path_delay_internal_from_.insert(pin);
|
||||
if (exception->breakPath())
|
||||
path_delay_internal_from_break_.insert(pin);
|
||||
|
|
@ -3932,8 +3931,7 @@ Sdc::unrecordPathDelayInternalFrom(ExceptionPath *exception)
|
|||
&& from->hasPins()
|
||||
&& !path_delay_internal_from_.empty()) {
|
||||
for (const Pin *pin : *from->pins()) {
|
||||
if (!(network_->isRegClkPin(pin)
|
||||
|| network_->isTopLevelPort(pin))
|
||||
if (!isExceptionStartpoint(pin)
|
||||
&& !pathDelayFrom(pin)) {
|
||||
path_delay_internal_from_.erase(pin);
|
||||
if (exception->breakPath())
|
||||
|
|
@ -3943,6 +3941,21 @@ 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)
|
||||
{
|
||||
|
|
@ -5304,13 +5317,13 @@ Sdc::filterRegQStates(const Pin *to_pin,
|
|||
}
|
||||
}
|
||||
|
||||
ExceptionStateSet *
|
||||
void
|
||||
Sdc::exceptionThruStates(const Pin *from_pin,
|
||||
const Pin *to_pin,
|
||||
const RiseFall *to_rf,
|
||||
const MinMax *min_max) const
|
||||
const MinMax *min_max,
|
||||
ExceptionStateSet *&states) const
|
||||
{
|
||||
ExceptionStateSet *states = nullptr;
|
||||
exceptionThruStates(first_thru_pin_exceptions_.findKey(to_pin),
|
||||
to_rf, min_max, states);
|
||||
if (!first_thru_edge_exceptions_.empty()) {
|
||||
|
|
@ -5325,7 +5338,6 @@ Sdc::exceptionThruStates(const Pin *from_pin,
|
|||
exceptionThruStates(first_thru_inst_exceptions_.findKey(to_inst),
|
||||
to_rf, min_max, states);
|
||||
}
|
||||
return states;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -2355,6 +2355,7 @@ proc set_path_delay { cmd args min_max } {
|
|||
set from [parse_from_arg keys arg_error]
|
||||
set thrus [parse_thrus_arg args arg_error]
|
||||
set to [parse_to_arg keys flags arg_error]
|
||||
check_exception_pins $from $to
|
||||
if { $arg_error } {
|
||||
delete_from_thrus_to $from $thrus $to
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -980,13 +980,11 @@ Search::visitStartpoints(VertexVisitor *visitor)
|
|||
visitor->visit(vertex);
|
||||
|
||||
const PinSet &startpoints = sdc_->pathDelayInternalFrom();
|
||||
if (!startpoints.empty()) {
|
||||
for (const Pin *pin : startpoints) {
|
||||
Vertex *vertex = graph_->pinDrvrVertex(pin);
|
||||
visitor->visit(vertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Search::visitEndpoints(VertexVisitor *visitor)
|
||||
|
|
@ -2176,7 +2174,6 @@ PathVisitor::visitFromPath(const Pin *from_pin,
|
|||
to_tag = search_->thruClkTag(from_path, from_vertex, from_tag, true,
|
||||
edge, to_rf, arc_delay_min_max_eq,
|
||||
min_max, path_ap);
|
||||
if (to_tag)
|
||||
to_arrival = from_arrival + arc_delay;
|
||||
}
|
||||
}
|
||||
|
|
@ -2272,11 +2269,10 @@ PathVisitor::visitFromPath(const Pin *from_pin,
|
|||
else {
|
||||
if (!(sdc_->isPathDelayInternalFromBreak(to_pin)
|
||||
|| sdc_->isPathDelayInternalToBreak(from_pin))) {
|
||||
arc_delay = search_->deratedDelay(from_vertex, arc, edge, false, path_ap);
|
||||
if (!delayInf(arc_delay)) {
|
||||
to_arrival = from_arrival + arc_delay;
|
||||
to_tag = search_->thruTag(from_tag, edge, to_rf, min_max, path_ap);
|
||||
}
|
||||
arc_delay = search_->deratedDelay(from_vertex, arc, edge, false, path_ap);
|
||||
if (!delayInf(arc_delay))
|
||||
to_arrival = from_arrival + arc_delay;
|
||||
}
|
||||
}
|
||||
if (to_tag)
|
||||
|
|
@ -2643,7 +2639,7 @@ Search::mutateTag(Tag *from_tag,
|
|||
|
||||
// Kill path delay tags past the -to pin.
|
||||
if ((exception->isPathDelay()
|
||||
&& sdc_->isCompleteTo(state, from_pin, from_rf, min_max))
|
||||
&& sdc_->isCompleteTo(state, to_pin, to_rf, min_max))
|
||||
// Kill loop tags at register clock pins.
|
||||
|| (exception->isLoop()
|
||||
&& to_is_reg_clk)) {
|
||||
|
|
@ -2653,7 +2649,7 @@ Search::mutateTag(Tag *from_tag,
|
|||
}
|
||||
|
||||
// Get the set of -thru exceptions starting at to_pin/edge.
|
||||
new_states = sdc_->exceptionThruStates(from_pin, to_pin, to_rf, min_max);
|
||||
sdc_->exceptionThruStates(from_pin, to_pin, to_rf, min_max, new_states);
|
||||
if (new_states || state_change) {
|
||||
// Second pass to apply state changes and add updated existing
|
||||
// states to new states.
|
||||
|
|
@ -2691,7 +2687,7 @@ Search::mutateTag(Tag *from_tag,
|
|||
}
|
||||
else
|
||||
// Get the set of -thru exceptions starting at to_pin/edge.
|
||||
new_states = sdc_->exceptionThruStates(from_pin, to_pin, to_rf, min_max);
|
||||
sdc_->exceptionThruStates(from_pin, to_pin, to_rf, min_max, new_states);
|
||||
|
||||
if (new_states)
|
||||
return findTag(to_rf, path_ap, to_clk_info, to_is_clk,
|
||||
|
|
|
|||
|
|
@ -2027,7 +2027,7 @@ Sta::checkExceptionFromPins(ExceptionFrom *from,
|
|||
PinSet::ConstIterator pin_iter(from->pins());
|
||||
while (pin_iter.hasNext()) {
|
||||
const Pin *pin = pin_iter.next();
|
||||
if (exceptionFromInvalid(pin)) {
|
||||
if (!sdc_->isExceptionStartpoint(pin)) {
|
||||
if (line)
|
||||
report_->fileWarn(1554, file, line, "'%s' is not a valid start point.",
|
||||
cmd_network_->pathName(pin));
|
||||
|
|
@ -2039,24 +2039,6 @@ Sta::checkExceptionFromPins(ExceptionFrom *from,
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Sta::exceptionFromInvalid(const Pin *pin) const
|
||||
{
|
||||
Net *net = network_->net(pin);
|
||||
// Floating pins are invalid.
|
||||
return (net == nullptr
|
||||
&& !network_->isTopLevelPort(pin))
|
||||
|| (net
|
||||
// Pins connected to power/ground are invalid.
|
||||
&& (network_->isPower(net)
|
||||
|| network_->isGround(net)))
|
||||
|| !((network_->isTopLevelPort(pin)
|
||||
&& network_->direction(pin)->isAnyInput())
|
||||
|| network_->isRegClkPin(pin)
|
||||
|| network_->isLatchData(pin)
|
||||
|| network_->direction(pin)->isInternal());
|
||||
}
|
||||
|
||||
void
|
||||
Sta::deleteExceptionFrom(ExceptionFrom *from)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue