Merge remote-tracking branch 'upstream/master' into sta_latest_0618
This commit is contained in:
commit
5dae3933dc
|
|
@ -107,8 +107,7 @@ DcalcPred::searchThru(Edge *edge,
|
|||
|| edge->isDisabledLoop()
|
||||
|| sdc->isDisabledConstraint(edge)
|
||||
|| sdc->isDisabledCondDefault(edge)
|
||||
|| (edge->isBidirectInstPath()
|
||||
&& !variables->bidirectInstPathsEnabled()));
|
||||
|| sta_->isDisabledBidirectInstPath(edge));
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -1011,13 +1010,13 @@ GraphDelayCalc::findDriverEdgeDelays(Vertex *drvr_vertex,
|
|||
if (search_pred_->searchFrom(from_vertex, mode)
|
||||
&& search_pred_->searchThru(edge, mode)) {
|
||||
for (const MinMax *min_max : MinMax::range()) {
|
||||
for (const TimingArc *arc : arc_set->arcs()) {
|
||||
delay_changed |= findDriverArcDelays(drvr_vertex, multi_drvr, edge, arc,
|
||||
for (const TimingArc *arc : arc_set->arcs()) {
|
||||
delay_changed |= findDriverArcDelays(drvr_vertex, multi_drvr, edge, arc,
|
||||
scene, min_max, arc_delay_calc,
|
||||
load_pin_index_map);
|
||||
delay_exists[arc->toEdge()->asRiseFall()->index()] = true;
|
||||
}
|
||||
}
|
||||
load_pin_index_map);
|
||||
delay_exists[arc->toEdge()->asRiseFall()->index()] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (delay_changed && observer_) {
|
||||
|
|
|
|||
|
|
@ -250,6 +250,13 @@ Graph::makeInstDrvrWireEdges(const Instance *inst,
|
|||
if (network_->isDriver(pin)
|
||||
&& !visited_drvrs.contains(pin))
|
||||
makeWireEdgesFromPin(pin, visited_drvrs);
|
||||
if (network_->isTopInstance(inst)
|
||||
&& network_->direction(pin)->isBidirect()) {
|
||||
Vertex *bidir_load, *bidir_drvr;
|
||||
pinVertices(pin, bidir_load, bidir_drvr);
|
||||
Edge *edge = makeEdge(bidir_load, bidir_drvr, TimingArcSet::wireTimingArcSet());
|
||||
edge->setIsBidirectPortPath(true);
|
||||
}
|
||||
}
|
||||
delete pin_iter;
|
||||
}
|
||||
|
|
@ -1211,6 +1218,7 @@ Edge::init(VertexId from,
|
|||
vertex_out_prev_ = edge_id_null;
|
||||
is_bidirect_inst_path_ = false;
|
||||
is_bidirect_net_path_ = false;
|
||||
is_bidirect_port_path_ = false;
|
||||
|
||||
arc_delays_ = nullptr;
|
||||
arc_delay_annotated_is_bits_ = true;
|
||||
|
|
@ -1368,6 +1376,12 @@ Edge::setIsBidirectNetPath(bool is_bidir)
|
|||
is_bidirect_net_path_ = is_bidir;
|
||||
}
|
||||
|
||||
void
|
||||
Edge::setIsBidirectPortPath(bool is_bidir)
|
||||
{
|
||||
is_bidirect_port_path_ = is_bidir;
|
||||
}
|
||||
|
||||
void
|
||||
Edge::setHasSimSense(bool has_sense)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@ remove_delay_slew_annotations()
|
|||
Pin *pin() { return self->pin(); }
|
||||
bool is_bidirect_driver() { return self->isBidirectDriver(); }
|
||||
int level() { return Sta::sta()->vertexLevel(self); }
|
||||
bool is_root() { return self->isRoot(); }
|
||||
int tag_group_index() { return self->tagGroupIndex(); }
|
||||
|
||||
float
|
||||
|
|
|
|||
|
|
@ -364,6 +364,9 @@ public:
|
|||
void setIsBidirectInstPath(bool is_bidir);
|
||||
bool isBidirectNetPath() const { return is_bidirect_net_path_; }
|
||||
void setIsBidirectNetPath(bool is_bidir);
|
||||
bool isBidirectPortPath() const { return is_bidirect_port_path_; }
|
||||
void setIsBidirectPortPath(bool is_bidir);
|
||||
|
||||
void removeDelayAnnotated();
|
||||
[[nodiscard]] bool hasSimSense() const { return has_sim_sense_; }
|
||||
void setHasSimSense(bool has_sense);
|
||||
|
|
@ -403,6 +406,8 @@ protected:
|
|||
bool delay_annotation_is_incremental_:1;
|
||||
bool is_bidirect_inst_path_:1;
|
||||
bool is_bidirect_net_path_:1;
|
||||
// Bidirect load -> driver edge.
|
||||
bool is_bidirect_port_path_:1;
|
||||
bool is_disabled_loop_:1;
|
||||
bool has_sim_sense_:1;
|
||||
bool has_disabled_cond_:1;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ public:
|
|||
const Pin *refPin() const { return ref_pin_; }
|
||||
void setRefPin(const Pin *ref_pin);
|
||||
const RiseFall *refTransition() const;
|
||||
bool refPinEdgesExist() const { return ref_pin_edges_exist_; }
|
||||
void setRefPinEdgesExist(bool exists);
|
||||
|
||||
protected:
|
||||
PortDelay(const Pin *pin,
|
||||
|
|
@ -62,6 +64,7 @@ protected:
|
|||
bool source_latency_included_{false};
|
||||
bool network_latency_included_{false};
|
||||
const Pin *ref_pin_{nullptr};
|
||||
bool ref_pin_edges_exist_{false};
|
||||
RiseFallMinMax delays_;
|
||||
PinSet leaf_pins_;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -576,6 +576,7 @@ public:
|
|||
const Clock *clk,
|
||||
const RiseFall *clk_rf,
|
||||
const MinMaxAll *min_max);
|
||||
void ensureInputDelayRefPinEdges();
|
||||
void setOutputDelay(const Pin *pin,
|
||||
const RiseFallBoth *rf,
|
||||
const Clock *clk,
|
||||
|
|
@ -806,7 +807,6 @@ public:
|
|||
const MinMaxAll *min_max);
|
||||
|
||||
// STA interface.
|
||||
InputDelaySet *refPinInputDelays(const Pin *ref_pin) const;
|
||||
const LogicValueMap &logicValues() const { return logic_value_map_; }
|
||||
const LogicValueMap &caseLogicValues() const { return case_value_map_; }
|
||||
// Returns nullptr if set_operating_conditions has not been called.
|
||||
|
|
@ -1221,6 +1221,7 @@ protected:
|
|||
InputDelay *except);
|
||||
void deleteInputDelaysReferencing(const Clock *clk);
|
||||
void deleteInputDelay(InputDelay *input_delay);
|
||||
|
||||
OutputDelay *findOutputDelay(const Pin *pin,
|
||||
const ClockEdge *clk_edge);
|
||||
OutputDelay *makeOutputDelay(const Pin *pin,
|
||||
|
|
@ -1229,6 +1230,7 @@ protected:
|
|||
OutputDelay *except);
|
||||
void deleteOutputDelaysReferencing(const Clock *clk);
|
||||
void deleteOutputDelay(OutputDelay *output_delay);
|
||||
|
||||
void deleteClockInsertion(ClockInsertion *insertion);
|
||||
void deleteClockInsertionsReferencing(Clock *clk);
|
||||
void deleteInterClockUncertainty(InterClockUncertainty *uncertainties);
|
||||
|
|
@ -1334,7 +1336,7 @@ protected:
|
|||
|
||||
InputDelaySet input_delays_;
|
||||
InputDelaysPinMap input_delay_pin_map_;
|
||||
InputDelaysPinMap input_delay_ref_pin_map_;
|
||||
bool have_input_delay_ref_pins_{false};
|
||||
// Input delays on hierarchical pins are indexed by the load pins.
|
||||
InputDelaysPinMap input_delay_leaf_pin_map_;
|
||||
InputDelaysPinMap input_delay_internal_pin_map_;
|
||||
|
|
@ -1342,7 +1344,6 @@ protected:
|
|||
|
||||
OutputDelaySet output_delays_;
|
||||
OutputDelaysPinMap output_delay_pin_map_;
|
||||
OutputDelaysPinMap output_delay_ref_pin_map_;
|
||||
// Output delays on hierarchical pins are indexed by the load pins.
|
||||
OutputDelaysPinMap output_delay_leaf_pin_map_;
|
||||
|
||||
|
|
|
|||
|
|
@ -800,8 +800,6 @@ public:
|
|||
|
||||
protected:
|
||||
void init0();
|
||||
void enqueueRefPinInputDelays(const Pin *ref_pin,
|
||||
const Sdc *sdc);
|
||||
void seedArrivals(Vertex *vertex);
|
||||
void pruneCrprArrivals();
|
||||
void constrainedRequiredsInvalid(Vertex *vertex,
|
||||
|
|
|
|||
|
|
@ -567,8 +567,6 @@ public:
|
|||
const Sdc *sdc);
|
||||
// Edge is disabled to break combinational loops.
|
||||
[[nodiscard]] bool isDisabledLoop(Edge *edge) const;
|
||||
// Edge is disabled internal bidirect output path.
|
||||
[[nodiscard]] bool isDisabledBidirectInstPath(Edge *edge) const;
|
||||
// Edge is disabled bidirect net path.
|
||||
[[nodiscard]] bool isDisabledBidirectNetPath(Edge *edge) const;
|
||||
[[nodiscard]] bool isDisabledPresetClr(Edge *edge) const;
|
||||
|
|
@ -1044,6 +1042,7 @@ public:
|
|||
int endpointViolationCount(const MinMax *min_max);
|
||||
// Find all required times after updateTiming().
|
||||
void findRequireds();
|
||||
void findRequired(Vertex *vertex);
|
||||
std::string reportDelayCalc(Edge *edge,
|
||||
TimingArc *arc,
|
||||
const Scene *scene,
|
||||
|
|
@ -1532,7 +1531,6 @@ protected:
|
|||
const Mode *mode,
|
||||
// Return value.
|
||||
PinSet &pins);
|
||||
void findRequired(Vertex *vertex);
|
||||
|
||||
void reportDelaysWrtClks(const Pin *pin,
|
||||
const Scene *scene,
|
||||
|
|
|
|||
|
|
@ -106,6 +106,8 @@ public:
|
|||
const Variables *variables() const { return variables_; }
|
||||
// Edge is default cond disabled by timing_disable_cond_default_arcs var.
|
||||
[[nodiscard]] bool isDisabledCondDefault(const Edge *edge) const;
|
||||
// Edge is disabled internal bidirect output path.
|
||||
[[nodiscard]] bool isDisabledBidirectInstPath(Edge *edge) const;
|
||||
|
||||
const SceneSeq &scenes() { return scenes_; }
|
||||
const SceneSeq &scenes() const { return scenes_; }
|
||||
|
|
|
|||
|
|
@ -204,6 +204,9 @@ public:
|
|||
static int wireArcIndex(const RiseFall *rf);
|
||||
static int wireArcCount() { return 2; }
|
||||
|
||||
// Psuedo definition for port ref_pin arcs.
|
||||
static TimingArcSet *portRefPinTimingArcSet() { return port_refpin_timing_arc_set_; }
|
||||
|
||||
protected:
|
||||
TimingArcSet(const TimingRole *role,
|
||||
TimingArcAttrsPtr attrs);
|
||||
|
|
@ -230,6 +233,7 @@ protected:
|
|||
|
||||
static TimingArcAttrsPtr wire_timing_arc_attrs_;
|
||||
static TimingArcSet *wire_timing_arc_set_;
|
||||
static TimingArcSet *port_refpin_timing_arc_set_;
|
||||
};
|
||||
|
||||
// A timing arc is a single from/to transition between two ports.
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ public:
|
|||
static const TimingRole *nonSeqHold() { return &non_seq_hold_; }
|
||||
static const TimingRole *clockTreePathMin() { return &clock_tree_path_min_; }
|
||||
static const TimingRole *clockTreePathMax() { return &clock_tree_path_max_; }
|
||||
static const TimingRole *portDelayRefPin() { return &port_delay_ref_pin_; }
|
||||
const std::string &to_string() const { return name_; }
|
||||
int index() const { return index_; }
|
||||
bool isWire() const;
|
||||
|
|
@ -139,6 +140,8 @@ private:
|
|||
static const TimingRole non_seq_hold_;
|
||||
static const TimingRole clock_tree_path_min_;
|
||||
static const TimingRole clock_tree_path_max_;
|
||||
// Artificial timing from input/output_delay ref_pin to the input/output.
|
||||
static const TimingRole port_delay_ref_pin_;
|
||||
static TimingRoleMap timing_roles_;
|
||||
|
||||
friend class TimingRoleLess;
|
||||
|
|
|
|||
|
|
@ -175,6 +175,7 @@ TimingArc::intrinsicDelay() const
|
|||
|
||||
TimingArcAttrsPtr TimingArcSet::wire_timing_arc_attrs_ = nullptr;
|
||||
TimingArcSet *TimingArcSet::wire_timing_arc_set_ = nullptr;
|
||||
TimingArcSet *TimingArcSet::port_refpin_timing_arc_set_ = nullptr;
|
||||
|
||||
TimingArcSet::TimingArcSet(LibertyCell *,
|
||||
LibertyPort *from,
|
||||
|
|
@ -524,6 +525,9 @@ TimingArcSet::init()
|
|||
Transition::rise(), nullptr);
|
||||
new TimingArc(wire_timing_arc_set_, Transition::fall(),
|
||||
Transition::fall(), nullptr);
|
||||
|
||||
port_refpin_timing_arc_set_ = new TimingArcSet(TimingRole::portDelayRefPin(),
|
||||
wire_timing_arc_attrs_);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -90,6 +90,8 @@ const TimingRole TimingRole::clock_tree_path_min_("min clock tree path", false,
|
|||
false, MinMax::min(), nullptr, 27);
|
||||
const TimingRole TimingRole::clock_tree_path_max_("max clock tree path", false, false,
|
||||
false, MinMax::max(), nullptr, 28);
|
||||
const TimingRole TimingRole::port_delay_ref_pin_("port delay ref pin", false, false,
|
||||
false, nullptr, nullptr, 29);
|
||||
|
||||
TimingRole::TimingRole(const char *name,
|
||||
bool is_sdf_iopath,
|
||||
|
|
|
|||
|
|
@ -87,6 +87,14 @@ PortDelay::refTransition() const
|
|||
return RiseFall::rise();
|
||||
}
|
||||
|
||||
void
|
||||
PortDelay::setRefPinEdgesExist(bool exists)
|
||||
{
|
||||
ref_pin_edges_exist_ = exists;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
InputDelay::InputDelay(const Pin *pin,
|
||||
const ClockEdge *clk_edge,
|
||||
int index,
|
||||
|
|
@ -97,6 +105,8 @@ InputDelay::InputDelay(const Pin *pin,
|
|||
findLeafLoadPins(pin, network, &leaf_pins_);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
OutputDelay::OutputDelay(const Pin *pin,
|
||||
const ClockEdge *clk_edge,
|
||||
const Network *network) :
|
||||
|
|
|
|||
54
sdc/Sdc.cc
54
sdc/Sdc.cc
|
|
@ -115,12 +115,10 @@ Sdc::Sdc(Mode *mode,
|
|||
cycle_acctings_(this),
|
||||
|
||||
input_delay_pin_map_(PinIdLess(network_)),
|
||||
input_delay_ref_pin_map_(PinIdLess(network_)),
|
||||
input_delay_leaf_pin_map_(PinIdLess(network_)),
|
||||
input_delay_internal_pin_map_(PinIdLess(network_)),
|
||||
|
||||
output_delay_pin_map_(PinIdLess(network_)),
|
||||
output_delay_ref_pin_map_(PinIdLess(network_)),
|
||||
output_delay_leaf_pin_map_(PinIdLess(network_)),
|
||||
|
||||
port_ext_cap_map_(network_),
|
||||
|
|
@ -191,9 +189,9 @@ Sdc::clear()
|
|||
input_delays_.clear();
|
||||
input_delay_pin_map_.clear();
|
||||
input_delay_index_ = 0;
|
||||
input_delay_ref_pin_map_.clear();
|
||||
input_delay_leaf_pin_map_.clear();
|
||||
input_delay_internal_pin_map_.clear();
|
||||
have_input_delay_ref_pins_ = false;
|
||||
|
||||
output_delays_.clear();
|
||||
output_delay_pin_map_.clear();
|
||||
|
|
@ -287,12 +285,10 @@ Sdc::deleteConstraints()
|
|||
deleteContents(input_delays_);
|
||||
deleteContents(input_delay_pin_map_);
|
||||
deleteContents(input_delay_leaf_pin_map_);
|
||||
deleteContents(input_delay_ref_pin_map_);
|
||||
deleteContents(input_delay_internal_pin_map_);
|
||||
|
||||
deleteContents(output_delays_);
|
||||
deleteContents(output_delay_pin_map_);
|
||||
deleteContents(output_delay_ref_pin_map_);
|
||||
deleteContents(output_delay_leaf_pin_map_);
|
||||
|
||||
deleteContents(clk_hpin_disables_);
|
||||
|
|
@ -2671,16 +2667,9 @@ Sdc::setInputDelay(const Pin *pin,
|
|||
delays->setValue(rf, min_max, delay);
|
||||
}
|
||||
|
||||
if (ref_pin) {
|
||||
InputDelaySet *ref_inputs = findKey(input_delay_ref_pin_map_, ref_pin);
|
||||
if (ref_inputs == nullptr) {
|
||||
ref_inputs = new InputDelaySet;
|
||||
input_delay_ref_pin_map_[ref_pin] = ref_inputs;
|
||||
}
|
||||
ref_inputs->insert(input_delay);
|
||||
}
|
||||
input_delay->setRefPin(ref_pin);
|
||||
|
||||
if (ref_pin)
|
||||
have_input_delay_ref_pins_ = true;
|
||||
input_delay->setSourceLatencyIncluded(source_latency_included);
|
||||
input_delay->setNetworkLatencyIncluded(network_latency_included);
|
||||
}
|
||||
|
|
@ -2766,12 +2755,6 @@ Sdc::deleteInputDelays(const Pin *pin,
|
|||
}
|
||||
}
|
||||
|
||||
InputDelaySet *
|
||||
Sdc::refPinInputDelays(const Pin *ref_pin) const
|
||||
{
|
||||
return findKey(input_delay_ref_pin_map_, ref_pin);
|
||||
}
|
||||
|
||||
InputDelaySet *
|
||||
Sdc::inputDelaysLeafPin(const Pin *leaf_pin) const
|
||||
{
|
||||
|
|
@ -2828,17 +2811,35 @@ Sdc::swapPortDelays(Sdc *sdc1,
|
|||
{
|
||||
std::swap(sdc1->input_delays_, sdc2->input_delays_);
|
||||
std::swap(sdc1->input_delay_pin_map_, sdc2->input_delay_pin_map_);
|
||||
std::swap(sdc1->input_delay_ref_pin_map_, sdc2->input_delay_ref_pin_map_);
|
||||
std::swap(sdc1->input_delay_leaf_pin_map_, sdc2->input_delay_leaf_pin_map_);
|
||||
std::swap(sdc1->input_delay_internal_pin_map_, sdc2->input_delay_internal_pin_map_);
|
||||
std::swap(sdc1->input_delay_index_, sdc2->input_delay_index_);
|
||||
|
||||
std::swap(sdc1->output_delays_, sdc2->output_delays_);
|
||||
std::swap(sdc1->output_delay_pin_map_, sdc2->output_delay_pin_map_);
|
||||
std::swap(sdc1->output_delay_ref_pin_map_, sdc2->output_delay_ref_pin_map_);
|
||||
std::swap(sdc1->output_delay_leaf_pin_map_, sdc2->output_delay_leaf_pin_map_);
|
||||
}
|
||||
|
||||
void
|
||||
Sdc::ensureInputDelayRefPinEdges()
|
||||
{
|
||||
if (have_input_delay_ref_pins_) {
|
||||
for (InputDelay *input_delay : input_delays_) {
|
||||
const Pin *ref_pin = input_delay->refPin();
|
||||
if (ref_pin
|
||||
&& !input_delay->refPinEdgesExist()) {
|
||||
Vertex *ref_pin_vertex = graph_->pinLoadVertex(ref_pin);
|
||||
for (const Pin *pin : input_delay->leafPins()) {
|
||||
Vertex *input_vertex = graph_->pinDrvrVertex(pin);
|
||||
graph_->makeEdge(ref_pin_vertex, input_vertex,
|
||||
TimingArcSet::portRefPinTimingArcSet());
|
||||
}
|
||||
input_delay->setRefPinEdgesExist(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
|
|
@ -2867,16 +2868,7 @@ Sdc::setOutputDelay(const Pin *pin,
|
|||
delays->setValue(rf, min_max, delay);
|
||||
}
|
||||
|
||||
if (ref_pin) {
|
||||
OutputDelaySet *ref_outputs = findKey(output_delay_ref_pin_map_, ref_pin);
|
||||
if (ref_outputs == nullptr) {
|
||||
ref_outputs = new OutputDelaySet;
|
||||
output_delay_ref_pin_map_[ref_pin] = ref_outputs;
|
||||
}
|
||||
ref_outputs->insert(output_delay);
|
||||
}
|
||||
output_delay->setRefPin(ref_pin);
|
||||
|
||||
output_delay->setSourceLatencyIncluded(source_latency_included);
|
||||
output_delay->setNetworkLatencyIncluded(network_latency_included);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,6 +118,9 @@ Levelize::findLevels()
|
|||
if (observer_)
|
||||
observer_->levelsChangedBefore();
|
||||
|
||||
for (const Mode *mode : modes_)
|
||||
mode->sdc()->ensureInputDelayRefPinEdges();
|
||||
|
||||
VertexIterator vertex_iter(graph_);
|
||||
while (vertex_iter.hasNext()) {
|
||||
Vertex *vertex = vertex_iter.next();
|
||||
|
|
@ -194,11 +197,13 @@ bool
|
|||
Levelize::searchThru(Edge *edge)
|
||||
{
|
||||
const TimingRole *role = edge->role();
|
||||
return !role->isTimingCheck() && role != TimingRole::latchDtoQ()
|
||||
&& !edge->isDisabledLoop()
|
||||
// Register/latch preset/clr edges are disabled by default.
|
||||
&& !(role == TimingRole::regSetClr() && !variables_->presetClrArcsEnabled())
|
||||
&& !(edge->isBidirectInstPath() && !variables_->bidirectInstPathsEnabled());
|
||||
return !(role->isTimingCheck()
|
||||
|| role == TimingRole::latchDtoQ()
|
||||
|| edge->isDisabledLoop()
|
||||
// Register/latch preset/clr edges are disabled by default.
|
||||
|| (role == TimingRole::regSetClr()
|
||||
&& !variables_->presetClrArcsEnabled())
|
||||
|| isDisabledBidirectInstPath(edge));
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -184,13 +184,14 @@ SearchAdj::searchThru(Edge *edge,
|
|||
{
|
||||
const TimingRole *role = edge->role();
|
||||
const Variables *variables = sta_->variables();
|
||||
return !role->isTimingCheck()
|
||||
&& !role->isLatchDtoQ()
|
||||
// Register/latch preset/clr edges are disabled by default.
|
||||
&& !(role == TimingRole::regSetClr() && !variables->presetClrArcsEnabled())
|
||||
&& !(edge->isBidirectInstPath() && !variables->bidirectInstPathsEnabled())
|
||||
&& (!edge->isDisabledLoop()
|
||||
|| (variables->dynamicLoopBreaking() && hasPendingLoopPaths(edge)));
|
||||
return !(role->isTimingCheck()
|
||||
|| role->isLatchDtoQ()
|
||||
// Register/latch preset/clr edges are disabled by default.
|
||||
|| (role == TimingRole::regSetClr()
|
||||
&& !variables->presetClrArcsEnabled())
|
||||
|| sta_->isDisabledBidirectInstPath(edge)
|
||||
|| (edge->isDisabledLoop()
|
||||
&& !(variables->dynamicLoopBreaking() && hasPendingLoopPaths(edge))));
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -1226,7 +1227,6 @@ ArrivalVisitor::seedArrivals(Vertex *vertex)
|
|||
network_->pathName(pin));
|
||||
search_->makeUnclkedPaths(vertex, true, false, tag_bldr_, mode);
|
||||
}
|
||||
enqueueRefPinInputDelays(pin, sdc);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1387,27 +1387,6 @@ ArrivalVisitor::pruneCrprArrivals()
|
|||
}
|
||||
}
|
||||
|
||||
// Enqueue pins with input delays that use ref_pin as the clock
|
||||
// reference pin as if there is a timing arc from the reference pin to
|
||||
// the input delay pin.
|
||||
void
|
||||
ArrivalVisitor::enqueueRefPinInputDelays(const Pin *ref_pin,
|
||||
const Sdc *sdc)
|
||||
{
|
||||
InputDelaySet *input_delays = sdc->refPinInputDelays(ref_pin);
|
||||
if (input_delays) {
|
||||
BfsFwdIterator *arrival_iter = search_->arrivalIterator();
|
||||
for (InputDelay *input_delay : *input_delays) {
|
||||
const Pin *pin = input_delay->pin();
|
||||
Vertex *vertex, *bidirect_drvr_vertex;
|
||||
graph_->pinVertices(pin, vertex, bidirect_drvr_vertex);
|
||||
arrival_iter->enqueue(vertex);
|
||||
if (bidirect_drvr_vertex)
|
||||
arrival_iter->enqueue(bidirect_drvr_vertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Search::enqueueLatchDataOutputs(Vertex *vertex)
|
||||
{
|
||||
|
|
@ -3250,8 +3229,10 @@ Search::isEndpoint(Vertex *vertex,
|
|||
const Pin *pin = vertex->pin();
|
||||
const Sdc *sdc = mode->sdc();
|
||||
return hasFanin(vertex, pred, graph_, mode)
|
||||
&& ((vertex->hasChecks() && hasEnabledChecks(vertex, mode))
|
||||
|| sdc->isConstrainedEnd(pin) || !hasFanout(vertex, pred, graph_, mode)
|
||||
&& ((vertex->hasChecks()
|
||||
&& hasEnabledChecks(vertex, mode))
|
||||
|| sdc->isConstrainedEnd(pin)
|
||||
|| !hasFanout(vertex, pred, graph_, mode)
|
||||
|| sdc->isPathDelayInternalTo(pin)
|
||||
// Unconstrained paths at register clk pins.
|
||||
|| (unconstrained_paths_ && vertex->isRegClk())
|
||||
|
|
|
|||
|
|
@ -184,6 +184,7 @@ ClkTreeSearchPred::searchThru(Edge *edge,
|
|||
|| sdc->isDisabledConstraint(edge)
|
||||
|| sdc->isDisabledCondDefault(edge)
|
||||
|| edge->isBidirectInstPath()
|
||||
|| edge->isBidirectPortPath()
|
||||
|| edge->isDisabledLoop());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1702,8 +1702,10 @@ Sta::disabledEdges(const Mode *mode)
|
|||
VertexOutEdgeIterator edge_iter(vertex, graph_);
|
||||
while (edge_iter.hasNext()) {
|
||||
Edge *edge = edge_iter.next();
|
||||
if (isDisabledConstant(edge, mode) || isDisabledCondDefault(edge)
|
||||
|| isDisabledConstraint(edge, sdc) || edge->isDisabledLoop()
|
||||
if (isDisabledConstant(edge, mode)
|
||||
|| isDisabledCondDefault(edge)
|
||||
|| isDisabledConstraint(edge, sdc)
|
||||
|| edge->isDisabledLoop()
|
||||
|| isDisabledPresetClr(edge))
|
||||
disabled_edges.push_back(edge);
|
||||
}
|
||||
|
|
@ -1841,12 +1843,6 @@ Sta::exprConstantPins(FuncExpr *expr,
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Sta::isDisabledBidirectInstPath(Edge *edge) const
|
||||
{
|
||||
return !variables_->bidirectInstPathsEnabled() && edge->isBidirectInstPath();
|
||||
}
|
||||
|
||||
bool
|
||||
Sta::isDisabledPresetClr(Edge *edge) const
|
||||
{
|
||||
|
|
@ -5242,8 +5238,10 @@ FanInOutSrchPred::searchThru(Edge *edge,
|
|||
const Sim *sim = mode->sim();
|
||||
return searchThruRole(edge)
|
||||
&& (thru_disabled_
|
||||
|| !(sdc->isDisabledConstraint(edge) || sim->isDisabledCond(edge)
|
||||
|| sta_->isDisabledCondDefault(edge)))
|
||||
|| !(sdc->isDisabledConstraint(edge)
|
||||
|| sim->isDisabledCond(edge)
|
||||
|| sta_->isDisabledCondDefault(edge)
|
||||
|| sta_->isDisabledBidirectInstPath(edge)))
|
||||
&& (thru_constants_ || sim->simTimingSense(edge) != TimingSense::none);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "Graph.hh"
|
||||
#include "Mode.hh"
|
||||
#include "Network.hh"
|
||||
#include "PortDirection.hh"
|
||||
#include "Scene.hh"
|
||||
#include "Sdc.hh"
|
||||
#include "TimingArc.hh"
|
||||
|
|
@ -124,6 +125,14 @@ StaState::isDisabledCondDefault(const Edge *edge) const
|
|||
&& edge->timingArcSet()->isCondDefault();
|
||||
}
|
||||
|
||||
bool
|
||||
StaState::isDisabledBidirectInstPath(Edge *edge) const
|
||||
{
|
||||
return (edge->isBidirectInstPath()
|
||||
|| edge->isBidirectPortPath())
|
||||
&& !variables_->bidirectInstPathsEnabled();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
size_t
|
||||
|
|
|
|||
Loading…
Reference in New Issue