set_input_delay/set_output_delay leaf pin iterators

This commit is contained in:
James Cherry 2019-11-10 17:10:26 -07:00
parent 5a9c99228c
commit c89e9da712
9 changed files with 264 additions and 441 deletions

1
.gitignore vendored
View File

@ -10,6 +10,7 @@
TAGS
*~
\#*#
.#*
.~lock.*#
.DS_Store
Makefile

View File

@ -90,6 +90,7 @@ Clock::setPins(PinSet *pins,
{
if (pins)
pins_ = *pins;
delete pins;
makeLeafPins(network);
}

View File

@ -82,97 +82,21 @@ InputDelay::InputDelay(Pin *pin,
int index,
Network *network) :
PortDelay(pin, clk_edge, ref_pin),
next_(nullptr),
index_(index)
{
findLeafLoadPins(pin, network, &leaf_pins_);
}
void
InputDelay::setNext(InputDelay *next)
{
next_ = next;
}
OutputDelay::OutputDelay(Pin *pin,
ClockEdge *clk_edge,
Pin *ref_pin,
Network *network) :
PortDelay(pin, clk_edge, ref_pin),
next_(nullptr)
PortDelay(pin, clk_edge, ref_pin)
{
if (network)
findLeafDriverPins(pin, network, &leaf_pins_);
}
void
OutputDelay::setNext(OutputDelay *next)
{
next_ = next;
}
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
PinInputDelayIterator::PinInputDelayIterator(const Pin *pin,
const Sdc *sdc)
{
next_ = sdc->input_delay_map_.findKey(pin);
}
bool
PinInputDelayIterator::hasNext()
{
return next_ != nullptr;
}
InputDelay *
PinInputDelayIterator::next()
{
InputDelay *next = next_;
if (next)
next_ = next_->next();
return next;
}
LeafPinInputDelayIterator::LeafPinInputDelayIterator(const Pin *vertex_pin,
const Sdc *sdc) :
PinInputDelayIterator()
{
next_ = sdc->input_delay_leaf_pin_map_.findKey(vertex_pin);
}
////////////////////////////////////////////////////////////////
PinOutputDelayIterator::PinOutputDelayIterator(const Pin *pin,
const Sdc *sdc)
{
next_ = sdc->output_delay_map_.findKey(pin);
}
bool
PinOutputDelayIterator::hasNext()
{
return next_ != nullptr;
}
OutputDelay *
PinOutputDelayIterator::next()
{
OutputDelay *next = next_;
if (next)
next_ = next_->next();
return next;
}
LeafPinOutputDelayIterator::LeafPinOutputDelayIterator(const Pin *vertex_pin,
const Sdc *sdc) :
PinOutputDelayIterator()
{
next_ = sdc->output_delay_leaf_pin_map_.findKey(vertex_pin);
}
////////////////////////////////////////////////////////////////
PortDelayLess::PortDelayLess(const Network *network) :

View File

@ -71,11 +71,6 @@ protected:
Pin *ref_pin,
int index,
Network *network);
InputDelay *next() { return next_; }
// Linked list of port delays on the same pin wrt different clocks.
InputDelay *next_;
void setNext(InputDelay *next);
private:
DISALLOW_COPY_AND_ASSIGN(InputDelay);
@ -83,8 +78,6 @@ private:
int index_;
friend class Sdc;
friend class PinInputDelayIterator;
friend class InputDelayIterator;
};
class OutputDelay : public PortDelay
@ -96,70 +89,11 @@ protected:
ClockEdge *clk_edge,
Pin *ref_pin,
Network *network);
OutputDelay *next() { return next_; }
void setNext(OutputDelay *next);
// Linked list of port delays on the same port wrt different clocks.
OutputDelay *next_;
private:
DISALLOW_COPY_AND_ASSIGN(OutputDelay);
friend class Sdc;
friend class PinOutputDelayIterator;
friend class OutputDelayIterator;
};
class PinInputDelayIterator : public Iterator<InputDelay*>
{
public:
PinInputDelayIterator(const Pin *pin,
const Sdc *sdc);
virtual bool hasNext();
virtual InputDelay *next();
protected:
PinInputDelayIterator() {}
InputDelay *next_;
DISALLOW_COPY_AND_ASSIGN(PinInputDelayIterator);
};
class LeafPinInputDelayIterator : public PinInputDelayIterator
{
public:
LeafPinInputDelayIterator(const Pin *pin,
const Sdc *sdc);
private:
DISALLOW_COPY_AND_ASSIGN(LeafPinInputDelayIterator);
};
class PinOutputDelayIterator : public Iterator<OutputDelay*>
{
public:
PinOutputDelayIterator(const Pin *pin,
const Sdc *sdc);
virtual bool hasNext();
virtual OutputDelay *next();
protected:
PinOutputDelayIterator() {}
OutputDelay *next_;
DISALLOW_COPY_AND_ASSIGN(PinOutputDelayIterator);
};
class LeafPinOutputDelayIterator : public PinOutputDelayIterator
{
public:
LeafPinOutputDelayIterator(const Pin *pin,
const Sdc *sdc);
private:
DISALLOW_COPY_AND_ASSIGN(LeafPinOutputDelayIterator);
};
// Prediate used to sort port delays.

View File

@ -167,12 +167,14 @@ Sdc::clear()
data_checks_to_map_.clear();
input_delays_.clear();
input_delay_map_.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();
output_delay_map_.clear();
output_delays_.clear();
output_delay_pin_map_.clear();
output_delay_leaf_pin_map_.clear();
port_slew_limit_map_.clear();
@ -283,32 +285,18 @@ Sdc::deleteConstraints()
delete checks;
}
InputDelayMap::Iterator input_iter(input_delay_map_);
while (input_iter.hasNext()) {
InputDelay *input_delay = input_iter.next();
while (input_delay) {
InputDelay *next = input_delay->next();
delete input_delay;
input_delay = next;
}
}
for (auto input_delay : input_delays_)
delete input_delay;
input_delay_pin_map_.deleteContents();
input_delay_leaf_pin_map_.deleteContents();
input_delay_internal_pin_map_.deleteContents();
InputDelayRefPinMap::Iterator input_set_iter(input_delay_ref_pin_map_);
while (input_set_iter.hasNext()) {
InputDelaySet *input_delays = input_set_iter.next();
delete input_delays;
}
input_delay_internal_pin_map_.deleteContents();
for (auto output_delay : output_delays_)
delete output_delay;
output_delay_pin_map_.deleteContents();
output_delay_ref_pin_map_.deleteContents();
output_delay_leaf_pin_map_.deleteContents();
OutputDelayMap::Iterator output_iter(output_delay_map_);
while (output_iter.hasNext()) {
OutputDelay *output_delay = output_iter.next();
while (output_delay) {
OutputDelay *next = output_delay->next();
delete output_delay;
output_delay = next;
}
}
clk_hpin_disables_.deleteContentsClear();
clk_hpin_disables_valid_ = false;
@ -442,8 +430,8 @@ Sdc::isConstrained(const Pin *pin) const
|| pin_clk_gating_check_map_.hasKey(pin)
|| data_checks_from_map_.hasKey(pin)
|| data_checks_to_map_.hasKey(pin)
|| input_delay_map_.hasKey(pin)
|| output_delay_map_.hasKey(pin)
|| input_delay_pin_map_.hasKey(pin)
|| output_delay_pin_map_.hasKey(pin)
|| port_slew_limit_map_.hasKey(port)
|| pin_cap_limit_map_.hasKey(pin1)
|| port_cap_limit_map_.hasKey(port)
@ -2772,12 +2760,16 @@ Sdc::setInputDelay(Pin *pin,
float delay)
{
ClockEdge *clk_edge = clk ? clk->edge(clk_tr) : nullptr;
InputDelay *input_delay = ensureInputDelay(pin, clk_edge, ref_pin);
RiseFallMinMax *delays = input_delay->delays();
if (add)
InputDelay *input_delay = findInputDelay(pin, clk_edge, ref_pin);
if (input_delay == nullptr)
input_delay = makeInputDelay(pin, clk_edge, ref_pin);
if (add) {
RiseFallMinMax *delays = input_delay->delays();
delays->mergeValue(tr, min_max, delay);
}
else {
deleteInputDelays(pin, input_delay);
RiseFallMinMax *delays = input_delay->delays();
delays->setValue(tr, min_max, delay);
}
input_delay->setSourceLatencyIncluded(source_latency_included);
@ -2785,35 +2777,45 @@ Sdc::setInputDelay(Pin *pin,
}
InputDelay *
Sdc::ensureInputDelay(Pin *pin,
ClockEdge *clk_edge,
Pin *ref_pin)
Sdc::makeInputDelay(Pin *pin,
ClockEdge *clk_edge,
Pin *ref_pin)
{
InputDelay *input_delay = findInputDelay(pin, clk_edge, ref_pin);
if (input_delay == nullptr) {
input_delay = new InputDelay(pin, clk_edge, ref_pin, input_delay_index_++,
network_);
input_delays_.insert(input_delay);
input_delay->setNext(input_delay_map_[pin]);
input_delay_map_[pin] = input_delay;
if (ref_pin) {
InputDelaySet *ref_inputs = input_delay_ref_pin_map_.findKey(ref_pin);
if (ref_inputs == nullptr) {
ref_inputs = new InputDelaySet;
input_delay_ref_pin_map_[ref_pin] = ref_inputs;
}
ref_inputs->insert(input_delay);
InputDelay *input_delay = new InputDelay(pin, clk_edge, ref_pin,
input_delay_index_++,
network_);
input_delays_.insert(input_delay);
InputDelaySet *inputs = input_delay_pin_map_.findKey(pin);
if (inputs == nullptr) {
inputs = new InputDelaySet;
input_delay_pin_map_[pin] = inputs;
}
inputs->insert(input_delay);
if (ref_pin) {
InputDelaySet *ref_inputs = input_delay_ref_pin_map_.findKey(ref_pin);
if (ref_inputs == nullptr) {
ref_inputs = new InputDelaySet;
input_delay_ref_pin_map_[ref_pin] = ref_inputs;
}
for (Pin *vpin : input_delay->leafPins()) {
input_delay_leaf_pin_map_[vpin] = input_delay;
if (!network_->isTopLevelPort(vpin)) {
InputDelaySet *input_set = input_delay_internal_pin_map_[vpin];
if (input_set == nullptr) {
input_set = new InputDelaySet;
input_delay_internal_pin_map_[vpin] = input_set;
}
input_set->insert(input_delay);
ref_inputs->insert(input_delay);
}
for (Pin *lpin : input_delay->leafPins()) {
InputDelaySet *leaf_inputs = input_delay_leaf_pin_map_[lpin];
if (leaf_inputs == nullptr) {
leaf_inputs = new InputDelaySet;
input_delay_leaf_pin_map_[lpin] = leaf_inputs;
}
leaf_inputs->insert(input_delay);
if (!network_->isTopLevelPort(lpin)) {
InputDelaySet *internal_inputs = input_delay_internal_pin_map_[lpin];
if (internal_inputs == nullptr) {
internal_inputs = new InputDelaySet;
input_delay_internal_pin_map_[pin] = internal_inputs;
}
internal_inputs->insert(input_delay);
}
}
return input_delay;
@ -2824,12 +2826,13 @@ Sdc::findInputDelay(const Pin *pin,
ClockEdge *clk_edge,
Pin *ref_pin)
{
for (InputDelay *input_delay = input_delay_map_.findKey(pin);
input_delay;
input_delay = input_delay->next()) {
if (input_delay->clkEdge() == clk_edge
&& input_delay->refPin() == ref_pin)
return input_delay;
InputDelaySet *inputs = input_delay_pin_map_.findKey(pin);
if (inputs) {
for (InputDelay *input_delay : *inputs) {
if (input_delay->clkEdge() == clk_edge
&& input_delay->refPin() == ref_pin)
return input_delay;
}
}
return nullptr;
}
@ -2855,27 +2858,12 @@ void
Sdc::deleteInputDelays(Pin *pin,
InputDelay *except)
{
InputDelay *input_delay = input_delay_map_.findKey(pin);
while (input_delay) {
InputDelay *next = input_delay->next();
if (input_delay == except)
input_delay->setNext(nullptr);
else {
delete input_delay;
input_delays_.erase(input_delay);
}
input_delay = next;
}
input_delay_map_[pin] = except;
for (Pin *vpin : except->leafPins()) {
input_delay_leaf_pin_map_[vpin] = except;
InputDelaySet *input_delays =
input_delay_internal_pin_map_.findKey(vpin);
if (input_delays) {
input_delays->clear();
input_delays->insert(except);
}
InputDelaySet *input_delays = input_delay_pin_map_[pin];
InputDelaySet::Iterator iter(input_delays);
while (iter.hasNext()) {
InputDelay *input_delay = iter.next();
if (input_delay != except)
deleteInputDelay(input_delay);
}
}
@ -2885,70 +2873,48 @@ Sdc::refPinInputDelays(const Pin *ref_pin) const
return input_delay_ref_pin_map_.findKey(ref_pin);
}
PinInputDelayIterator *
Sdc::inputDelayIterator(const Pin *pin) const
InputDelaySet *
Sdc::inputDelaysLeafPin(const Pin *leaf_pin)
{
return new PinInputDelayIterator(pin, this);
return input_delay_leaf_pin_map_.findKey(leaf_pin);
}
bool
Sdc::hasInputDelay(const Pin *leaf_pin) const
{
return input_delay_leaf_pin_map_.findKey(leaf_pin) != nullptr;
InputDelaySet *input_delays = input_delay_leaf_pin_map_.findKey(leaf_pin);
return input_delays && !input_delays->empty();
}
bool
Sdc::isInputDelayInternal(const Pin *pin) const
{
InputDelaySet *input_delays =
input_delay_internal_pin_map_.findKey(pin);
return input_delays && !input_delays->empty();
return input_delay_internal_pin_map_.hasKey(pin);
}
void
Sdc::deleteInputDelaysReferencing(Clock *clk)
{
Vector<InputDelay*> refs;
for (InputDelay *input_delay : input_delays_) {
InputDelaySet::Iterator iter(input_delays_);
while (iter.hasNext()) {
InputDelay *input_delay = iter.next();
if (input_delay->clock() == clk)
refs.push_back(input_delay);
}
for (InputDelay *input_delay : refs)
deleteInputDelay(input_delay);
}
}
void
Sdc::deleteInputDelay(InputDelay *input_delay)
{
input_delays_.erase(input_delay);
Pin *pin = input_delay->pin();
InputDelay *head = input_delay_map_.findKey(pin);
if (head == input_delay) {
InputDelay *next = input_delay->next();
if (next)
input_delay_map_[pin] = next;
else
input_delay_map_.erase(pin);
head = next;
}
else {
for (InputDelay *delay = head; delay; ) {
InputDelay *next = delay->next();
if (next == input_delay) {
delay->setNext(input_delay->next());
break;
}
delay = next;
}
}
for (Pin *vpin : input_delay->leafPins()) {
if (head)
input_delay_leaf_pin_map_[vpin] = head;
else
input_delay_leaf_pin_map_.erase(vpin);
Pin *pin = input_delay->pin();
InputDelaySet *inputs = input_delay_pin_map_[pin];
inputs->erase(input_delay);
for (Pin *lpin : input_delay->leafPins()) {
InputDelaySet *inputs = input_delay_leaf_pin_map_[lpin];
inputs->erase(input_delay);
}
delete input_delay;
@ -2969,53 +2935,75 @@ Sdc::setOutputDelay(Pin *pin,
float delay)
{
ClockEdge *clk_edge = clk ? clk->edge(clk_tr) : nullptr;
OutputDelay *output_delay = ensureOutputDelay(pin, clk_edge, ref_pin);
RiseFallMinMax *delays = output_delay->delays();
if (add)
OutputDelay *output_delay = findOutputDelay(pin, clk_edge, ref_pin);
if (output_delay == nullptr)
output_delay = makeOutputDelay(pin, clk_edge, ref_pin);
if (add) {
RiseFallMinMax *delays = output_delay->delays();
delays->mergeValue(tr, min_max, delay);
}
else {
deleteOutputDelays(pin, output_delay);
RiseFallMinMax *delays = output_delay->delays();
delays->setValue(tr, min_max, delay);
}
output_delay->setSourceLatencyIncluded(source_latency_included);
output_delay->setNetworkLatencyIncluded(network_latency_included);
}
OutputDelay *
Sdc::ensureOutputDelay(Pin *pin,
ClockEdge *clk_edge,
Pin *ref_pin)
{
OutputDelay *output_delay = findOutputDelay(pin, clk_edge, ref_pin);
if (output_delay == nullptr) {
output_delay = new OutputDelay(pin, clk_edge, ref_pin, network_);
output_delays_.insert(output_delay);
output_delay->setNext(output_delay_map_[pin]);
output_delay_map_[pin] = output_delay;
for (Pin *vpin : output_delay->leafPins()) {
output_delay_leaf_pin_map_[vpin] = output_delay;
if (graph_)
annotateGraphConstrained(vpin, true);
}
}
return output_delay;
}
OutputDelay *
Sdc::findOutputDelay(const Pin *pin,
ClockEdge *clk_edge,
Pin *ref_pin)
{
for (OutputDelay *output_delay = output_delay_map_.findKey(pin);
output_delay;
output_delay = output_delay->next()) {
if (output_delay->clkEdge() == clk_edge
&& output_delay->refPin() == ref_pin)
return output_delay;
OutputDelaySet *outputs = output_delay_pin_map_.findKey(pin);
if (outputs) {
for (OutputDelay *output_delay : *outputs) {
if (output_delay->clkEdge() == clk_edge
&& output_delay->refPin() == ref_pin)
return output_delay;
}
}
return nullptr;
}
OutputDelay *
Sdc::makeOutputDelay(Pin *pin,
ClockEdge *clk_edge,
Pin *ref_pin)
{
OutputDelay *output_delay = new OutputDelay(pin, clk_edge, ref_pin,
network_);
output_delays_.insert(output_delay);
OutputDelaySet *outputs = output_delay_pin_map_.findKey(pin);
if (outputs == nullptr) {
outputs = new OutputDelaySet;
output_delay_pin_map_[pin] = outputs;
}
outputs->insert(output_delay);
if (ref_pin) {
OutputDelaySet *ref_outputs = output_delay_ref_pin_map_.findKey(ref_pin);
if (ref_outputs == nullptr) {
ref_outputs = new OutputDelaySet;
output_delay_ref_pin_map_[ref_pin] = ref_outputs;
}
ref_outputs->insert(output_delay);
}
for (Pin *lpin : output_delay->leafPins()) {
OutputDelaySet *leaf_outputs = output_delay_leaf_pin_map_[lpin];
if (leaf_outputs == nullptr) {
leaf_outputs = new OutputDelaySet;
output_delay_leaf_pin_map_[lpin] = leaf_outputs;
}
leaf_outputs->insert(output_delay);
if (graph_)
annotateGraphConstrained(lpin, true);
}
return output_delay;
}
void
Sdc::removeOutputDelay(Pin *pin,
TransRiseFallBoth *tr,
@ -3024,9 +3012,9 @@ Sdc::removeOutputDelay(Pin *pin,
MinMaxAll *min_max)
{
ClockEdge *clk_edge = clk ? clk->edge(clk_tr) : nullptr;
InputDelay *input_delay = findInputDelay(pin, clk_edge, nullptr);
if (input_delay) {
RiseFallMinMax *delays = input_delay->delays();
OutputDelay *output_delay = findOutputDelay(pin, clk_edge, nullptr);
if (output_delay) {
RiseFallMinMax *delays = output_delay->delays();
delays->removeValue(tr, min_max);
}
}
@ -3035,24 +3023,19 @@ void
Sdc::deleteOutputDelays(Pin *pin,
OutputDelay *except)
{
OutputDelay *output_delay = output_delay_map_.findKey(pin);
while (output_delay) {
OutputDelay *next = output_delay->next();
if (output_delay == except)
output_delay->setNext(nullptr);
else
delete output_delay;
output_delay = next;
OutputDelaySet *output_delays = output_delay_pin_map_[pin];
OutputDelaySet::Iterator iter(output_delays);
while (iter.hasNext()) {
OutputDelay *output_delay = iter.next();
if (output_delay != except)
deleteOutputDelay(output_delay);
}
output_delay_map_[pin] = except;
for (Pin *vpin : except->leafPins())
output_delay_leaf_pin_map_[vpin] = except;
}
PinOutputDelayIterator *
Sdc::outputDelayIterator(const Pin *pin) const
OutputDelaySet *
Sdc::outputDelaysLeafPin(const Pin *leaf_pin)
{
return new PinOutputDelayIterator(pin, this);
return output_delay_leaf_pin_map_.findKey(leaf_pin);
}
bool
@ -3064,45 +3047,26 @@ Sdc::hasOutputDelay(const Pin *leaf_pin) const
void
Sdc::deleteOutputDelaysReferencing(Clock *clk)
{
Vector<OutputDelay*> refs;
for (OutputDelay *output_delay : output_delays_) {
OutputDelaySet::Iterator iter(output_delays_);
while (iter.hasNext()) {
OutputDelay *output_delay = iter.next();
if (output_delay->clock() == clk)
refs.push_back(output_delay);
deleteOutputDelay(output_delay);
}
for (OutputDelay *output_delay : refs)
deleteOutputDelay(output_delay);
}
void
Sdc::deleteOutputDelay(OutputDelay *output_delay)
{
Pin *pin = output_delay->pin();
output_delays_.erase(output_delay);
OutputDelay *head = output_delay_map_.findKey(pin);
if (head == output_delay) {
OutputDelay *next = output_delay->next();
if (next)
output_delay_map_[pin] = next;
else
output_delay_map_.erase(pin);
head = next;
}
else {
for (OutputDelay *delay = head; delay; ) {
OutputDelay *next = delay->next();
if (next == output_delay) {
delay->setNext(output_delay->next());
break;
}
delay = next;
}
}
for (Pin *vpin : output_delay->leafPins()) {
if (head)
output_delay_leaf_pin_map_[vpin] = head;
else
output_delay_leaf_pin_map_.erase(vpin);
Pin *pin = output_delay->pin();
OutputDelaySet *outputs = output_delay_pin_map_[pin];
outputs->erase(output_delay);
for (Pin *lpin : output_delay->leafPins()) {
OutputDelaySet *outputs = output_delay_leaf_pin_map_[lpin];
outputs->erase(output_delay);
}
delete output_delay;
@ -6345,14 +6309,9 @@ Sdc::setEdgeDisabledInstFrom(Pin *from_pin,
void
Sdc::annotateGraphOutputDelays(bool annotate)
{
OutputDelayMap::Iterator output_iter(output_delay_map_);
while (output_iter.hasNext()) {
OutputDelay *output_delay = output_iter.next();
while (output_delay) {
for (Pin *vpin : output_delay->leafPins())
annotateGraphConstrained(vpin, annotate);
output_delay = output_delay->next();
}
for (OutputDelay *output_delay : output_delays_) {
for (Pin *lpin : output_delay->leafPins())
annotateGraphConstrained(lpin, annotate);
}
}

View File

@ -38,8 +38,6 @@
namespace sta {
class OperatingConditions;
class PinInputDelayIterator;
class PinOutputDelayIterator;
class PortExtCap;
class ClockGatingCheck;
class InputDriveCell;
@ -106,12 +104,9 @@ public:
typedef Map<const char*,Clock*, CharPtrLess> ClockNameMap;
typedef UnorderedMap<const Pin*, ClockSet*> ClockPinMap;
typedef Set<InputDelay*> InputDelaySet;
typedef Map<const Pin*,InputDelay*> InputDelayMap;
typedef Set<InputDelay*> InputDelaySet;
typedef Map<const Pin*,InputDelaySet*> InputDelayRefPinMap;
typedef Map<const Pin*,InputDelaySet*> InputDelayInternalPinMap;
typedef Map<const Pin*,InputDelaySet*> InputDelaysPinMap;
typedef Set<OutputDelay*> OutputDelaySet;
typedef Map<const Pin*,OutputDelay*> OutputDelayMap;
typedef Map<const Pin*,OutputDelaySet*> OutputDelaysPinMap;
// Use HashSet so no read lock is required.
typedef HashSet<CycleAccting*, CycleAcctingHash, CycleAcctingEqual> CycleAcctingSet;
typedef Set<Instance*> InstanceSet;
@ -817,13 +812,7 @@ public:
void setUseDefaultArrivalClock(bool enable);
// STA interface.
InputDelay *ensureInputDelay(Pin *pin,
ClockEdge *clk_edge,
Pin *ref_pin);
InputDelaySet *refPinInputDelays(const Pin *ref_pin) const;
OutputDelay *ensureOutputDelay(Pin *pin,
ClockEdge *clk_edge,
Pin *ref_pin);
LogicValueMap *logicValues() { return &logic_value_map_; }
LogicValueMap *caseLogicValues() { return &case_value_map_; }
// Returns nullptr if set_operating_conditions has not been called.
@ -892,18 +881,23 @@ public:
const ClockEdge *tgt);
// Report clock to clock relationships that exceed max_cycle_count.
void reportClkToClkMaxCycleWarnings();
const InputDelaySet &inputDelays() const { return input_delays_; }
// Pin -> input delays.
const InputDelayMap &inputDelayMap() const { return input_delay_map_; }
// Iterate over the input delays on pin (which may be hierarchical).
PinInputDelayIterator *inputDelayIterator(const Pin *pin) const;
const InputDelaysPinMap &inputDelayPinMap() const { return input_delay_pin_map_; }
// Input delays on leaf_pin.
InputDelaySet *inputDelaysLeafPin(const Pin *leaf_pin);
bool hasInputDelay(const Pin *leaf_pin) const;
// Pin is internal (not top level port) and has an input arrival.
bool isInputDelayInternal(const Pin *pin) const;
const OutputDelaySet &outputDelays() const { return output_delays_; }
// Iterate over the output delays on pin (which may be hierarchical).
PinOutputDelayIterator *outputDelayIterator(const Pin *pin) const;
// Pin -> output delays.
const OutputDelaysPinMap &outputDelayPinMap() const { return output_delay_pin_map_; }
// Output delays on leaf_pin.
OutputDelaySet *outputDelaysLeafPin(const Pin *leaf_pin);
bool hasOutputDelay(const Pin *leaf_pin) const;
PortExtCap *portExtCap(Port *port) const;
bool hasPortExtCap(Port *port) const;
void portExtCap(Port *port,
@ -1168,6 +1162,9 @@ protected:
InputDelay *findInputDelay(const Pin *pin,
ClockEdge *clk_edge,
Pin *ref_pin);
InputDelay *makeInputDelay(Pin *pin,
ClockEdge *clk_edge,
Pin *ref_pin);
void deleteInputDelays(Pin *pin,
InputDelay *except);
void deleteInputDelaysReferencing(Clock *clk);
@ -1175,6 +1172,9 @@ protected:
OutputDelay *findOutputDelay(const Pin *pin,
ClockEdge *clk_edge,
Pin *ref_pin);
OutputDelay *makeOutputDelay(Pin *pin,
ClockEdge *clk_edge,
Pin *ref_pin);
void deleteOutputDelays(Pin *pin, OutputDelay *except);
void deleteOutputDelaysReferencing(Clock *clk);
void deleteOutputDelay(OutputDelay *output_delay);
@ -1313,17 +1313,21 @@ protected:
std::mutex cycle_acctings_lock_;
DataChecksMap data_checks_from_map_;
DataChecksMap data_checks_to_map_;
InputDelaySet input_delays_;
InputDelayMap input_delay_map_;
InputDelaysPinMap input_delay_pin_map_;
int input_delay_index_;
InputDelayRefPinMap input_delay_ref_pin_map_;
InputDelaysPinMap input_delay_ref_pin_map_;
// Input delays on hierarchical pins are indexed by the load pins.
InputDelayMap input_delay_leaf_pin_map_;
InputDelayInternalPinMap input_delay_internal_pin_map_;
InputDelaysPinMap input_delay_leaf_pin_map_;
InputDelaysPinMap input_delay_internal_pin_map_;
OutputDelaySet output_delays_;
OutputDelayMap output_delay_map_;
OutputDelaysPinMap output_delay_pin_map_;
OutputDelaysPinMap output_delay_ref_pin_map_;
// Output delays on hierarchical pins are indexed by the load pins.
OutputDelayMap output_delay_leaf_pin_map_;
OutputDelaysPinMap output_delay_leaf_pin_map_;
PortSlewLimitMap port_slew_limit_map_;
PinSlewLimitMap pin_slew_limit_map_;
CellSlewLimitMap cell_slew_limit_map_;
@ -1420,10 +1424,6 @@ private:
friend class FindNetCaps;
friend class ClockGroupIterator;
friend class GroupPathIterator;
friend class PinInputDelayIterator;
friend class LeafPinInputDelayIterator;
friend class PinOutputDelayIterator;
friend class LeafPinOutputDelayIterator;
};
class ClockIterator : public ClockSeq::Iterator

View File

@ -247,11 +247,12 @@ CheckTiming::checkUnconstraintedOutputs(PinSet &unconstrained_ends)
bool
CheckTiming::hasClkedDepature(Pin *pin)
{
PinOutputDelayIterator delay_iter(pin, sdc_);
while (delay_iter.hasNext()) {
OutputDelay *output_delay = delay_iter.next();
if (output_delay->clkEdge() != nullptr)
return true;
OutputDelaySet *output_delays = sdc_->outputDelaysLeafPin(pin);
if (output_delays) {
for (OutputDelay *output_delay : *output_delays) {
if (output_delay->clkEdge() != nullptr)
return true;
}
}
return false;
}

View File

@ -868,7 +868,7 @@ Search::visitStartpoints(VertexVisitor *visitor)
}
delete pin_iter;
for (auto iter : sdc_->inputDelayMap()) {
for (auto iter : sdc_->inputDelayPinMap()) {
const Pin *pin = iter.first;
// Already hit these.
if (!network_->isTopLevelPort(pin)) {
@ -1332,7 +1332,7 @@ ArrivalVisitor::enqueueRefPinInputDelays(const Pin *ref_pin)
InputDelaySet *input_delays = sdc->refPinInputDelays(ref_pin);
if (input_delays) {
const Graph *graph = sta_->graph();
for (auto input_delay : *input_delays) {
for (InputDelay *input_delay : *input_delays) {
const Pin *pin = input_delay->pin();
Vertex *vertex, *bidirect_drvr_vertex;
graph->pinVertices(pin, vertex, bidirect_drvr_vertex);
@ -1661,7 +1661,7 @@ Search::seedInputArrivals(ClockSet *clks)
{
// Input arrivals can be on internal pins, so iterate over the pins
// that have input arrivals rather than the top level input pins.
for (auto iter : sdc_->inputDelayMap()) {
for (auto iter : sdc_->inputDelayPinMap()) {
const Pin *pin = iter.first;
if (!sdc_->isLeafPinClock(pin)) {
Vertex *vertex = graph_->pinDrvrVertex(pin);
@ -1677,25 +1677,26 @@ Search::seedInputArrival(const Pin *pin,
{
bool has_arrival = false;
// There can be multiple arrivals for a pin with wrt different clocks.
LeafPinInputDelayIterator arrival_iter(pin, sdc_);
TagGroupBldr tag_bldr(true, this);
tag_bldr.init(vertex);
while (arrival_iter.hasNext()) {
InputDelay *input_delay = arrival_iter.next();
Clock *input_clk = input_delay->clock();
ClockSet *pin_clks = sdc_->findLeafPinClocks(pin);
if (input_clk && wrt_clks->hasKey(input_clk)
// Input arrivals wrt a clock source pin is the insertion
// delay (source latency), but arrivals wrt other clocks
// propagate.
&& (pin_clks == nullptr
|| !pin_clks->hasKey(input_clk))) {
seedInputDelayArrival(pin, vertex, input_delay, false, &tag_bldr);
has_arrival = true;
InputDelaySet *input_delays = sdc_->inputDelaysLeafPin(pin);
if (input_delays) {
for (InputDelay *input_delay : *input_delays) {
Clock *input_clk = input_delay->clock();
ClockSet *pin_clks = sdc_->findLeafPinClocks(pin);
if (input_clk && wrt_clks->hasKey(input_clk)
// Input arrivals wrt a clock source pin is the insertion
// delay (source latency), but arrivals wrt other clocks
// propagate.
&& (pin_clks == nullptr
|| !pin_clks->hasKey(input_clk))) {
seedInputDelayArrival(pin, vertex, input_delay, false, &tag_bldr);
has_arrival = true;
}
}
if (has_arrival)
setVertexArrivals(vertex, &tag_bldr);
}
if (has_arrival)
setVertexArrivals(vertex, &tag_bldr);
}
void
@ -1725,18 +1726,19 @@ Search::seedInputArrival1(const Pin *pin,
TagGroupBldr *tag_bldr)
{
// There can be multiple arrivals for a pin with wrt different clocks.
LeafPinInputDelayIterator arrival_iter(pin, sdc_);
while (arrival_iter.hasNext()) {
InputDelay *input_delay = arrival_iter.next();
Clock *input_clk = input_delay->clock();
ClockSet *pin_clks = sdc_->findLeafPinClocks(pin);
// Input arrival wrt a clock source pin is the clock insertion
// delay (source latency), but arrivals wrt other clocks
// propagate.
if (pin_clks == nullptr
|| !pin_clks->hasKey(input_clk))
seedInputDelayArrival(pin, vertex, input_delay, is_segment_start,
tag_bldr);
InputDelaySet *input_delays = sdc_->inputDelaysLeafPin(pin);
if (input_delays) {
for (InputDelay *input_delay : *input_delays) {
Clock *input_clk = input_delay->clock();
ClockSet *pin_clks = sdc_->findLeafPinClocks(pin);
// Input arrival wrt a clock source pin is the clock insertion
// delay (source latency), but arrivals wrt other clocks
// propagate.
if (pin_clks == nullptr
|| !pin_clks->hasKey(input_clk))
seedInputDelayArrival(pin, vertex, input_delay, is_segment_start,
tag_bldr);
}
}
}

View File

@ -299,36 +299,37 @@ VisitPathEnds::visitOutputDelayEnd(const Pin *pin,
bool &is_constrained)
{
const MinMax *min_max = path_ap->pathMinMax();
LeafPinOutputDelayIterator delay_iter(pin, sdc_);
while (delay_iter.hasNext()) {
OutputDelay *output_delay = delay_iter.next();
float margin;
bool exists;
output_delay->delays()->value(end_tr, min_max, margin, exists);
if (exists) {
const Pin *ref_pin = output_delay->refPin();
ClockEdge *tgt_clk_edge = output_delay->clkEdge();
if (!filtered
|| search_->matchesFilter(path, tgt_clk_edge)) {
if (ref_pin) {
Clock *tgt_clk = output_delay->clock();
Vertex *ref_vertex = graph_->pinLoadVertex(ref_pin);
TransRiseFall *ref_tr = output_delay->refTransition();
VertexPathIterator ref_path_iter(ref_vertex,ref_tr,path_ap,this);
while (ref_path_iter.hasNext()) {
PathVertex *ref_path = ref_path_iter.next();
if (ref_path->isClock(this)
&& (tgt_clk == nullptr
|| ref_path->clock(this) == tgt_clk))
visitOutputDelayEnd1(output_delay, pin, path, end_tr,
ref_path->clkEdge(this), ref_path, min_max,
visitor, is_constrained);
OutputDelaySet *output_delays = sdc_->outputDelaysLeafPin(pin);
if (output_delays) {
for (OutputDelay *output_delay : *output_delays) {
float margin;
bool exists;
output_delay->delays()->value(end_tr, min_max, margin, exists);
if (exists) {
const Pin *ref_pin = output_delay->refPin();
ClockEdge *tgt_clk_edge = output_delay->clkEdge();
if (!filtered
|| search_->matchesFilter(path, tgt_clk_edge)) {
if (ref_pin) {
Clock *tgt_clk = output_delay->clock();
Vertex *ref_vertex = graph_->pinLoadVertex(ref_pin);
TransRiseFall *ref_tr = output_delay->refTransition();
VertexPathIterator ref_path_iter(ref_vertex,ref_tr,path_ap,this);
while (ref_path_iter.hasNext()) {
PathVertex *ref_path = ref_path_iter.next();
if (ref_path->isClock(this)
&& (tgt_clk == nullptr
|| ref_path->clock(this) == tgt_clk))
visitOutputDelayEnd1(output_delay, pin, path, end_tr,
ref_path->clkEdge(this), ref_path, min_max,
visitor, is_constrained);
}
}
else
visitOutputDelayEnd1(output_delay, pin, path, end_tr,
tgt_clk_edge, nullptr, min_max,
visitor, is_constrained);
}
else
visitOutputDelayEnd1(output_delay, pin, path, end_tr,
tgt_clk_edge, nullptr, min_max,
visitor, is_constrained);
}
}
}