LibertyCell::timingArcSets() range iteration
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
bad3dae60f
commit
8c5b0fcaa5
|
|
@ -710,9 +710,7 @@ GraphDelayCalc1::driveCellDefaultFromPort(LibertyCell *cell,
|
||||||
{
|
{
|
||||||
LibertyPort *from_port = 0;
|
LibertyPort *from_port = 0;
|
||||||
int from_port_index = 0;
|
int from_port_index = 0;
|
||||||
LibertyCellTimingArcSetIterator set_iter(cell, nullptr, to_port);
|
for (TimingArcSet *arc_set : cell->timingArcSets(nullptr, to_port)) {
|
||||||
while (set_iter.hasNext()) {
|
|
||||||
TimingArcSet *arc_set = set_iter.next();
|
|
||||||
LibertyPort *set_from_port = arc_set->from();
|
LibertyPort *set_from_port = arc_set->from();
|
||||||
int set_from_port_index = findPortIndex(cell, set_from_port);
|
int set_from_port_index = findPortIndex(cell, set_from_port);
|
||||||
if (from_port == nullptr
|
if (from_port == nullptr
|
||||||
|
|
@ -754,9 +752,7 @@ GraphDelayCalc1::findInputDriverDelay(LibertyCell *drvr_cell,
|
||||||
debugPrint(debug_, "delay_calc", 2, " driver cell %s %s",
|
debugPrint(debug_, "delay_calc", 2, " driver cell %s %s",
|
||||||
drvr_cell->name(),
|
drvr_cell->name(),
|
||||||
rf->asString());
|
rf->asString());
|
||||||
LibertyCellTimingArcSetIterator set_iter(drvr_cell, from_port, to_port);
|
for (TimingArcSet *arc_set : drvr_cell->timingArcSets(from_port, to_port)) {
|
||||||
while (set_iter.hasNext()) {
|
|
||||||
TimingArcSet *arc_set = set_iter.next();
|
|
||||||
TimingArcSetArcIterator arc_iter(arc_set);
|
TimingArcSetArcIterator arc_iter(arc_set);
|
||||||
while (arc_iter.hasNext()) {
|
while (arc_iter.hasNext()) {
|
||||||
TimingArc *arc = arc_iter.next();
|
TimingArc *arc = arc_iter.next();
|
||||||
|
|
|
||||||
|
|
@ -185,9 +185,7 @@ Graph::makePortInstanceEdges(const Instance *inst,
|
||||||
LibertyCell *cell,
|
LibertyCell *cell,
|
||||||
LibertyPort *from_to_port)
|
LibertyPort *from_to_port)
|
||||||
{
|
{
|
||||||
LibertyCellTimingArcSetIterator timing_iter(cell);
|
for (TimingArcSet *arc_set : cell->timingArcSets()) {
|
||||||
while (timing_iter.hasNext()) {
|
|
||||||
TimingArcSet *arc_set = timing_iter.next();
|
|
||||||
LibertyPort *from_port = arc_set->from();
|
LibertyPort *from_port = arc_set->from();
|
||||||
LibertyPort *to_port = arc_set->to();
|
LibertyPort *to_port = arc_set->to();
|
||||||
if ((from_to_port == nullptr
|
if ((from_to_port == nullptr
|
||||||
|
|
|
||||||
|
|
@ -424,9 +424,10 @@ public:
|
||||||
bool isClockGateOther() const;
|
bool isClockGateOther() const;
|
||||||
bool isClockGate() const;
|
bool isClockGate() const;
|
||||||
void setClockGateType(ClockGateType type);
|
void setClockGateType(ClockGateType type);
|
||||||
|
const TimingArcSetSeq &timingArcSets() const { return timing_arc_sets_; }
|
||||||
// from or to may be nullptr to wildcard.
|
// from or to may be nullptr to wildcard.
|
||||||
TimingArcSetSeq *timingArcSets(const LibertyPort *from,
|
const TimingArcSetSeq &timingArcSets(const LibertyPort *from,
|
||||||
const LibertyPort *to) const;
|
const LibertyPort *to) const;
|
||||||
size_t timingArcSetCount() const;
|
size_t timingArcSetCount() const;
|
||||||
// Find a timing arc set equivalent to key.
|
// Find a timing arc set equivalent to key.
|
||||||
TimingArcSet *findTimingArcSet(TimingArcSet *key) const;
|
TimingArcSet *findTimingArcSet(TimingArcSet *key) const;
|
||||||
|
|
@ -583,7 +584,6 @@ private:
|
||||||
friend class LibertyCellPgPortIterator;
|
friend class LibertyCellPgPortIterator;
|
||||||
friend class LibertyPort;
|
friend class LibertyPort;
|
||||||
friend class LibertyBuilder;
|
friend class LibertyBuilder;
|
||||||
friend class LibertyCellTimingArcSetIterator;
|
|
||||||
friend class LibertyCellSequentialIterator;
|
friend class LibertyCellSequentialIterator;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -621,16 +621,6 @@ private:
|
||||||
LibertyPgPortMap::Iterator iter_;
|
LibertyPgPortMap::Iterator iter_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LibertyCellTimingArcSetIterator : public TimingArcSetSeq::ConstIterator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
LibertyCellTimingArcSetIterator(const LibertyCell *cell);
|
|
||||||
// from or to may be nullptr to wildcard.
|
|
||||||
LibertyCellTimingArcSetIterator(const LibertyCell *cell,
|
|
||||||
const LibertyPort *from,
|
|
||||||
const LibertyPort *to);
|
|
||||||
};
|
|
||||||
|
|
||||||
class LibertyCellSequentialIterator : public SequentialSeq::ConstIterator
|
class LibertyCellSequentialIterator : public SequentialSeq::ConstIterator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -355,11 +355,9 @@ equivCellTimingArcSets(const LibertyCell *cell1,
|
||||||
if (cell1->timingArcSetCount() != cell2->timingArcSetCount())
|
if (cell1->timingArcSetCount() != cell2->timingArcSetCount())
|
||||||
return false;
|
return false;
|
||||||
else {
|
else {
|
||||||
LibertyCellTimingArcSetIterator set_iter1(cell1);
|
for (TimingArcSet *arc_set1 : cell1->timingArcSets()) {
|
||||||
while (set_iter1.hasNext()) {
|
TimingArcSet *arc_set2 = cell2->findTimingArcSet(arc_set1);
|
||||||
TimingArcSet *set1 = set_iter1.next();
|
if (!(arc_set2 && TimingArcSet::equiv(arc_set1, arc_set2)))
|
||||||
TimingArcSet *set2 = cell2->findTimingArcSet(set1);
|
|
||||||
if (!(set2 && TimingArcSet::equiv(set1, set2)))
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -1353,20 +1353,26 @@ LibertyCell::makeTimingArcPortMaps()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TimingArcSetSeq *
|
const TimingArcSetSeq &
|
||||||
LibertyCell::timingArcSets(const LibertyPort *from,
|
LibertyCell::timingArcSets(const LibertyPort *from,
|
||||||
const LibertyPort *to) const
|
const LibertyPort *to) const
|
||||||
{
|
{
|
||||||
|
TimingArcSetSeq *arc_sets = nullptr;
|
||||||
if (from && to) {
|
if (from && to) {
|
||||||
LibertyPortPair port_pair(from, to);
|
LibertyPortPair port_pair(from, to);
|
||||||
return port_timing_arc_set_map_.findKey(port_pair);
|
arc_sets = port_timing_arc_set_map_.findKey(port_pair);
|
||||||
}
|
}
|
||||||
else if (from)
|
else if (from)
|
||||||
return timing_arc_set_from_map_.findKey(from);
|
arc_sets = timing_arc_set_from_map_.findKey(from);
|
||||||
else if (to)
|
else if (to)
|
||||||
return timing_arc_set_to_map_.findKey(to);
|
arc_sets = timing_arc_set_to_map_.findKey(to);
|
||||||
else
|
|
||||||
return nullptr;
|
if (arc_sets)
|
||||||
|
return *arc_sets;
|
||||||
|
else {
|
||||||
|
static TimingArcSetSeq null_set;
|
||||||
|
return null_set;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TimingArcSet *
|
TimingArcSet *
|
||||||
|
|
@ -1461,11 +1467,13 @@ LibertyCell::addScaledCell(OperatingConditions *op_cond,
|
||||||
port->addScaledPort(op_cond, scaled_port);
|
port->addScaledPort(op_cond, scaled_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
LibertyCellTimingArcSetIterator set_iter1(this);
|
const TimingArcSetSeq &arc_sets1 = this->timingArcSets();
|
||||||
LibertyCellTimingArcSetIterator set_iter2(scaled_cell);
|
const TimingArcSetSeq &arc_sets2 = scaled_cell->timingArcSets();
|
||||||
while (set_iter1.hasNext() && set_iter2.hasNext()) {
|
for (auto set_itr1 = arc_sets1.begin(), set_itr2 = arc_sets2.begin();
|
||||||
TimingArcSet *arc_set1 = set_iter1.next();
|
set_itr1 != arc_sets1.end() && set_itr2 != arc_sets2.end();
|
||||||
TimingArcSet *arc_set2 = set_iter2.next();
|
set_itr1++, set_itr2++) {
|
||||||
|
TimingArcSet *arc_set1 = *set_itr1;
|
||||||
|
TimingArcSet *arc_set2 = *set_itr2;
|
||||||
TimingArcSetArcIterator arc_iter1(arc_set1);
|
TimingArcSetArcIterator arc_iter1(arc_set1);
|
||||||
TimingArcSetArcIterator arc_iter2(arc_set2);
|
TimingArcSetArcIterator arc_iter2(arc_set2);
|
||||||
while (arc_iter1.hasNext() && arc_iter2.hasNext()) {
|
while (arc_iter1.hasNext() && arc_iter2.hasNext()) {
|
||||||
|
|
@ -1566,20 +1574,6 @@ LibertyCell::addOcvDerate(OcvDerate *derate)
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
LibertyCellTimingArcSetIterator::LibertyCellTimingArcSetIterator(const LibertyCell *cell) :
|
|
||||||
TimingArcSetSeq::ConstIterator(&cell->timing_arc_sets_)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
LibertyCellTimingArcSetIterator::LibertyCellTimingArcSetIterator(const LibertyCell *cell,
|
|
||||||
const LibertyPort *from,
|
|
||||||
const LibertyPort *to):
|
|
||||||
TimingArcSetSeq::ConstIterator(cell->timingArcSets(from, to))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// Latch enable port/function for a latch D->Q timing arc set.
|
// Latch enable port/function for a latch D->Q timing arc set.
|
||||||
class LatchEnable
|
class LatchEnable
|
||||||
{
|
{
|
||||||
|
|
@ -1644,14 +1638,11 @@ LibertyCell::makeLatchEnables(Report *report,
|
||||||
if (en_to_q->role() == TimingRole::latchEnToQ()) {
|
if (en_to_q->role() == TimingRole::latchEnToQ()) {
|
||||||
LibertyPort *en = en_to_q->from();
|
LibertyPort *en = en_to_q->from();
|
||||||
LibertyPort *q = en_to_q->to();
|
LibertyPort *q = en_to_q->to();
|
||||||
LibertyCellTimingArcSetIterator to_iter(this, nullptr, q);
|
|
||||||
while (to_iter.hasNext()) {
|
for (TimingArcSet *d_to_q : timingArcSets(nullptr, q)) {
|
||||||
TimingArcSet *d_to_q = to_iter.next();
|
|
||||||
if (d_to_q->role() == TimingRole::latchDtoQ()) {
|
if (d_to_q->role() == TimingRole::latchDtoQ()) {
|
||||||
LibertyPort *d = d_to_q->from();
|
LibertyPort *d = d_to_q->from();
|
||||||
LibertyCellTimingArcSetIterator check_iter(this, en, d);
|
for (TimingArcSet *setup_check : timingArcSets(en, d)) {
|
||||||
while (check_iter.hasNext()) {
|
|
||||||
TimingArcSet *setup_check = check_iter.next();
|
|
||||||
if (setup_check->role() == TimingRole::setup()) {
|
if (setup_check->role() == TimingRole::setup()) {
|
||||||
LatchEnable *latch_enable = makeLatchEnable(d, en, q, d_to_q,
|
LatchEnable *latch_enable = makeLatchEnable(d, en, q, d_to_q,
|
||||||
en_to_q,
|
en_to_q,
|
||||||
|
|
@ -1749,16 +1740,12 @@ LibertyCell::inferLatchRoles(Debug *debug)
|
||||||
if (hasInferedRegTimingArcs()) {
|
if (hasInferedRegTimingArcs()) {
|
||||||
// Hunt down potential latch D/EN/Q triples.
|
// Hunt down potential latch D/EN/Q triples.
|
||||||
LatchEnableSet latch_enables;
|
LatchEnableSet latch_enables;
|
||||||
LibertyCellTimingArcSetIterator set_iter(this);
|
for (TimingArcSet *en_to_q : timingArcSets()) {
|
||||||
while (set_iter.hasNext()) {
|
|
||||||
TimingArcSet *en_to_q = set_iter.next();
|
|
||||||
// Locate potential d->q arcs from reg clk->q arcs.
|
// Locate potential d->q arcs from reg clk->q arcs.
|
||||||
if (en_to_q->role() == TimingRole::regClkToQ()) {
|
if (en_to_q->role() == TimingRole::regClkToQ()) {
|
||||||
LibertyPort *en = en_to_q->from();
|
LibertyPort *en = en_to_q->from();
|
||||||
LibertyPort *q = en_to_q->to();
|
LibertyPort *q = en_to_q->to();
|
||||||
LibertyCellTimingArcSetIterator to_iter(this, nullptr, q);
|
for (TimingArcSet *d_to_q : timingArcSets(nullptr, q)) {
|
||||||
while (to_iter.hasNext()) {
|
|
||||||
TimingArcSet *d_to_q = to_iter.next();
|
|
||||||
// Look for combinational d->q arcs.
|
// Look for combinational d->q arcs.
|
||||||
TimingRole *d_to_q_role = d_to_q->role();
|
TimingRole *d_to_q_role = d_to_q->role();
|
||||||
if ((d_to_q_role == TimingRole::combinational()
|
if ((d_to_q_role == TimingRole::combinational()
|
||||||
|
|
@ -1770,9 +1757,7 @@ LibertyCell::inferLatchRoles(Debug *debug)
|
||||||
|| d_to_q_role == TimingRole::latchDtoQ()) {
|
|| d_to_q_role == TimingRole::latchDtoQ()) {
|
||||||
LibertyPort *d = d_to_q->from();
|
LibertyPort *d = d_to_q->from();
|
||||||
// Check for setup check from en -> d.
|
// Check for setup check from en -> d.
|
||||||
LibertyCellTimingArcSetIterator check_iter(this, en, d);
|
for (TimingArcSet *setup_check : timingArcSets(en, d)) {
|
||||||
while (check_iter.hasNext()) {
|
|
||||||
TimingArcSet *setup_check = check_iter.next();
|
|
||||||
if (setup_check->role() == TimingRole::setup()) {
|
if (setup_check->role() == TimingRole::setup()) {
|
||||||
makeLatchEnable(d, en, q, d_to_q, en_to_q, setup_check, debug);
|
makeLatchEnable(d, en, q, d_to_q, en_to_q, setup_check, debug);
|
||||||
d_to_q->setRole(TimingRole::latchDtoQ());
|
d_to_q->setRole(TimingRole::latchDtoQ());
|
||||||
|
|
@ -2035,11 +2020,9 @@ LibertyPort::driveResistance(const RiseFall *rf,
|
||||||
{
|
{
|
||||||
float max_drive = min_max->initValue();
|
float max_drive = min_max->initValue();
|
||||||
bool found_drive = false;
|
bool found_drive = false;
|
||||||
LibertyCellTimingArcSetIterator set_iter(liberty_cell_, nullptr, this);
|
for (TimingArcSet *arc_set : liberty_cell_->timingArcSets(nullptr, this)) {
|
||||||
while (set_iter.hasNext()) {
|
if (!arc_set->role()->isTimingCheck()) {
|
||||||
TimingArcSet *set = set_iter.next();
|
TimingArcSetArcIterator arc_iter(arc_set);
|
||||||
if (!set->role()->isTimingCheck()) {
|
|
||||||
TimingArcSetArcIterator arc_iter(set);
|
|
||||||
while (arc_iter.hasNext()) {
|
while (arc_iter.hasNext()) {
|
||||||
TimingArc *arc = arc_iter.next();
|
TimingArc *arc = arc_iter.next();
|
||||||
if (rf == nullptr
|
if (rf == nullptr
|
||||||
|
|
@ -2073,11 +2056,9 @@ LibertyPort::intrinsicDelay(const RiseFall *rf,
|
||||||
{
|
{
|
||||||
ArcDelay max_delay = min_max->initValue();
|
ArcDelay max_delay = min_max->initValue();
|
||||||
bool found_delay = false;
|
bool found_delay = false;
|
||||||
LibertyCellTimingArcSetIterator set_iter(liberty_cell_, nullptr, this);
|
for (TimingArcSet *arc_set : liberty_cell_->timingArcSets(nullptr, this)) {
|
||||||
while (set_iter.hasNext()) {
|
if (!arc_set->role()->isTimingCheck()) {
|
||||||
TimingArcSet *set = set_iter.next();
|
TimingArcSetArcIterator arc_iter(arc_set);
|
||||||
if (!set->role()->isTimingCheck()) {
|
|
||||||
TimingArcSetArcIterator arc_iter(set);
|
|
||||||
while (arc_iter.hasNext()) {
|
while (arc_iter.hasNext()) {
|
||||||
TimingArc *arc = arc_iter.next();
|
TimingArc *arc = arc_iter.next();
|
||||||
if (rf == nullptr
|
if (rf == nullptr
|
||||||
|
|
|
||||||
|
|
@ -354,12 +354,8 @@ LibertyWriter::writePortAttrs(const LibertyPort *port)
|
||||||
fprintf(stream_, " max_capacitance : %s;\n",
|
fprintf(stream_, " max_capacitance : %s;\n",
|
||||||
cap_unit_->asString(limit, 3));
|
cap_unit_->asString(limit, 3));
|
||||||
|
|
||||||
LibertyCellTimingArcSetIterator set_iter(port->libertyCell(),
|
for (TimingArcSet *arc_set : port->libertyCell()->timingArcSets(nullptr,port))
|
||||||
nullptr, port);
|
|
||||||
while (set_iter.hasNext()) {
|
|
||||||
const TimingArcSet *arc_set = set_iter.next();
|
|
||||||
writeTimingArcSet(arc_set);
|
writeTimingArcSet(arc_set);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
27
sdc/Sdc.cc
27
sdc/Sdc.cc
|
|
@ -382,11 +382,8 @@ Sdc::removeLibertyAnnotations()
|
||||||
LibertyPortPair *pair = from_to_iter.next();
|
LibertyPortPair *pair = from_to_iter.next();
|
||||||
const LibertyPort *from = pair->first;
|
const LibertyPort *from = pair->first;
|
||||||
const LibertyPort *to = pair->second;
|
const LibertyPort *to = pair->second;
|
||||||
LibertyCellTimingArcSetIterator arc_iter(cell, from, to);
|
for (TimingArcSet *arc_set : cell->timingArcSets(from, to))
|
||||||
while (arc_iter.hasNext()) {
|
|
||||||
TimingArcSet *arc_set = arc_iter.next();
|
|
||||||
arc_set->setIsDisabledConstraint(false);
|
arc_set->setIsDisabledConstraint(false);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3408,11 +3405,8 @@ Sdc::disable(LibertyCell *cell,
|
||||||
}
|
}
|
||||||
if (from && to) {
|
if (from && to) {
|
||||||
disabled_cell->setDisabledFromTo(from, to);
|
disabled_cell->setDisabledFromTo(from, to);
|
||||||
LibertyCellTimingArcSetIterator arc_iter(cell, from, to);
|
for (TimingArcSet *arc_set : cell->timingArcSets(from, to))
|
||||||
while (arc_iter.hasNext()) {
|
|
||||||
TimingArcSet *arc_set = arc_iter.next();
|
|
||||||
arc_set->setIsDisabledConstraint(true);
|
arc_set->setIsDisabledConstraint(true);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (from) {
|
else if (from) {
|
||||||
disabled_cell->setDisabledFrom(from);
|
disabled_cell->setDisabledFrom(from);
|
||||||
|
|
@ -3437,11 +3431,8 @@ Sdc::removeDisable(LibertyCell *cell,
|
||||||
if (disabled_cell) {
|
if (disabled_cell) {
|
||||||
if (from && to) {
|
if (from && to) {
|
||||||
disabled_cell->removeDisabledFromTo(from, to);
|
disabled_cell->removeDisabledFromTo(from, to);
|
||||||
LibertyCellTimingArcSetIterator arc_iter(cell, from, to);
|
for (TimingArcSet *arc_set : cell->timingArcSets(from, to))
|
||||||
while (arc_iter.hasNext()) {
|
arc_set->setIsDisabledConstraint(false);
|
||||||
TimingArcSet *arc_set = arc_iter.next();
|
|
||||||
arc_set->setIsDisabledConstraint(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (from) {
|
else if (from) {
|
||||||
disabled_cell->removeDisabledFrom(from);
|
disabled_cell->removeDisabledFrom(from);
|
||||||
|
|
@ -3884,10 +3875,8 @@ Sdc::exceptionToInvalid(const Pin *pin)
|
||||||
LibertyPort *port = network_->libertyPort(pin);
|
LibertyPort *port = network_->libertyPort(pin);
|
||||||
if (port) {
|
if (port) {
|
||||||
LibertyCell *cell = port->libertyCell();
|
LibertyCell *cell = port->libertyCell();
|
||||||
LibertyCellTimingArcSetIterator set_iter(cell, nullptr, port);
|
for (TimingArcSet *arc_set : cell->timingArcSets(nullptr, port)) {
|
||||||
while (set_iter.hasNext()) {
|
TimingRole *role = arc_set->role();
|
||||||
TimingArcSet *set = set_iter.next();
|
|
||||||
TimingRole *role = set->role();
|
|
||||||
if (role->genericRole() == TimingRole::regClkToQ())
|
if (role->genericRole() == TimingRole::regClkToQ())
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -4050,9 +4039,7 @@ Sdc::hasLibertyChecks(const Pin *pin)
|
||||||
if (cell) {
|
if (cell) {
|
||||||
LibertyPort *port = network_->libertyPort(pin);
|
LibertyPort *port = network_->libertyPort(pin);
|
||||||
if (port) {
|
if (port) {
|
||||||
LibertyCellTimingArcSetIterator timing_iter(cell, nullptr, port);
|
for (TimingArcSet *arc_set : cell->timingArcSets(nullptr, port)) {
|
||||||
while (timing_iter.hasNext()) {
|
|
||||||
TimingArcSet *arc_set = timing_iter.next();
|
|
||||||
if (arc_set->role()->isTimingCheck())
|
if (arc_set->role()->isTimingCheck())
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -273,10 +273,8 @@ FindRegVisitor::findInferedSequential(LibertyCell *cell,
|
||||||
{
|
{
|
||||||
bool matches = false;
|
bool matches = false;
|
||||||
const RiseFall *clk_rf1 = clk_rf->asRiseFall();
|
const RiseFall *clk_rf1 = clk_rf->asRiseFall();
|
||||||
LibertyCellTimingArcSetIterator set_iter(cell);
|
for (TimingArcSet *arc_set : cell->timingArcSets()) {
|
||||||
while (set_iter.hasNext()) {
|
TimingArcSetArcIterator arc_iter(arc_set);
|
||||||
TimingArcSet *set = set_iter.next();
|
|
||||||
TimingArcSetArcIterator arc_iter(set);
|
|
||||||
TimingArc *arc = arc_iter.next();
|
TimingArc *arc = arc_iter.next();
|
||||||
RiseFall *arc_clk_rf = arc->fromEdge()->asRiseFall();
|
RiseFall *arc_clk_rf = arc->fromEdge()->asRiseFall();
|
||||||
bool tr_matches = (clk_rf == RiseFallBoth::riseFall()
|
bool tr_matches = (clk_rf == RiseFallBoth::riseFall()
|
||||||
|
|
@ -284,7 +282,7 @@ FindRegVisitor::findInferedSequential(LibertyCell *cell,
|
||||||
&& clk_sense == TimingSense::positive_unate)
|
&& clk_sense == TimingSense::positive_unate)
|
||||||
|| (arc_clk_rf == clk_rf1->opposite()
|
|| (arc_clk_rf == clk_rf1->opposite()
|
||||||
&& clk_sense == TimingSense::negative_unate));
|
&& clk_sense == TimingSense::negative_unate));
|
||||||
TimingRole *role = set->role();
|
TimingRole *role = arc_set->role();
|
||||||
if (tr_matches
|
if (tr_matches
|
||||||
&& ((role == TimingRole::regClkToQ()
|
&& ((role == TimingRole::regClkToQ()
|
||||||
&& edge_triggered)
|
&& edge_triggered)
|
||||||
|
|
@ -302,10 +300,8 @@ FindRegVisitor::hasTimingCheck(LibertyCell *cell,
|
||||||
LibertyPort *clk,
|
LibertyPort *clk,
|
||||||
LibertyPort *d)
|
LibertyPort *d)
|
||||||
{
|
{
|
||||||
LibertyCellTimingArcSetIterator set_iter(cell, clk, d);
|
for (TimingArcSet *arc_set : cell->timingArcSets(clk, d)) {
|
||||||
while (set_iter.hasNext()) {
|
TimingRole *role = arc_set->role();
|
||||||
TimingArcSet *set = set_iter.next();
|
|
||||||
TimingRole *role = set->role();
|
|
||||||
if (role->isTimingCheck())
|
if (role->isTimingCheck())
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -541,10 +537,8 @@ FindRegClkPins::matchPin(Pin *pin)
|
||||||
{
|
{
|
||||||
LibertyPort *port = network_->libertyPort(pin);
|
LibertyPort *port = network_->libertyPort(pin);
|
||||||
LibertyCell *cell = port->libertyCell();
|
LibertyCell *cell = port->libertyCell();
|
||||||
LibertyCellTimingArcSetIterator set_iter(cell, port, nullptr);
|
for (TimingArcSet *arc_set : cell->timingArcSets(port, nullptr)) {
|
||||||
while (set_iter.hasNext()) {
|
TimingRole *role = arc_set->role();
|
||||||
TimingArcSet *set = set_iter.next();
|
|
||||||
TimingRole *role = set->role();
|
|
||||||
if (role->isTimingCheck())
|
if (role->isTimingCheck())
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -598,10 +592,8 @@ FindRegAsyncPins::matchPin(Pin *pin)
|
||||||
{
|
{
|
||||||
LibertyPort *port = network_->libertyPort(pin);
|
LibertyPort *port = network_->libertyPort(pin);
|
||||||
LibertyCell *cell = port->libertyCell();
|
LibertyCell *cell = port->libertyCell();
|
||||||
LibertyCellTimingArcSetIterator set_iter(cell, port, nullptr);
|
for (TimingArcSet *arc_set : cell->timingArcSets(port, nullptr)) {
|
||||||
while (set_iter.hasNext()) {
|
TimingRole *role = arc_set->role();
|
||||||
TimingArcSet *set = set_iter.next();
|
|
||||||
TimingRole *role = set->role();
|
|
||||||
if (role == TimingRole::regSetClr())
|
if (role == TimingRole::regSetClr())
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -647,10 +639,8 @@ FindRegOutputPins::matchPin(Pin *pin)
|
||||||
{
|
{
|
||||||
LibertyPort *port = network_->libertyPort(pin);
|
LibertyPort *port = network_->libertyPort(pin);
|
||||||
LibertyCell *cell = port->libertyCell();
|
LibertyCell *cell = port->libertyCell();
|
||||||
LibertyCellTimingArcSetIterator set_iter(cell, nullptr, port);
|
for (TimingArcSet *arc_set : cell->timingArcSets(nullptr, port)) {
|
||||||
while (set_iter.hasNext()) {
|
TimingRole *role = arc_set->role();
|
||||||
TimingArcSet *set = set_iter.next();
|
|
||||||
TimingRole *role = set->role();
|
|
||||||
if (role == TimingRole::regClkToQ()
|
if (role == TimingRole::regClkToQ()
|
||||||
|| role == TimingRole::latchEnToQ()
|
|| role == TimingRole::latchEnToQ()
|
||||||
|| role == TimingRole::latchDtoQ())
|
|| role == TimingRole::latchDtoQ())
|
||||||
|
|
|
||||||
|
|
@ -489,9 +489,7 @@ MakeTimingModel::makeGateModelTable(const Pin *output_pin,
|
||||||
const LibertyPort *drvr_port = network_->libertyPort(drvr_pin);
|
const LibertyPort *drvr_port = network_->libertyPort(drvr_pin);
|
||||||
if (drvr_port) {
|
if (drvr_port) {
|
||||||
const LibertyCell *drvr_cell = drvr_port->libertyCell();
|
const LibertyCell *drvr_cell = drvr_port->libertyCell();
|
||||||
LibertyCellTimingArcSetIterator set_iter(drvr_cell, nullptr, drvr_port);
|
for (TimingArcSet *arc_set : drvr_cell->timingArcSets(nullptr, drvr_port)) {
|
||||||
while (set_iter.hasNext()) {
|
|
||||||
TimingArcSet *arc_set = set_iter.next();
|
|
||||||
TimingArcSetArcIterator arc_iter(arc_set);
|
TimingArcSetArcIterator arc_iter(arc_set);
|
||||||
while (arc_iter.hasNext()) {
|
while (arc_iter.hasNext()) {
|
||||||
TimingArc *drvr_arc = arc_iter.next();
|
TimingArc *drvr_arc = arc_iter.next();
|
||||||
|
|
|
||||||
|
|
@ -911,9 +911,9 @@ isPositiveUnate(const LibertyCell *cell,
|
||||||
const LibertyPort *from,
|
const LibertyPort *from,
|
||||||
const LibertyPort *to)
|
const LibertyPort *to)
|
||||||
{
|
{
|
||||||
TimingArcSetSeq *arc_sets = cell->timingArcSets(from, to);
|
const TimingArcSetSeq &arc_sets = cell->timingArcSets(from, to);
|
||||||
if (arc_sets && !arc_sets->empty()) {
|
if (!arc_sets.empty()) {
|
||||||
TimingSense sense = (*arc_sets)[0]->sense();
|
TimingSense sense = arc_sets[0]->sense();
|
||||||
return sense == TimingSense::positive_unate
|
return sense == TimingSense::positive_unate
|
||||||
|| sense == TimingSense::non_unate;
|
|| sense == TimingSense::non_unate;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1244,10 +1244,8 @@ isCondDisabled(Edge *edge,
|
||||||
LibertyCell *cell = network->libertyCell(inst);
|
LibertyCell *cell = network->libertyCell(inst);
|
||||||
LibertyPort *from_port = network->libertyPort(from_pin);
|
LibertyPort *from_port = network->libertyPort(from_pin);
|
||||||
LibertyPort *to_port = network->libertyPort(to_pin);
|
LibertyPort *to_port = network->libertyPort(to_pin);
|
||||||
LibertyCellTimingArcSetIterator cond_iter(cell, from_port, to_port);
|
|
||||||
is_disabled = false;
|
is_disabled = false;
|
||||||
while (cond_iter.hasNext()) {
|
for (TimingArcSet *cond_set : cell->timingArcSets(from_port, to_port)) {
|
||||||
TimingArcSet *cond_set = cond_iter.next();
|
|
||||||
FuncExpr *cond = cond_set->cond();
|
FuncExpr *cond = cond_set->cond();
|
||||||
if (cond && sim->evalExpr(cond, inst) == LogicValue::one) {
|
if (cond && sim->evalExpr(cond, inst) == LogicValue::one) {
|
||||||
disable_cond = cond;
|
disable_cond = cond;
|
||||||
|
|
|
||||||
|
|
@ -1268,7 +1268,7 @@ proc get_timing_arcs_objects { object_arg } {
|
||||||
} elseif { $libcells != {} } {
|
} elseif { $libcells != {} } {
|
||||||
set arc_sets {}
|
set arc_sets {}
|
||||||
foreach libcell $libcells {
|
foreach libcell $libcells {
|
||||||
lappend arc_sets [libcell_timing_arc_sets $libcell]
|
lappend arc_sets [$libcell timing_arc_sets]
|
||||||
}
|
}
|
||||||
return $arc_sets
|
return $arc_sets
|
||||||
}
|
}
|
||||||
|
|
|
||||||
40
tcl/StaTcl.i
40
tcl/StaTcl.i
|
|
@ -576,6 +576,16 @@ using namespace sta;
|
||||||
Tcl_SetObjResult(interp, obj);
|
Tcl_SetObjResult(interp, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%typemap(out) const TimingArcSetSeq& {
|
||||||
|
Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
|
||||||
|
const TimingArcSetSeq *arc_sets = $1;
|
||||||
|
for (TimingArcSet *arc_set : *arc_sets) {
|
||||||
|
Tcl_Obj *obj = SWIG_NewInstanceObj(arc_set, SWIGTYPE_p_TimingArcSet, false);
|
||||||
|
Tcl_ListObjAppendElement(interp, list, obj);
|
||||||
|
}
|
||||||
|
Tcl_SetObjResult(interp, list);
|
||||||
|
}
|
||||||
|
|
||||||
%typemap(out) Wireload* {
|
%typemap(out) Wireload* {
|
||||||
Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
|
Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
|
||||||
Tcl_SetObjResult(interp, obj);
|
Tcl_SetObjResult(interp, obj);
|
||||||
|
|
@ -1238,16 +1248,6 @@ using namespace sta;
|
||||||
Tcl_SetObjResult(interp, obj);
|
Tcl_SetObjResult(interp, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
%typemap(out) TimingArcSetArcIterator* {
|
|
||||||
Tcl_Obj *obj=SWIG_NewInstanceObj($1, $1_descriptor, false);
|
|
||||||
Tcl_SetObjResult(interp, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
%typemap(out) LibertyCellTimingArcSetIterator* {
|
|
||||||
Tcl_Obj *obj=SWIG_NewInstanceObj($1, $1_descriptor, false);
|
|
||||||
Tcl_SetObjResult(interp, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
%typemap(out) CheckErrorSeq & {
|
%typemap(out) CheckErrorSeq & {
|
||||||
Tcl_Obj *error_list = Tcl_NewListObj(0, nullptr);
|
Tcl_Obj *error_list = Tcl_NewListObj(0, nullptr);
|
||||||
CheckErrorSeq *check_errors = $1;
|
CheckErrorSeq *check_errors = $1;
|
||||||
|
|
@ -1649,13 +1649,6 @@ private:
|
||||||
~TimingArcSet();
|
~TimingArcSet();
|
||||||
};
|
};
|
||||||
|
|
||||||
class LibertyCellTimingArcSetIterator
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
LibertyCellTimingArcSetIterator();
|
|
||||||
~LibertyCellTimingArcSetIterator();
|
|
||||||
};
|
|
||||||
|
|
||||||
class TimingArcSetArcIterator
|
class TimingArcSetArcIterator
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
@ -5714,8 +5707,11 @@ find_liberty_ports_matching(const char *pattern,
|
||||||
LibertyCellPortIterator *
|
LibertyCellPortIterator *
|
||||||
liberty_port_iterator() { return new LibertyCellPortIterator(self); }
|
liberty_port_iterator() { return new LibertyCellPortIterator(self); }
|
||||||
|
|
||||||
LibertyCellTimingArcSetIterator *
|
const TimingArcSetSeq &
|
||||||
timing_arc_set_iterator() { return new LibertyCellTimingArcSetIterator(self); }
|
timing_arc_sets()
|
||||||
|
{
|
||||||
|
return self->timingArcSets();
|
||||||
|
}
|
||||||
|
|
||||||
} // LibertyCell methods
|
} // LibertyCell methods
|
||||||
|
|
||||||
|
|
@ -5816,12 +5812,6 @@ full_name()
|
||||||
|
|
||||||
} // TimingArcSet methods
|
} // TimingArcSet methods
|
||||||
|
|
||||||
%extend LibertyCellTimingArcSetIterator {
|
|
||||||
bool has_next() { return self->hasNext(); }
|
|
||||||
TimingArcSet *next() { return self->next(); }
|
|
||||||
void finish() { delete self; }
|
|
||||||
}
|
|
||||||
|
|
||||||
%extend TimingArc {
|
%extend TimingArc {
|
||||||
LibertyPort *from() { return self->from(); }
|
LibertyPort *from() { return self->from(); }
|
||||||
LibertyPort *to() { return self->to(); }
|
LibertyPort *to() { return self->to(); }
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue