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