Merge pull request #169 from openroadie/master

Update to latest OpenSTA
This commit is contained in:
Harsh Vardhan 2023-06-15 11:30:45 -07:00 committed by GitHub
commit 2609cc89ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
73 changed files with 809 additions and 605 deletions

View File

@ -63,7 +63,7 @@ open source projects are. The copyright and develpment are exclusive to Parallax
Software. OpenSTA does not accept external code contributions.
The official git repository is located at
https://github.com/jjcherry56/OpenSTA.git. Any forks from this code
https://github.com/parallaxsw/OpenSTA.git. Any forks from this code
base have not passed extensive regression testing which is not
publicly available.
@ -78,14 +78,14 @@ work, but these are the versions used for development.
```
from Ubuntu Xcode
18.04.1 11.3
cmake 3.10.2 3.10.2 3.16.2
clang 9.1.0 11.0.0
gcc 3.3.2 7.3.0
22.04.2 11.3
cmake 3.10.2 3.24.2 3.16.2
clang 9.1.0 14.0.3
gcc 3.3.2 11.3.0
tcl 8.4 8.6 8.6.6
swig 1.3.28 3.0.12 4.0.1
bison 1.35 3.0.4 3.5
flex 2.5.4 2.6.4 2.5.35
swig 1.3.28 4.1.0 4.0.1
bison 1.35 3.0.2 3.8.2
flex 2.5.4 2.6.4 2.6.4
```
Note that flex versions before 2.6.4 contain 'register' declarations that

View File

@ -17,7 +17,7 @@
#include "StaMain.hh"
#include <tcl.h>
#include <stdlib.h>
#include <cstdlib>
#include <sys/stat.h>
#include "Machine.hh"

View File

@ -20,7 +20,7 @@
#include "ArnoldiDelayCalc.hh"
#include <stdio.h>
#include <cstdio>
#include <cmath> // abs
#include "Report.hh"

View File

@ -20,11 +20,6 @@
#include "ArnoldiReduce.hh"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include "Debug.hh"
#include "MinMax.hh"
#include "Sdc.hh"

View File

@ -16,6 +16,8 @@
#include "LumpedCapDelayCalc.hh"
#include <cmath> // isnan
#include "Debug.hh"
#include "Units.hh"
#include "TimingArc.hh"
@ -29,6 +31,8 @@
namespace sta {
using std::isnan;
ArcDelayCalc *
makeLumpedCapDelayCalc(StaState *sta)
{

View File

@ -17,6 +17,7 @@
#pragma once
#include <string>
#include "MinMax.hh"
#include "LibertyClass.hh"
#include "NetworkClass.hh"

View File

@ -16,7 +16,7 @@
#pragma once
#include <string.h> // memcpy
#include <cstring> // memcpy
#include <vector>
#include "ObjectId.hh"

View File

@ -82,8 +82,6 @@ public:
const char *filename(const Cell *cell) override;
Port *findPort(const Cell *cell,
const char *name) const override;
PortSeq findPortsMatching(const Cell *cell,
const PatternMatch *pattern) const override;
bool isLeaf(const Cell *cell) const override;
CellPortIterator *portIterator(const Cell *cell) const override;
CellPortBitIterator *portBitIterator(const Cell *cell) const override;

View File

@ -16,7 +16,8 @@
#pragma once
#include <stdarg.h>
#include <cstdarg>
#include "Map.hh"
#include "StringUtil.hh"

View File

@ -61,7 +61,8 @@ public:
ExceptionThruSeq *thrus() const { return thrus_; }
ExceptionTo *to() const { return to_; }
ExceptionPt *firstPt();
bool intersectsPts(ExceptionPath *exception) const;
bool intersectsPts(ExceptionPath *exception,
const Network *network) const;
const MinMaxAll *minMax() const { return min_max_; }
virtual bool matches(const MinMax *min_max,
bool exact) const;
@ -71,7 +72,8 @@ public:
virtual bool resetMatch(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
const MinMaxAll *min_max);
const MinMaxAll *min_max,
const Network *network);
// The priority remains the same even though pin/clock/net/inst objects
// are added to the exceptions points during exception merging because
// only exceptions with the same priority are merged.
@ -262,7 +264,8 @@ public:
virtual bool resetMatch(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
const MinMaxAll *min_max);
const MinMaxAll *min_max,
const Network *network);
virtual int typePriority() const;
virtual bool tighterThan(ExceptionPath *exception) const;
};
@ -424,7 +427,8 @@ public:
const Network *network);
ExceptionFrom *clone(const Network *network);
virtual bool isFrom() const { return true; }
bool intersectsPts(ExceptionFrom *from) const;
bool intersectsPts(ExceptionFrom *from,
const Network *network) const;
virtual int typePriority() const { return 0; }
protected:
@ -448,7 +452,8 @@ public:
virtual bool isTo() const { return true; }
const char *asString(const Network *network) const;
const RiseFallBoth *endTransition() { return end_rf_; }
bool intersectsPts(ExceptionTo *to) const;
bool intersectsPts(ExceptionTo *to,
const Network *network) const;
virtual int typePriority() const { return 1; }
bool matches(const Pin *pin,
const ClockEdge *clk_edge,
@ -511,7 +516,8 @@ public:
const Network *network) const;
virtual void mergeInto(ExceptionPt *pt,
const Network *network);
bool intersectsPts(ExceptionThru *thru) const;
bool intersectsPts(ExceptionThru *thru,
const Network *network) const;
virtual int typePriority() const { return 2; }
virtual size_t objectCount() const;
virtual void connectPinAfter(PinSet *drvrs,

View File

@ -16,6 +16,8 @@
#pragma once
#include <limits>
#include "ObjectId.hh"
#include "Set.hh"
#include "Vector.hh"
@ -45,6 +47,8 @@ typedef int DcalcAPIndex;
typedef int TagGroupIndex;
typedef Vector<GraphLoop*> GraphLoopSeq;
static constexpr int level_max = std::numeric_limits<Level>::max();
// 16,777,215 tags
static const int tag_group_index_bits = 24;
static const TagGroupIndex tag_group_index_max = (1<<tag_group_index_bits)-1;

View File

@ -17,6 +17,7 @@
#pragma once
#include <string>
#include "GraphClass.hh"
#include "DcalcAnalysisPt.hh"
#include "StaState.hh"

View File

@ -64,7 +64,7 @@
#define vsnprint vsnprintf
#endif
#include <stddef.h> // size_t
#include <cstddef> // size_t
namespace sta {

View File

@ -148,7 +148,7 @@ public:
virtual Port *findPort(const Cell *cell,
const char *name) const = 0;
virtual PortSeq findPortsMatching(const Cell *cell,
const PatternMatch *pattern) const = 0;
const PatternMatch *pattern) const;
virtual bool isLeaf(const Cell *cell) const = 0;
virtual CellPortIterator *portIterator(const Cell *cell) const = 0;
// Iterate over port bits (expanded buses).

View File

@ -17,6 +17,7 @@
#pragma once
#include <cstdint>
#include "Set.hh"
#include "Vector.hh"
#include "Iterator.hh"
@ -145,6 +146,9 @@ public:
static int compare(const InstanceSet *set1,
const InstanceSet *set2,
const Network *network);
static bool intersects(const InstanceSet *set1,
const InstanceSet *set2,
const Network *network);
};
class PinSet : public Set<const Pin*, PinIdLess>
@ -155,6 +159,9 @@ public:
static int compare(const PinSet *set1,
const PinSet *set2,
const Network *network);
static bool intersects(const PinSet *set1,
const PinSet *set2,
const Network *network);
};
class NetSet : public Set<const Net*, NetIdLess>
@ -165,6 +172,9 @@ public:
static int compare(const NetSet *set1,
const NetSet *set2,
const Network *network);
static bool intersects(const NetSet *set1,
const NetSet *set2,
const Network *network);
};
} // namespace

View File

@ -17,6 +17,7 @@
#pragma once
#include <complex>
#include "StaState.hh"
#include "LibertyClass.hh"
#include "NetworkClass.hh"

View File

@ -60,27 +60,32 @@ parseBusName(const char *name,
// bus_name is set to null if name is not a range.
// Caller must delete returned bus_name string.
void
parseBusRange(const char *name,
const char brkt_left,
const char brkt_right,
char escape,
// Return values.
bool &is_bus,
string &bus_name,
int &from,
int &to);
parseBusName(const char *name,
const char brkt_left,
const char brkt_right,
char escape,
// Return values.
bool &is_bus,
bool &is_range,
string &bus_name,
int &from,
int &to,
bool &subscript_wild);
// brkt_lefts and brkt_rights are corresponding strings of legal
// bus brackets such as "[(<" and "])>".
void
parseBusRange(const char *name,
const char *brkts_left,
const char *brkts_right,
const char escape,
// Return values.
bool &is_bus,
string &bus_name,
int &from,
int &to);
parseBusName(const char *name,
const char *brkts_left,
const char *brkts_right,
const char escape,
// Return values.
bool &is_bus,
bool &is_range,
string &bus_name,
int &from,
int &to,
bool &subscript_wild);
// Insert escapes before ch1 and ch2 in token.
string

View File

@ -66,10 +66,8 @@ public:
protected:
VertexId vertex_id_;
unsigned int tag_index_:tag_index_bits;
TagIndex tag_index_;
bool is_enum_:1;
private:
};
} // namespace

View File

@ -17,6 +17,7 @@
#pragma once
#include <string>
#include "Error.hh"
// Don't require all of tcl.h.

View File

@ -17,9 +17,10 @@
#pragma once
#include <stdio.h>
#include <stdarg.h>
#include <cstdarg>
#include <string>
#include <mutex>
#include "Machine.hh" // __attribute__
struct Tcl_Interp;

View File

@ -17,6 +17,7 @@
#pragma once
#include <tcl.h>
#include "Report.hh"
namespace sta {

View File

@ -16,6 +16,8 @@
#pragma once
#include <limits>
#include "Vector.hh"
#include "Set.hh"
#include "Map.hh"
@ -97,7 +99,7 @@ protected:
};
typedef int PathAPIndex;
typedef unsigned TagIndex;
typedef uint32_t TagIndex;
typedef Vector<Tag*> TagSeq;
typedef Vector<MinPulseWidthCheck*> MinPulseWidthCheckSeq;
typedef Vector<MinPeriodCheck*> MinPeriodCheckSeq;
@ -122,9 +124,10 @@ enum class ReportPathFormat { full,
json
};
static const int tag_index_bits = 24;
static const TagIndex tag_index_max = (1 << tag_index_bits) - 1;
static const TagIndex tag_index_max = std::numeric_limits<uint32_t>::max();
static const TagIndex tag_index_null = tag_index_max;
static const int path_ap_index_bit_count = 4;
static const int path_ap_index_bit_count = 8;
// One path analysis point per corner min/max.
static const int corner_count_max = (1 << path_ap_index_bit_count) / 2;
} // namespace

View File

@ -17,8 +17,6 @@
#pragma once
#include <set>
#include <math.h>
#include <algorithm>
namespace sta {
@ -70,12 +68,10 @@ public:
this->clear();
}
static bool
intersects(const std::set<KEY, CMP> &set1,
const std::set<KEY, CMP> &set2);
static bool
intersects(const std::set<KEY, CMP> *set1,
const std::set<KEY, CMP> *set2);
const std::set<KEY, CMP> *set2,
CMP key_less);
// Java style container itererator
// Set::Iterator<Key*> iter(set);
@ -172,47 +168,24 @@ Set<KEY, CMP>::isSubset(const std::set<KEY, CMP> *set2)
}
}
template <class KEY, class CMP>
bool
Set<KEY, CMP>::intersects(const std::set<KEY, CMP> &set1,
const std::set<KEY, CMP> &set2)
{
return intersects(&set1, &set2);
}
template <class KEY, class CMP>
bool
Set<KEY, CMP>::intersects(const std::set<KEY, CMP> *set1,
const std::set<KEY, CMP> *set2)
const std::set<KEY, CMP> *set2,
CMP key_less)
{
if (set1 && !set1->empty()
&& set2 && !set2->empty()) {
const std::set<KEY, CMP> *small = set1;
const std::set<KEY, CMP> *big = set2;
if (small->size() > big->size()) {
small = set2;
big = set1;
}
auto iter1 = big->begin();
auto last1 = big->end();
auto iter2 = small->begin();
auto last2 = small->end();
if (static_cast<float>(small->size() + big->size()) < (small->size() * log(static_cast<float>(big->size())))) {
while (iter1 != last1 && iter2 != last2) {
if (*iter1 < *iter2)
++iter1;
else if (*iter2 < *iter1)
++iter2;
else
return true;
}
}
else {
for (/* empty */; iter2 != last2; ++iter2) {
const KEY key2 = *iter2;
if (big->find(key2) != last1)
return true;
}
if (set1 && set2) {
auto iter1 = set1->begin();
auto end1 = set1->end();
auto iter2 = set2->begin();
auto end2 = set2->end();
while (iter1 != end1 && iter2 != end2) {
if (key_less(*iter1, *iter2))
iter1++;
else if (key_less(*iter2, *iter1))
iter2++;
else
return true;
}
}
return false;

View File

@ -16,7 +16,7 @@
#pragma once
#include <stddef.h> // size_t
#include <cstddef> // size_t
namespace sta {

View File

@ -16,9 +16,10 @@
#pragma once
#include <stdarg.h>
#include <string.h>
#include <cstdarg>
#include <cstring>
#include <string>
#include "Machine.hh" // __attribute__
#include "Vector.hh"

View File

@ -362,6 +362,7 @@ public:
bool &extrapolated) const;
float findValue(float axis_value1) const;
float findValueClip(float axis_value1) const;
float findValueClipZero(float axis_value1) const;
FloatSeq *values() const { return values_; }
using Table::findValue;
@ -506,8 +507,8 @@ public:
Table1 *ref_times);
~OutputWaveforms();
const RiseFall *rf() const { return rf_; }
bool inBounds(float in_slew,
float load_cap) const;
TableAxisPtr slewAxis() const { return slew_axis_; }
TableAxisPtr capAxis() const { return cap_axis_; }
Table1 voltageWaveform(float in_slew,
float load_cap);
float voltageTime(float in_slew,
@ -515,6 +516,12 @@ public:
float voltage);
const Table1 *currentWaveform(float slew,
float cap);
float timeCurrent(float slew,
float cap,
float time);
float voltageCurrent(float slew,
float cap,
float volt);
float referenceTime(float slew);
void setVdd(float vdd);
static bool checkAxes(TableTemplate *tbl_template);
@ -525,6 +532,10 @@ private:
float cap);
FloatSeq *voltageTimes(size_t wave_index,
float cap);
void findVoltages(size_t wave_index,
float cap);
const Table1 *voltageCurrents(size_t wave_index,
float cap);
// Row.
TableAxisPtr slew_axis_;
@ -532,6 +543,7 @@ private:
TableAxisPtr cap_axis_;
const RiseFall *rf_;
Table1Seq current_waveforms_;
Table1Seq voltage_currents_;
FloatTable voltage_times_;
Table1 *ref_times_;
float vdd_;

View File

@ -17,6 +17,7 @@
#pragma once
#include <string>
#include "Delay.hh"
#include "LibertyClass.hh"

View File

@ -18,6 +18,7 @@
#include <array>
#include <vector>
#include "Iterator.hh"
#include "Map.hh"
#include "StringUtil.hh"

View File

@ -27,7 +27,7 @@
#else // ZLIB_FOUND
#include <stdio.h>
#include <cstdio>
#define gzFile FILE*
#define gzopen fopen

View File

@ -15,8 +15,8 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <stdlib.h>
#include <string.h>
#include <cstdlib>
#include <cstring>
#include "StringUtil.hh"
#include "liberty/LibertyParser.hh"

View File

@ -16,8 +16,8 @@
#include "LibertyParser.hh"
#include <stdio.h>
#include <string.h>
#include <cstdio>
#include <cstring>
#include "Report.hh"
#include "Error.hh"

View File

@ -16,8 +16,8 @@
#include "LibertyReader.hh"
#include <ctype.h>
#include <stdlib.h>
#include <cctype>
#include <cstdlib>
#include "Report.hh"
#include "Debug.hh"
@ -5637,13 +5637,13 @@ PortNameBitIterator::init(const char *port_name)
else {
// Check for bus range.
LibertyLibrary *library = visitor_->library();
bool is_bus;
bool is_bus, is_range, subscript_wild;
string bus_name;
int from, to;
parseBusRange(port_name, library->busBrktLeft(),
library->busBrktRight(), '\\',
is_bus, bus_name, from, to);
if (is_bus) {
parseBusName(port_name, library->busBrktLeft(),
library->busBrktRight(), '\\',
is_bus, is_range, bus_name, from, to, subscript_wild);
if (is_range) {
port = visitor_->findPort(port_name);
if (port) {
if (port->isBus()) {

View File

@ -16,7 +16,7 @@
#include "LibertyWriter.hh"
#include <stdlib.h>
#include <cstdlib>
#include <algorithm>
#include "Units.hh"

View File

@ -908,6 +908,27 @@ Table1::findValueClip(float axis_value1) const
}
}
float
Table1::findValueClipZero(float axis_value1) const
{
if (axis1_->size() == 1)
return this->value(axis_value1);
else {
size_t axis_index1 = axis1_->findAxisIndex(axis_value1);
float x1 = axis_value1;
float x1l = axis1_->axisValue(axis_index1);
float x1u = axis1_->axisValue(axis_index1 + 1);
if (x1 < x1l || x1 > x1u)
return 0.0;
else {
float y1 = this->value(axis_index1);
float y2 = this->value(axis_index1 + 1);
float dx1 = (x1 - x1l) / (x1u - x1l);
return (1 - dx1) * y1 + dx1 * y2;
}
}
}
string
Table1::reportValue(const char *result_name, const
LibertyLibrary *library,
@ -1592,6 +1613,7 @@ OutputWaveforms::OutputWaveforms(TableAxisPtr slew_axis,
cap_axis_(cap_axis),
rf_(rf),
current_waveforms_(current_waveforms),
voltage_currents_(current_waveforms.size()),
voltage_times_(current_waveforms.size()),
ref_times_(ref_times),
vdd_(0.0)
@ -1601,6 +1623,7 @@ OutputWaveforms::OutputWaveforms(TableAxisPtr slew_axis,
OutputWaveforms::~OutputWaveforms()
{
current_waveforms_.deleteContents();
voltage_currents_.deleteContents();
voltage_times_.deleteContents();
delete ref_times_;
}
@ -1622,14 +1645,6 @@ OutputWaveforms::checkAxes(TableTemplate *tbl_template)
&& axis3->variable() == TableAxisVariable::time);
}
bool
OutputWaveforms::inBounds(float in_slew,
float load_cap) const
{
return slew_axis_->inBounds(in_slew)
&& cap_axis_->inBounds(load_cap);
}
const Table1 *
OutputWaveforms::currentWaveform(float slew,
float cap)
@ -1640,6 +1655,48 @@ OutputWaveforms::currentWaveform(float slew,
return current_waveforms_[wave_index];
}
float
OutputWaveforms::timeCurrent(float slew,
float cap,
float time)
{
size_t slew_index = slew_axis_->findAxisIndex(slew);
size_t cap_index = cap_axis_->findAxisIndex(cap);
size_t slew_count = slew_axis_->size();
size_t wave_index00 = slew_index * slew_count + cap_index;
size_t wave_index01 = slew_index * slew_count + (cap_index + 1);
size_t wave_index10 = (slew_index + 1) * slew_count + cap_index;
size_t wave_index11 = (slew_index + 1) * slew_count + (cap_index + 1);
const Table1 *waveform00 = current_waveforms_[wave_index00];
const Table1 *waveform01 = current_waveforms_[wave_index01];
const Table1 *waveform10 = current_waveforms_[wave_index10];
const Table1 *waveform11 = current_waveforms_[wave_index11];
// Interpolate waveform samples at voltage steps.
size_t index1 = slew_index;
size_t index2 = cap_index;
float x1 = slew;
float x2 = cap;
float x1l = slew_axis_->axisValue(index1);
float x1u = slew_axis_->axisValue(index1 + 1);
float dx1 = (x1 - x1l) / (x1u - x1l);
float x2l = cap_axis_->axisValue(index2);
float x2u = cap_axis_->axisValue(index2 + 1);
float dx2 = (x2 - x2l) / (x2u - x2l);
float y00 = waveform00->findValueClipZero(time);
float y01 = waveform01->findValueClipZero(time);
float y10 = waveform10->findValueClipZero(time);
float y11 = waveform11->findValueClipZero(time);
float current
= (1 - dx1) * (1 - dx2) * y00
+ dx1 * (1 - dx2) * y10
+ dx1 * dx2 * y11
+ (1 - dx1) * dx2 * y01;
return current;
}
float
OutputWaveforms::referenceTime(float slew)
{
@ -1652,6 +1709,23 @@ OutputWaveforms::setVdd(float vdd)
vdd_ = vdd;
}
Table1
OutputWaveforms::voltageWaveform(float slew,
float cap)
{
float volt_step = vdd_ / voltage_waveform_step_count_;
FloatSeq *times = new FloatSeq;
FloatSeq *volts = new FloatSeq;
for (size_t v = 0; v <= voltage_waveform_step_count_; v++) {
float volt = v * volt_step;
float time = voltageTime(slew, cap, volt);
times->push_back(time);
volts->push_back(volt);
}
TableAxisPtr time_axis = make_shared<TableAxis>(TableAxisVariable::time, times);
return Table1(volts, time_axis);
}
float
OutputWaveforms::voltageTime(float slew,
float cap,
@ -1691,23 +1765,6 @@ OutputWaveforms::voltageTime(float slew,
return time;
}
Table1
OutputWaveforms::voltageWaveform(float slew,
float cap)
{
float volt_step = vdd_ / voltage_waveform_step_count_;
FloatSeq *times = new FloatSeq;
FloatSeq *volts = new FloatSeq;
for (size_t v = 0; v <= voltage_waveform_step_count_; v++) {
float volt = v * volt_step;
float time = voltageTime(slew, cap, volt);
times->push_back(time);
volts->push_back(volt);
}
TableAxisPtr time_axis = make_shared<TableAxis>(TableAxisVariable::time, times);
return Table1(volts, time_axis);
}
float
OutputWaveforms::voltageTime1(float voltage,
size_t wave_index,
@ -1728,57 +1785,128 @@ OutputWaveforms::voltageTimes(size_t wave_index,
{
FloatSeq *voltage_times = voltage_times_[wave_index];
if (voltage_times == nullptr) {
// Integrate current waveform to find voltage waveform.
// i = C dv/dt
FloatSeq volts;
Table1 *currents = current_waveforms_[wave_index];
TableAxisPtr time_axis = currents->axis1();
float prev_time = time_axis->axisValue(0);
float prev_current = currents->value(0);
float voltage = 0.0;
volts.push_back(voltage);
bool always_rise = true;
bool invert = (always_rise && rf_ == RiseFall::fall());
for (size_t i = 1; i < time_axis->size(); i++) {
float time = time_axis->axisValue(i);
float current = currents->value(i);
float dv = (current + prev_current) / 2.0 * (time - prev_time) / cap;
voltage += invert ? -dv : dv;
volts.push_back(voltage);
prev_time = time;
prev_current = current;
}
// Sample the voltage waveform at uniform intervals to speed up
// voltage time lookup.
voltage_times = new FloatSeq;
float volt_step = vdd_ / voltage_waveform_step_count_;
size_t i = 0;
float time0 = time_axis->axisValue(i);
float volt0 = volts[i];
i = 1;
float time1 = time_axis->axisValue(i);
float volt1 = volts[i];
for (size_t v = 0; v <= voltage_waveform_step_count_; v++) {
float volt3 = v * volt_step;
while (volt3 > volt1 && i < volts.size() - 1) {
time0 = time1;
volt0 = volt1;
i++;
time1 = time_axis->axisValue(i);
volt1 = volts[i];
}
float time3 = time0 + (time1 - time0) * (volt3 - volt0) / (volt1 - volt0);
if (time3 < 0.0)
printf("luse\n");
//printf("%.2f %.2e\n", volt3, time3);
voltage_times->push_back(time3);
}
voltage_times_[wave_index] = voltage_times;
findVoltages(wave_index, cap);
voltage_times = voltage_times_[wave_index];
}
return voltage_times;
}
void
OutputWaveforms::findVoltages(size_t wave_index,
float cap)
{
if (vdd_ == 0.0)
criticalError(239, "output waveform vdd = 0.0");
// Integrate current waveform to find voltage waveform.
// i = C dv/dt
FloatSeq volts;
Table1 *currents = current_waveforms_[wave_index];
TableAxisPtr time_axis = currents->axis1();
float prev_time = time_axis->axisValue(0);
float prev_current = currents->value(0);
float voltage = 0.0;
volts.push_back(voltage);
bool always_rise = true;
bool invert = (always_rise && rf_ == RiseFall::fall());
for (size_t i = 1; i < time_axis->size(); i++) {
float time = time_axis->axisValue(i);
float current = currents->value(i);
float dv = (current + prev_current) / 2.0 * (time - prev_time) / cap;
voltage += invert ? -dv : dv;
volts.push_back(voltage);
prev_time = time;
prev_current = current;
}
// Make voltage -> current table.
FloatSeq *axis_volts = new FloatSeq(volts);
TableAxisPtr volt_axis =
make_shared<TableAxis>(TableAxisVariable::input_voltage, axis_volts);
FloatSeq *currents1 = new FloatSeq(*currents->values());
Table1 *volt_currents = new Table1(currents1, volt_axis);
voltage_currents_[wave_index] = volt_currents;
// Sample the voltage waveform at uniform intervals to speed up
// voltage time lookup.
FloatSeq *voltage_times = new FloatSeq;
float volt_step = vdd_ / voltage_waveform_step_count_;
size_t i = 0;
float time0 = time_axis->axisValue(i);
float volt0 = volts[i];
i = 1;
float time1 = time_axis->axisValue(i);
float volt1 = volts[i];
for (size_t v = 0; v <= voltage_waveform_step_count_; v++) {
float volt3 = v * volt_step;
while (volt3 > volt1 && i < volts.size() - 1) {
time0 = time1;
volt0 = volt1;
i++;
time1 = time_axis->axisValue(i);
volt1 = volts[i];
}
float time3 = time0 + (time1 - time0) * (volt3 - volt0) / (volt1 - volt0);
voltage_times->push_back(time3);
}
voltage_times_[wave_index] = voltage_times;
}
float
OutputWaveforms::voltageCurrent(float slew,
float cap,
float volt)
{
size_t slew_index = slew_axis_->findAxisIndex(slew);
size_t cap_index = cap_axis_->findAxisIndex(cap);
size_t slew_count = slew_axis_->size();
size_t wave_index00 = slew_index * slew_count + cap_index;
size_t wave_index01 = slew_index * slew_count + (cap_index + 1);
size_t wave_index10 = (slew_index + 1) * slew_count + cap_index;
size_t wave_index11 = (slew_index + 1) * slew_count + (cap_index + 1);
float cap0 = cap_axis_->axisValue(cap_index);
float cap1 = cap_axis_->axisValue(cap_index + 1);
// Interpolate waveform samples at voltage steps.
size_t index1 = slew_index;
size_t index2 = cap_index;
float x1 = slew;
float x2 = cap;
float x1l = slew_axis_->axisValue(index1);
float x1u = slew_axis_->axisValue(index1 + 1);
float dx1 = (x1 - x1l) / (x1u - x1l);
float x2l = cap_axis_->axisValue(index2);
float x2u = cap_axis_->axisValue(index2 + 1);
float dx2 = (x2 - x2l) / (x2u - x2l);
const Table1 *waveform00 = voltageCurrents(wave_index00, cap0);
const Table1 *waveform01 = voltageCurrents(wave_index01, cap1);
const Table1 *waveform10 = voltageCurrents(wave_index10, cap0);
const Table1 *waveform11 = voltageCurrents(wave_index11, cap1);
float y00 = waveform00->findValueClipZero(volt);
float y01 = waveform01->findValueClipZero(volt);
float y10 = waveform10->findValueClipZero(volt);
float y11 = waveform11->findValueClipZero(volt);
float current
= (1 - dx1) * (1 - dx2) * y00
+ dx1 * (1 - dx2) * y10
+ dx1 * dx2 * y11
+ (1 - dx1) * dx2 * y01;
return current;
}
const Table1 *
OutputWaveforms::voltageCurrents(size_t wave_index,
float cap)
{
const Table1 *waveform = voltage_currents_[wave_index];
if (waveform == nullptr) {
findVoltages(wave_index, cap);
waveform = voltage_currents_[wave_index];
}
return waveform;
}
////////////////////////////////////////////////////////////////
DriverWaveform::DriverWaveform(const char *name,

View File

@ -1,180 +1,180 @@
0001 DmpCeff.cc:1597 cell %s delay model not supported on SPF parasitics by DMP delay calculator
0002 Liberty.cc:750 cell %s/%s port %s not found in cell %s/%s.
0003 Liberty.cc:776 cell %s/%s %s -> %s timing group %s not found in cell %s/%s.
0004 Liberty.cc:1728 cell %s/%s %s -> %s latch enable %s_edge is inconsistent with %s -> %s setup_%s check.
0005 Liberty.cc:1742 cell %s/%s %s -> %s latch enable %s_edge is inconsistent with latch group enable function positive sense.
0006 Liberty.cc:1750 cell %s/%s %s -> %s latch enable %s_edge is inconsistent with latch group enable function negative sense.
0002 Liberty.cc:770 cell %s/%s port %s not found in cell %s/%s.
0003 Liberty.cc:796 cell %s/%s %s -> %s timing group %s not found in cell %s/%s.
0004 Liberty.cc:1746 cell %s/%s %s -> %s latch enable %s_edge is inconsistent with %s -> %s setup_%s check.
0005 Liberty.cc:1760 cell %s/%s %s -> %s latch enable %s_edge is inconsistent with latch group enable function positive sense.
0006 Liberty.cc:1768 cell %s/%s %s -> %s latch enable %s_edge is inconsistent with latch group enable function negative sense.
0007 LibertyExpr.cc:82 %s references unknown port %s.
0008 ConcreteNetwork.cc:1917 cell type %s can not be linked.
0009 CycleAccting.cc:87 No common period was found between clocks %s and %s.
0010 Genclks.cc:274 no master clock found for generated clock %s.
0013 Genclks.cc:938 generated clock %s source pin %s missing paths from master clock %s.
0015 Sim.cc:865 propagated logic value %c differs from constraint value of %c on pin %s.
0016 LibertyReader.cc:1049 default_max_fanout is 0.0.
0016 LibertyReader.cc:1037 default_max_fanout is 0.0.
0017 Sta.cc:2093 '%s' is not a valid endpoint.
0018 Sta.cc:2017 '%s' is not a valid start point.
0021 SpefParse.yy:805 %d is not positive.
0022 SpefParse.yy:814 %.4f is not positive.
0023 SpefParse.yy:820 %.4f is not positive.
0024 WritePathSpice.cc:458 pg_pin %s/%s voltage %s not found,
0025 WritePathSpice.cc:465 Liberty pg_port %s/%s missing voltage_name attribute,
0026 WritePathSpice.cc:1037 %s pg_port %s not found,
0027 WritePathSpice.cc:1092 no register/latch found for path from %s to %s,
0028 WritePathSpice.cc:1464 The subkct file %s is missing definitions for %s
0029 WritePathSpice.cc:1562 subckt %s port %s has no corresponding liberty port, pg_port and is not power or ground.
0030 LibertyReader.cc:628 library missing name.
0031 LibertyReader.cc:660 default_wire_load %s not found.
0032 LibertyReader.cc:671 default_wire_selection %s not found.
0033 LibertyReader.cc:693 input_threshold_pct_%s not found.
0034 LibertyReader.cc:697 output_threshold_pct_%s not found.
0035 LibertyReader.cc:701 slew_lower_threshold_pct_%s not found.
0036 LibertyReader.cc:705 slew_upper_threshold_pct_%s not found.
0037 LibertyReader.cc:710 Library %s is missing one or more thresholds.
0038 LibertyReader.cc:800 unknown unit multiplier %s.
0039 LibertyReader.cc:819 unknown unit scale %c.
0040 LibertyReader.cc:822 unknown unit suffix %s.
0041 LibertyReader.cc:848 capacitive_load_units are not ff or pf.
0042 LibertyReader.cc:851 capacitive_load_units are not a string.
0043 LibertyReader.cc:854 capacitive_load_units missing suffix.
0044 LibertyReader.cc:857 capacitive_load_units scale is not a float.
0045 LibertyReader.cc:860 capacitive_load_units missing scale and suffix.
0046 LibertyReader.cc:863 capacitive_load_unit missing values suffix.
0047 LibertyReader.cc:881 delay_model %s not supported.
0048 LibertyReader.cc:885 delay_model %s not supported.
0049 LibertyReader.cc:889 delay_model %s not supported.
0050 LibertyReader.cc:894 delay_model %s not supported.
0024 WritePathSpice.cc:508 pg_pin %s/%s voltage %s not found,
0025 WritePathSpice.cc:515 Liberty pg_port %s/%s missing voltage_name attribute,
0026 WritePathSpice.cc:1094 %s pg_port %s not found,
0027 WritePathSpice.cc:1149 no register/latch found for path from %s to %s,
0028 WritePathSpice.cc:1615 The subkct file %s is missing definitions for %s
0029 WritePathSpice.cc:1713 subckt %s port %s has no corresponding liberty port, pg_port and is not power or ground.
0030 LibertyReader.cc:631 library missing name.
0031 LibertyReader.cc:657 default_wire_load %s not found.
0032 LibertyReader.cc:668 default_wire_selection %s not found.
0033 LibertyReader.cc:690 input_threshold_pct_%s not found.
0034 LibertyReader.cc:694 output_threshold_pct_%s not found.
0035 LibertyReader.cc:698 slew_lower_threshold_pct_%s not found.
0036 LibertyReader.cc:702 slew_upper_threshold_pct_%s not found.
0037 LibertyReader.cc:707 Library %s is missing one or more thresholds.
0038 LibertyReader.cc:786 unknown unit multiplier %s.
0039 LibertyReader.cc:807 unknown unit scale %c.
0040 LibertyReader.cc:810 unknown unit suffix %s.
0041 LibertyReader.cc:836 capacitive_load_units are not ff or pf.
0042 LibertyReader.cc:839 capacitive_load_units are not a string.
0043 LibertyReader.cc:842 capacitive_load_units missing suffix.
0044 LibertyReader.cc:845 capacitive_load_units scale is not a float.
0045 LibertyReader.cc:848 capacitive_load_units missing scale and suffix.
0046 LibertyReader.cc:851 capacitive_load_unit missing values suffix.
0047 LibertyReader.cc:869 delay_model %s not supported.
0048 LibertyReader.cc:873 delay_model %s not supported.
0049 LibertyReader.cc:877 delay_model %s not supported.
0050 LibertyReader.cc:882 delay_model %s not supported.
.
0051 LibertyReader.cc:897 unknown delay_model %s
0051 LibertyReader.cc:885 unknown delay_model %s
.
0052 LibertyReader.cc:916 unknown bus_naming_style format.
0053 LibertyReader.cc:594 library %s already exists.
0054 LibertyReader.cc:937 voltage_map voltage is not a float.
0055 LibertyReader.cc:940 voltage_map missing voltage.
0056 LibertyReader.cc:943 voltage_map supply name is not a string.
0057 LibertyReader.cc:946 voltage_map missing supply name and voltage.
0058 LibertyReader.cc:949 voltage_map missing values suffix.
0059 LibertyReader.cc:1167 default_wire_load_mode %s not found.
0060 LibertyReader.cc:683 default_operating_condition %s not found.
0061 LibertyReader.cc:1338 table template missing name.
0062 LibertyReader.cc:1383 missing variable_%d attribute.
0063 LibertyReader.cc:1426 axis type %s not supported.
0064 LibertyReader.cc:1486 bus type %s missing bit_from.
0065 LibertyReader.cc:1488 bus type %s missing bit_to.
0066 LibertyReader.cc:1492 type missing name.
0067 LibertyReader.cc:1519 scaling_factors do not have a name.
0068 LibertyReader.cc:1687 operating_conditions missing name.
0069 LibertyReader.cc:1757 wire_load missing name.
0070 LibertyReader.cc:1800 fanout_length is missing length and fanout.
0071 LibertyReader.cc:1815 wire_load_selection missing name.
0072 LibertyReader.cc:1846 wireload %s not found.
0074 LibertyReader.cc:1853 wire_load_from_area min not a float.
0075 LibertyReader.cc:1856 wire_load_from_area max not a float.
0076 LibertyReader.cc:1859 wire_load_from_area missing parameters.
0077 LibertyReader.cc:1862 wire_load_from_area missing parameters.
0078 LibertyReader.cc:1879 cell missing name.
0079 LibertyReader.cc:1902 cell %s ocv_derate_group %s not found.
0080 LibertyReader.cc:1938 port %s function size does not match port size.
0081 LibertyReader.cc:2006 %s %s bus width mismatch.
0082 LibertyReader.cc:2017 %s %s bus width mismatch.
0083 LibertyReader.cc:2027 clear
0084 LibertyReader.cc:2037 preset
0085 LibertyReader.cc:2073 latch enable function is non-unate for port %s.
0086 LibertyReader.cc:2078 latch enable function is unknown for port %s.
0087 LibertyReader.cc:2154 operating conditions %s not found.
0088 LibertyReader.cc:2157 scaled_cell missing operating condition.
0089 LibertyReader.cc:2160 scaled_cell cell %s has not been defined.
0090 LibertyReader.cc:2163 scaled_cell missing name.
0091 LibertyReader.cc:2189 scaled_cell %s, %s port functions do not match cell port functions.
0092 LibertyReader.cc:2194 scaled_cell ports do not match cell ports.
0093 LibertyReader.cc:2196 scaled_cell %s, %s timing does not match cell timing.
0094 LibertyReader.cc:2215 combinational timing to an input port.
0095 LibertyReader.cc:2306 missing %s_transition.
0096 LibertyReader.cc:2308 missing cell_%s.
0099 LibertyReader.cc:2900 scaling_factors %s not found.
0100 LibertyReader.cc:2943 pin name is not a string.
0101 LibertyReader.cc:2962 pin name is not a string.
0102 LibertyReader.cc:2978 pin name is not a string.
0103 LibertyReader.cc:3056 bus %s bus_type not found.
0104 LibertyReader.cc:3112 bus_type %s not found.
0105 LibertyReader.cc:3115 bus_type is not a string.
0106 LibertyReader.cc:3133 bundle %s member not found.
0107 LibertyReader.cc:3160 member is not a string.
0108 LibertyReader.cc:3167 members attribute is missing values.
0109 LibertyReader.cc:3218 unknown port direction.
0110 LibertyReader.cc:3586 pulse_latch unknown pulse type.
0111 LibertyReader.cc:3964 unknown timing_type %s.
0112 LibertyReader.cc:3984 unknown timing_sense %s.
0113 LibertyReader.cc:4024 mode value is not a string.
0114 LibertyReader.cc:4027 missing mode value.
0115 LibertyReader.cc:4030 mode name is not a string.
0116 LibertyReader.cc:4033 mode missing values.
0117 LibertyReader.cc:4036 mode missing mode name and value.
0118 LibertyReader.cc:2547 unsupported model axis.
0119 LibertyReader.cc:4139 unsupported model axis.
0120 LibertyReader.cc:4168 unsupported model axis.
0121 LibertyReader.cc:4203 unsupported model axis.
0122 LibertyReader.cc:4258 table template %s not found.
0123 LibertyReader.cc:4337 %s is missing values.
0124 LibertyReader.cc:4362 %s is not a list of floats.
0125 LibertyReader.cc:4364 table row has %u columns but axis has %d.
0126 LibertyReader.cc:4374 table has %u rows but axis has %d.
0127 LibertyReader.cc:4427 lut output is not a string.
0128 LibertyReader.cc:4469 mode definition missing name.
0129 LibertyReader.cc:4486 mode value missing name.
0130 LibertyReader.cc:4500 when attribute inside table model.
0131 LibertyReader.cc:4549 %s attribute is not a string.
0132 LibertyReader.cc:4552 %s is not a simple attribute.
0133 LibertyReader.cc:4575 %s is not a simple attribute.
0134 LibertyReader.cc:4588 %s is not a simple attribute.
0135 LibertyReader.cc:4612 %s value %s is not a float.
0136 LibertyReader.cc:4641 %s missing values.
0137 LibertyReader.cc:4645 %s missing values.
0138 LibertyReader.cc:4648 %s is not a complex attribute.
0139 LibertyReader.cc:4674 %s is not a float.
0140 LibertyReader.cc:4697 %s is missing values.
0141 LibertyReader.cc:4700 %s has more than one string.
0142 LibertyReader.cc:4709 %s is missing values.
0143 LibertyReader.cc:4734 %s attribute is not boolean.
0144 LibertyReader.cc:4737 %s attribute is not boolean.
0145 LibertyReader.cc:4740 %s is not a simple attribute.
0146 LibertyReader.cc:4756 attribute %s value %s not recognized.
0147 LibertyReader.cc:4786 unknown early/late value.
0148 LibertyReader.cc:5012 OCV derate group named %s not found.
0149 LibertyReader.cc:5028 ocv_derate missing name.
0150 LibertyReader.cc:5081 unknown rise/fall.
0151 LibertyReader.cc:5101 unknown derate type.
0152 LibertyReader.cc:5133 unsupported model axis.
0153 LibertyReader.cc:5165 unsupported model axis.
0154 LibertyReader.cc:5197 unsupported model axis.
0155 LibertyReader.cc:5268 unknown pg_type.
0156 LibertyReader.cc:5663 port %s subscript out of range.
0157 LibertyReader.cc:5667 port range %s of non-bus port %s.
0158 LibertyReader.cc:5681 port %s not found.
0159 LibertyReader.cc:5751 port %s not found.
0160 LibertyReader.cc:1034 default_max_transition is 0.0.
0161 LibertyReader.cc:3474 max_transition is 0.0.
0162 LibertyReader.cc:4572 %s attribute is not an integer.
0163 LibertyReader.cc:1139 default_fanout_load is 0.0.
0164 LibertyReader.cc:2328 timing group from output port.
0165 LibertyReader.cc:2338 timing group from output port.
0166 LibertyReader.cc:2348 timing group from output port.
0167 LibertyReader.cc:2366 timing group from output port.
0168 LibertyReader.cc:2381 timing group from output port.
0169 LibertyReader.cc:4444 cell %s test_cell redefinition.
0170 LibertyReader.cc:3883 timing group missing related_pin/related_bus_pin.
0052 LibertyReader.cc:904 unknown bus_naming_style format.
0053 LibertyReader.cc:597 library %s already exists.
0054 LibertyReader.cc:925 voltage_map voltage is not a float.
0055 LibertyReader.cc:928 voltage_map missing voltage.
0056 LibertyReader.cc:931 voltage_map supply name is not a string.
0057 LibertyReader.cc:934 voltage_map missing supply name and voltage.
0058 LibertyReader.cc:937 voltage_map missing values suffix.
0059 LibertyReader.cc:1155 default_wire_load_mode %s not found.
0060 LibertyReader.cc:680 default_operating_condition %s not found.
0061 LibertyReader.cc:1326 table template missing name.
0062 LibertyReader.cc:1371 missing variable_%d attribute.
0063 LibertyReader.cc:1414 axis type %s not supported.
0064 LibertyReader.cc:1474 bus type %s missing bit_from.
0065 LibertyReader.cc:1476 bus type %s missing bit_to.
0066 LibertyReader.cc:1480 type missing name.
0067 LibertyReader.cc:1507 scaling_factors do not have a name.
0068 LibertyReader.cc:1675 operating_conditions missing name.
0069 LibertyReader.cc:1745 wire_load missing name.
0070 LibertyReader.cc:1788 fanout_length is missing length and fanout.
0071 LibertyReader.cc:1803 wire_load_selection missing name.
0072 LibertyReader.cc:1834 wireload %s not found.
0074 LibertyReader.cc:1841 wire_load_from_area min not a float.
0075 LibertyReader.cc:1844 wire_load_from_area max not a float.
0076 LibertyReader.cc:1847 wire_load_from_area missing parameters.
0077 LibertyReader.cc:1850 wire_load_from_area missing parameters.
0078 LibertyReader.cc:1867 cell missing name.
0079 LibertyReader.cc:1890 cell %s ocv_derate_group %s not found.
0080 LibertyReader.cc:1926 port %s function size does not match port size.
0081 LibertyReader.cc:1994 %s %s bus width mismatch.
0082 LibertyReader.cc:2005 %s %s bus width mismatch.
0083 LibertyReader.cc:2015 clear
0084 LibertyReader.cc:2025 preset
0085 LibertyReader.cc:2061 latch enable function is non-unate for port %s.
0086 LibertyReader.cc:2066 latch enable function is unknown for port %s.
0087 LibertyReader.cc:2142 operating conditions %s not found.
0088 LibertyReader.cc:2145 scaled_cell missing operating condition.
0089 LibertyReader.cc:2148 scaled_cell cell %s has not been defined.
0090 LibertyReader.cc:2151 scaled_cell missing name.
0091 LibertyReader.cc:2177 scaled_cell %s, %s port functions do not match cell port functions.
0092 LibertyReader.cc:2182 scaled_cell ports do not match cell ports.
0093 LibertyReader.cc:2184 scaled_cell %s, %s timing does not match cell timing.
0094 LibertyReader.cc:2203 combinational timing to an input port.
0095 LibertyReader.cc:2294 missing %s_transition.
0096 LibertyReader.cc:2296 missing cell_%s.
0099 LibertyReader.cc:2894 scaling_factors %s not found.
0100 LibertyReader.cc:2937 pin name is not a string.
0101 LibertyReader.cc:2956 pin name is not a string.
0102 LibertyReader.cc:2972 pin name is not a string.
0103 LibertyReader.cc:3050 bus %s bus_type not found.
0104 LibertyReader.cc:3106 bus_type %s not found.
0105 LibertyReader.cc:3109 bus_type is not a string.
0106 LibertyReader.cc:3127 bundle %s member not found.
0107 LibertyReader.cc:3154 member is not a string.
0108 LibertyReader.cc:3161 members attribute is missing values.
0109 LibertyReader.cc:3212 unknown port direction.
0110 LibertyReader.cc:3580 pulse_latch unknown pulse type.
0111 LibertyReader.cc:3958 unknown timing_type %s.
0112 LibertyReader.cc:3978 unknown timing_sense %s.
0113 LibertyReader.cc:4018 mode value is not a string.
0114 LibertyReader.cc:4021 missing mode value.
0115 LibertyReader.cc:4024 mode name is not a string.
0116 LibertyReader.cc:4027 mode missing values.
0117 LibertyReader.cc:4030 mode missing mode name and value.
0118 LibertyReader.cc:2541 unsupported model axis.
0119 LibertyReader.cc:4133 unsupported model axis.
0120 LibertyReader.cc:4162 unsupported model axis.
0121 LibertyReader.cc:4197 unsupported model axis.
0122 LibertyReader.cc:4252 table template %s not found.
0123 LibertyReader.cc:4331 %s is missing values.
0124 LibertyReader.cc:4356 %s is not a list of floats.
0125 LibertyReader.cc:4358 table row has %u columns but axis has %d.
0126 LibertyReader.cc:4368 table has %u rows but axis has %d.
0127 LibertyReader.cc:4421 lut output is not a string.
0128 LibertyReader.cc:4463 mode definition missing name.
0129 LibertyReader.cc:4480 mode value missing name.
0130 LibertyReader.cc:4494 when attribute inside table model.
0131 LibertyReader.cc:4543 %s attribute is not a string.
0132 LibertyReader.cc:4546 %s is not a simple attribute.
0133 LibertyReader.cc:4569 %s is not a simple attribute.
0134 LibertyReader.cc:4582 %s is not a simple attribute.
0135 LibertyReader.cc:4606 %s value %s is not a float.
0136 LibertyReader.cc:4635 %s missing values.
0137 LibertyReader.cc:4639 %s missing values.
0138 LibertyReader.cc:4642 %s is not a complex attribute.
0139 LibertyReader.cc:4668 %s is not a float.
0140 LibertyReader.cc:4691 %s is missing values.
0141 LibertyReader.cc:4694 %s has more than one string.
0142 LibertyReader.cc:4703 %s is missing values.
0143 LibertyReader.cc:4728 %s attribute is not boolean.
0144 LibertyReader.cc:4731 %s attribute is not boolean.
0145 LibertyReader.cc:4734 %s is not a simple attribute.
0146 LibertyReader.cc:4750 attribute %s value %s not recognized.
0147 LibertyReader.cc:4781 unknown early/late value.
0148 LibertyReader.cc:5007 OCV derate group named %s not found.
0149 LibertyReader.cc:5023 ocv_derate missing name.
0150 LibertyReader.cc:5076 unknown rise/fall.
0151 LibertyReader.cc:5096 unknown derate type.
0152 LibertyReader.cc:5128 unsupported model axis.
0153 LibertyReader.cc:5160 unsupported model axis.
0154 LibertyReader.cc:5192 unsupported model axis.
0155 LibertyReader.cc:5263 unknown pg_type.
0156 LibertyReader.cc:5658 port %s subscript out of range.
0157 LibertyReader.cc:5662 port range %s of non-bus port %s.
0158 LibertyReader.cc:5676 port %s not found.
0159 LibertyReader.cc:5746 port %s not found.
0160 LibertyReader.cc:1022 default_max_transition is 0.0.
0161 LibertyReader.cc:3468 max_transition is 0.0.
0162 LibertyReader.cc:4566 %s attribute is not an integer.
0163 LibertyReader.cc:1127 default_fanout_load is 0.0.
0164 LibertyReader.cc:2316 timing group from output port.
0165 LibertyReader.cc:2326 timing group from output port.
0166 LibertyReader.cc:2336 timing group from output port.
0167 LibertyReader.cc:2354 timing group from output port.
0168 LibertyReader.cc:2369 timing group from output port.
0169 LibertyReader.cc:4438 cell %s test_cell redefinition.
0170 LibertyReader.cc:3877 timing group missing related_pin/related_bus_pin.
0179 SpefReader.cc:734 %s.
0190 VerilogReader.cc:1756 %s is not a verilog module.
0191 VerilogReader.cc:1761 %s is not a verilog module.
0190 VerilogReader.cc:1782 %s is not a verilog module.
0191 VerilogReader.cc:1787 %s is not a verilog module.
0201 StaTcl.i:118 no network has been linked.
0202 StaTcl.i:132 network does not support edits.
0204 StaTcl.i:4072 POCV support requires compilation with SSTA=1.
0204 StaTcl.i:4123 POCV support requires compilation with SSTA=1.
0206 LibertyExpr.cc:175 %s %s.
0207 GraphDelayCalc1.cc:738 port not found in cell
0208 Graph.cc:793 arc_delay_annotated array bounds exceeded
0209 Graph.cc:808 arc_delay_annotated array bounds exceeded
0210 Graph.cc:820 arc_delay_annotated array bounds exceeded
0211 SdcNetwork.cc:1077 inst path string lenth estimate busted
0212 SdcNetwork.cc:1149 inst path string lenth estimate exceeded
0211 SdcNetwork.cc:1095 inst path string lenth estimate busted
0212 SdcNetwork.cc:1167 inst path string lenth estimate exceeded
0213 Sdc.cc:4021 group path name and is_default are mutually exclusive.
0214 WriteSdc.cc:1254 unknown exception type
0215 WriteSdc.cc:1795 illegal set_logic value
@ -188,16 +188,16 @@
0256 ReportPath.cc:308 unsupported path type
0257 ReportPath.cc:347 unsupported path type
0259 ReportPath.cc:2376 unsupported path type
0260 Search.cc:2628 max tag group index exceeded
0261 Search.cc:2860 max tag index exceeded
0262 Search.cc:3551 unexpected filter path
0263 Search.cc:3719 tns incr existing vertex
0264 Sta.cc:4180 corresponding timing arc set not found in equiv cells
0260 Search.cc:2655 max tag group index exceeded
0261 Search.cc:2891 max tag index exceeded
0262 Search.cc:3618 unexpected filter path
0263 Search.cc:3786 tns incr existing vertex
0264 Sta.cc:4190 corresponding timing arc set not found in equiv cells
0265 TagGroup.cc:297 tag group missing tag
0266 Sta.cc:2090 '%s' is not a valid endpoint.
0267 Sta.cc:2014 '%s' is not a valid start point.
0272 StaTcl.i:4058 unknown common clk pessimism mode.
0273 StaTcl.i:5003 unknown clock sense
0272 StaTcl.i:4109 unknown common clk pessimism mode.
0273 StaTcl.i:5055 unknown clock sense
0299 Power.tcl:241 activity cannot be set on clock ports.
0300 CmdUtil.tcl:44 no commands match '$pattern'.
0301 Power.tcl:218 activity should be 0.0 to 1.0 or 2.0
@ -209,7 +209,7 @@
0314 CmdArgs.tcl:857 $arg_name must be a single net.
0315 CmdArgs.tcl:863 $arg_name '$object_type' is not a net.
0316 CmdArgs.tcl:868 $arg_name '$arg' not found.
0318 Search.tcl:1067 unknown path group '$name'.
0318 Search.tcl:1057 unknown path group '$name'.
0319 Sdc.tcl:288 $unit scale [format %.0e $scale] does not match library scale [format %.0e $unit_scale].
0320 Sdc.tcl:437 current_design for other than top cell not supported.
0321 Sdc.tcl:474 patterns argument not supported with -of_objects.
@ -264,6 +264,7 @@
0371 Sdc.tcl:3497 set_wire_load_min_block_size not supported.
0372 NetworkEdit.tcl:129 connect_pins is deprecated. Use connect_pin.
0373 Sdc.tcl:3647 define_corners must be called before read_liberty.
0374 Sta.cc:2416 maximum corner count exceeded
0400 Util.tcl:44 $cmd $key missing value.
0401 Util.tcl:61 $cmd $key missing value.
0402 Util.tcl:71 $cmd $arg is not a known keyword or flag.
@ -283,15 +284,15 @@
0416 Util.tcl:305 $cmd_arg '$arg' is not a positive integer.
0417 Util.tcl:311 $cmd_arg '$arg' is not an integer greater than or equal to one.
0418 Util.tcl:317 $cmd_arg '$arg' is not between 0 and 100.
0419 Search.tcl:336 report_clock_skew -setup and -hold are mutually exclusive options.
0419 Search.tcl:326 report_clock_skew -setup and -hold are mutually exclusive options.
0420 Search.tcl:136 $cmd -path_delay must be min, min_rise, min_fall, max, max_rise, max_fall or min_max.
0421 Search.tcl:146 $cmd command failed.
0422 Search.tcl:165 -endpoint_count must be a positive integer.
0423 Search.tcl:174 -group_count must be >= 1.
0424 Search.tcl:205 '$arg' is not a known keyword or flag.
0425 Search.tcl:207 positional arguments not supported.
0426 Search.tcl:520 analysis type single is not consistent with doing both setup/max and hold/min checks.
0427 Search.tcl:525 positional arguments not supported.
0426 Search.tcl:510 analysis type single is not consistent with doing both setup/max and hold/min checks.
0427 Search.tcl:515 positional arguments not supported.
0428 DelayCalc.tcl:350 set_assigned_transition transition is not a float.
0430 Sdf.tcl:46 -cond_use min_max cannot be used with analysis type single.
0432 Sdf.tcl:157 SDF -divider must be / or .
@ -370,9 +371,9 @@
0505 WritePathSpice.tcl:74 No -ground specified.
0506 WritePathSpice.tcl:78 No -path_args specified.
0507 WritePathSpice.tcl:83 No paths found for -path_args $path_args.
0508 Search.tcl:788 -min and -max cannot both be specified.
0509 Search.tcl:808 pin '$pin_arg' is hierarchical.
0510 Search.tcl:874 -format $format not recognized.
0508 Search.tcl:778 -min and -max cannot both be specified.
0509 Search.tcl:798 pin '$pin_arg' is hierarchical.
0510 Search.tcl:864 -format $format not recognized.
0511 Sdc.tcl:73 cannot open '$filename'.
0512 Sdc.tcl:128 incomplete command at end of file.
0513 Sdc.tcl:212 hierarchy separator must be one of '$sdc_dividers'.
@ -461,13 +462,13 @@
0604 Sdc.tcl:281 unknown $unit prefix '$prefix'.
0605 Sdc.tcl:3547 wire load model '$model_name' not found.
0606 Property.tcl:77 get_property unsupported object type $object_type.
0607 StaTcl.i:4308 unknown report path field %s
0608 StaTcl.i:4320 unknown report path field %s
0609 Search.tcl:421 -all_violators is deprecated. Use -violators
0610 Search.tcl:501 -max_transition deprecated. Use -max_slew.
0611 Search.tcl:506 -min_transition deprecated. Use -min_slew.
0607 StaTcl.i:4359 unknown report path field %s
0608 StaTcl.i:4371 unknown report path field %s
0609 Search.tcl:411 -all_violators is deprecated. Use -violators
0610 Search.tcl:491 -max_transition deprecated. Use -max_slew.
0611 Search.tcl:496 -min_transition deprecated. Use -min_slew.
0612 Sdf.tcl:41 -cond_use must be min, max or min_max.
0616 Search.tcl:1018 specify one of -setup and -hold.
0616 Search.tcl:1008 specify one of -setup and -hold.
0617 Sdf.tcl:50 -analysis_type is deprecated. Use set_operating_conditions -analysis_type.
0618 DmpCeff.cc:1581 parasitic Pi model has NaNs.
0619 PathEnum.cc:474 path diversion missing edge.
@ -476,30 +477,30 @@
0622 PathVertex.cc:279 missing requireds.
0623 PathVertexRep.cc:153 missing arrivals.
0624 PathVertexRep.cc:150 missing arrivals
0701 LibertyWriter.cc:416 %s/%s/%s timing model not supported.
0702 LibertyWriter.cc:436 3 axis table models not supported.
0703 LibertyWriter.cc:576 %s/%s/%s timing arc type %s not supported.
0704 LibertyWriter.cc:289 %s/%s bundled ports not supported.
0705 Liberty.cc:795 Liberty cell %s/%s for corner %s/%s not found.
0701 LibertyWriter.cc:411 %s/%s/%s timing model not supported.
0702 LibertyWriter.cc:431 3 axis table models not supported.
0703 LibertyWriter.cc:571 %s/%s/%s timing arc type %s not supported.
0704 LibertyWriter.cc:284 %s/%s bundled ports not supported.
0705 Liberty.cc:815 Liberty cell %s/%s for corner %s/%s not found.
0706 Parasitics.tcl:70 read_spef -increment is deprecated.
0710 LumpedCapDelayCalc.cc:169 gate delay input variable is NaN
0800 VcdReader.cc:109 unhandled vcd command.
0801 VcdReader.cc:145 timescale syntax error.
0802 VcdReader.cc:159 Unknown timescale unit.
0804 VcdReader.cc:200 Variable syntax error.
0800 VcdReader.cc:110 unhandled vcd command.
0801 VcdReader.cc:146 timescale syntax error.
0802 VcdReader.cc:160 Unknown timescale unit.
0804 VcdReader.cc:212 Variable syntax error.
0805 Vcd.cc:172 Unknown variable %s ID %s
0806 ReadVcdActivities.cc:247 clock %s vcd period %s differs from SDC clock period %s
0807 Sdc.tcl:394 only one of -cells, -data_pins, -clock_pins, -async_pins, -output_pins are suppported.
0810 MakeTimingModel.cc:189 clock %s pin %s is inside model block.
0900 LibertyReader.cc:2840 level_shifter_type must be HL, LH, or HL_LH
0901 LibertyReader.cc:2876 switch_cell_type must be coarse_grain or fine_grain
0902 LibertyReader.cc:2464 unsupported model axis.
0903 LibertyReader.cc:4219 %s group not in timing group.
0904 LibertyReader.cc:2447 receiver_capacitance group not in timing or pin group.
0906 LibertyReader.cc:4112 unsupported model axis.
0907 LibertyReader.cc:2492 output_current_%s group not in timing group.
0908 LibertyReader.cc:2591 vector reference_time not found.
0912 LibertyReader.cc:2589 vector index_1 and index_2 must have exactly one value.
0913 LibertyReader.cc:2531 output current waveform %.2e %.2e not found.
0914 LibertyReader.cc:2624 normalized_driver_waveform variable_2 must be normalized_voltage
0915 LibertyReader.cc:2627 normalized_driver_waveform variable_1 must be input_net_transition
0810 MakeTimingModel.cc:202 clock %s pin %s is inside model block.
0900 LibertyReader.cc:2834 level_shifter_type must be HL, LH, or HL_LH
0901 LibertyReader.cc:2870 switch_cell_type must be coarse_grain or fine_grain
0902 LibertyReader.cc:2452 unsupported model axis.
0903 LibertyReader.cc:4213 %s group not in timing group.
0904 LibertyReader.cc:2435 receiver_capacitance group not in timing or pin group.
0906 LibertyReader.cc:4106 unsupported model axis.
0907 LibertyReader.cc:2480 output_current_%s group not in timing group.
0908 LibertyReader.cc:2585 vector reference_time not found.
0912 LibertyReader.cc:2583 vector index_1 and index_2 must have exactly one value.
0913 LibertyReader.cc:2521 output current waveform %.2e %.2e not found.
0914 LibertyReader.cc:2618 normalized_driver_waveform variable_2 must be normalized_voltage
0915 LibertyReader.cc:2621 normalized_driver_waveform variable_1 must be input_net_transition

View File

@ -16,7 +16,7 @@
#include "ConcreteLibrary.hh"
#include <stdlib.h>
#include <cstdlib>
#include "PatternMatch.hh"
#include "PortDirection.hh"
@ -275,32 +275,6 @@ ConcreteCell::portCount() const
return ports_.size();
}
PortSeq
ConcreteCell::findPortsMatching(const PatternMatch *pattern) const
{
PortSeq matches;
char bus_brkt_right = library_->busBrktRight();
const char *pattern1 = pattern->pattern();
bool bus_pattern = (pattern1[strlen(pattern1) - 1] == bus_brkt_right);
ConcreteCellPortIterator *port_iter = portIterator();
while (port_iter->hasNext()) {
ConcretePort *port = port_iter->next();
if (port->isBus() && bus_pattern) {
ConcretePortMemberIterator *member_iter = port->memberIterator();
while (member_iter->hasNext()) {
ConcretePort *port_bit = member_iter->next();
if (pattern->match(port_bit->name()))
matches.push_back(reinterpret_cast<Port*>(port_bit));
}
delete member_iter;
}
else if (pattern->match(port->name()))
matches.push_back(reinterpret_cast<Port*>(port));
}
delete port_iter;
return matches;
}
ConcreteCellPortIterator *
ConcreteCell::portIterator() const
{

View File

@ -605,14 +605,6 @@ ConcreteNetwork::findPort(const Cell *cell,
return reinterpret_cast<Port*>(ccell->findPort(name));
}
PortSeq
ConcreteNetwork::findPortsMatching(const Cell *cell,
const PatternMatch *pattern) const
{
const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
return ccell->findPortsMatching(pattern);
}
bool
ConcreteNetwork::isLeaf(const Cell *cell) const
{

View File

@ -16,7 +16,7 @@
#include "HpinDrvrLoad.hh"
#include <stdio.h>
#include <cstdio>
#include "Network.hh"

View File

@ -22,6 +22,7 @@
#include "Liberty.hh"
#include "PortDirection.hh"
#include "Corner.hh"
#include "ParseBus.hh"
namespace sta {
@ -56,6 +57,63 @@ Network::libertyLibrary(const Cell *cell) const
return libertyCell(cell)->libertyLibrary();
}
PortSeq
Network::findPortsMatching(const Cell *cell,
const PatternMatch *pattern) const
{
PortSeq matches;
bool is_bus, is_range, subscript_wild;
string bus_name;
int from, to;
parseBusName(pattern->pattern(), '[', ']', '\\',
is_bus, is_range, bus_name, from, to, subscript_wild);
if (is_bus) {
PatternMatch bus_pattern(bus_name.c_str(), pattern);
CellPortIterator *port_iter = portIterator(cell);
while (port_iter->hasNext()) {
Port *port = port_iter->next();
if (isBus(port)
&& bus_pattern.match(name(port))) {
if (is_range) {
// bus[8:0]
if (from > to)
std::swap(from, to);
for (int bit = from; bit <= to; bit++) {
Port *port_bit = findBusBit(port, bit);
matches.push_back(port_bit);
}
}
else {
if (subscript_wild) {
PortMemberIterator *member_iter = memberIterator(port);
while (member_iter->hasNext()) {
Port *port_bit = member_iter->next();
matches.push_back(port_bit);
}
delete member_iter;
}
else {
// bus[0]
Port *port_bit = findBusBit(port, from);
matches.push_back(port_bit);
}
}
}
}
delete port_iter;
}
else {
CellPortIterator *port_iter = portIterator(cell);
while (port_iter->hasNext()) {
Port *port = port_iter->next();
if (pattern->match(name(port)))
matches.push_back(port);
}
delete port_iter;
}
return matches;
}
LibertyLibrary *
Network::libertyLibrary(const Instance *instance) const
{
@ -2035,6 +2093,16 @@ InstanceSet::compare(const InstanceSet *set1,
return (size1 > size2) ? 1 : -1;
}
bool
InstanceSet::intersects(const InstanceSet *set1,
const InstanceSet *set2,
const Network *network)
{
return Set<const Instance*, InstanceIdLess>::intersects(set1, set2, InstanceIdLess(network));
}
////////////////////////////////////////////////////////////////
PinSet::PinSet() :
Set<const Pin*, PinIdLess>(PinIdLess(nullptr))
{
@ -2072,6 +2140,16 @@ PinSet::compare(const PinSet *set1,
return (size1 > size2) ? 1 : -1;
}
bool
PinSet::intersects(const PinSet *set1,
const PinSet *set2,
const Network *network)
{
return Set<const Pin*, PinIdLess>::intersects(set1, set2, PinIdLess(network));
}
////////////////////////////////////////////////////////////////
NetSet::NetSet() :
Set<const Net*, NetIdLess>(NetIdLess(nullptr))
{
@ -2109,4 +2187,12 @@ NetSet::compare(const NetSet *set1,
return (size1 > size2) ? 1 : -1;
}
bool
NetSet::intersects(const NetSet *set1,
const NetSet *set2,
const Network *network)
{
return Set<const Net*, NetIdLess>::intersects(set1, set2, NetIdLess(network));
}
} // namespace

View File

@ -16,8 +16,8 @@
#include "ParseBus.hh"
#include <string.h>
#include <stdlib.h>
#include <cstring>
#include <cstdlib>
#include <string>
#include "StringUtil.hh"
@ -95,37 +95,43 @@ parseBusName(const char *name,
}
void
parseBusRange(const char *name,
const char brkt_left,
const char brkt_right,
char escape,
// Return values.
bool &is_bus,
string &bus_name,
int &from,
int &to)
parseBusName(const char *name,
const char brkt_left,
const char brkt_right,
char escape,
// Return values.
bool &is_bus,
bool &is_range,
string &bus_name,
int &from,
int &to,
bool &subscript_wild)
{
const char brkts_left[2] = {brkt_left, '\0'};
const char brkts_right[2] = {brkt_right, '\0'};
parseBusRange(name, brkts_left, brkts_right, escape,
is_bus, bus_name, from, to);
parseBusName(name, brkts_left, brkts_right, escape,
is_bus, is_range, bus_name, from, to, subscript_wild);
}
void
parseBusRange(const char *name,
const char *brkts_left,
const char *brkts_right,
char escape,
// Return values.
bool &is_bus,
string &bus_name,
int &from,
int &to)
parseBusName(const char *name,
const char *brkts_left,
const char *brkts_right,
char escape,
// Return values.
bool &is_bus,
bool &is_range,
string &bus_name,
int &from,
int &to,
bool &subscript_wild)
{
is_bus = false;
is_range = false;
subscript_wild = false;
size_t len = strlen(name);
// Shortest bus range is a[1:0].
if (len >= 6
// Shortest bus is a[0].
if (len >= 4
// Escaped bus brackets are not buses.
&& name[len - 2] != escape) {
char last_ch = name[len - 1];
@ -135,17 +141,25 @@ parseBusRange(const char *name,
char brkt_left = brkts_left[brkt_index];
const char *left = strrchr(name, brkt_left);
if (left) {
is_bus = true;
// Check for bus range.
const char range_sep = ':';
const char *range = strchr(name, range_sep);
if (range) {
is_bus = true;
is_range = true;
bus_name.append(name, left - name);
// No need to terminate bus subscript because atoi stops
// scanning at first non-digit character.
from = atoi(left + 1);
to = atoi(range + 1);
}
else {
bus_name.append(name, left - name);
if (left[1] == '*')
subscript_wild = true;
else
from = to = atoi(left + 1);
}
}
}
}

View File

@ -16,7 +16,7 @@
#include "VerilogNamespace.hh"
#include <ctype.h>
#include <cctype>
#include "StringUtil.hh"
#include "ParseBus.hh"

View File

@ -144,44 +144,6 @@ ConcreteParasitic::nodeIterator()
////////////////////////////////////////////////////////////////
ConcreteElmore::ConcreteElmore() :
loads_(nullptr)
{
}
ConcreteElmore::~ConcreteElmore()
{
delete loads_;
}
void
ConcreteElmore::findElmore(const Pin *load_pin,
float &elmore,
bool &exists) const
{
if (loads_)
loads_->findKey(load_pin, elmore, exists);
else
exists = false;
}
void
ConcreteElmore::deleteLoad(const Pin *load_pin)
{
loads_->erase(load_pin);
}
void
ConcreteElmore::setElmore(const Pin *load_pin,
float elmore)
{
if (loads_ == nullptr)
loads_ = new ConcreteElmoreLoadMap;
(*loads_)[load_pin] = elmore;
}
////////////////////////////////////////////////////////////////
ConcretePi::ConcretePi(float c2,
float rpi,
float c1) :
@ -230,10 +192,15 @@ ConcretePiElmore::ConcretePiElmore(float c2,
float rpi,
float c1) :
ConcretePi(c2, rpi, c1),
ConcreteElmore()
loads_(nullptr)
{
}
ConcretePiElmore::~ConcretePiElmore()
{
delete loads_;
}
float
ConcretePiElmore::capacitance() const
{
@ -273,14 +240,25 @@ ConcretePiElmore::findElmore(const Pin *load_pin,
float &elmore,
bool &exists) const
{
ConcreteElmore::findElmore(load_pin, elmore, exists);
if (loads_)
loads_->findKey(load_pin, elmore, exists);
else
exists = false;
}
void
ConcretePiElmore::setElmore(const Pin *load_pin,
float elmore)
{
ConcreteElmore::setElmore(load_pin, elmore);
if (loads_ == nullptr)
loads_ = new ConcreteElmoreLoadMap;
(*loads_)[load_pin] = elmore;
}
void
ConcretePiElmore::deleteLoad(const Pin *load_pin)
{
loads_->erase(load_pin);
}
////////////////////////////////////////////////////////////////

View File

@ -82,24 +82,6 @@ public:
virtual ParasiticNodeIterator *nodeIterator();
};
class ConcreteElmore
{
public:
void findElmore(const Pin *load_pin,
float &elmore,
bool &exists) const;
void deleteLoad(const Pin *load_pin);
void setElmore(const Pin *load_pin,
float elmore);
protected:
ConcreteElmore();
virtual ~ConcreteElmore();
private:
ConcreteElmoreLoadMap *loads_;
};
// Pi model for a driver pin.
class ConcretePi
{
@ -126,13 +108,13 @@ protected:
// Pi model for a driver pin and the elmore delay to each load.
class ConcretePiElmore : public ConcretePi,
public ConcreteElmore,
public ConcreteParasitic
{
public:
ConcretePiElmore(float c2,
float rpi,
float c1);
virtual ~ConcretePiElmore();
virtual bool isPiElmore() const { return true; }
virtual bool isPiModel() const { return true; }
virtual float capacitance() const;
@ -143,6 +125,10 @@ public:
virtual void findElmore(const Pin *load_pin, float &elmore,
bool &exists) const;
virtual void setElmore(const Pin *load_pin, float elmore);
void deleteLoad(const Pin *load_pin);
private:
ConcreteElmoreLoadMap *loads_;
};
// PiElmore from wireload model estimate.

View File

@ -16,8 +16,8 @@
#include "SpefNamespace.hh"
#include <ctype.h>
#include <string.h>
#include <cctype>
#include <cstring>
namespace sta {

View File

@ -16,7 +16,7 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <string.h>
#include <cstring>
#include "StringUtil.hh"
#include "StringSeq.hh"

View File

@ -135,11 +135,11 @@ ReadVcdActivities::setVarActivity(VcdVar *var,
if (var->width() == 1)
setVarActivity(sta_name.c_str(), var_values, 0);
else {
bool is_bus;
bool is_bus, is_range, subscript_wild;
string bus_name;
int from, to;
parseBusRange(sta_name.c_str(), '[', ']', '\\',
is_bus, bus_name, from, to);
parseBusName(sta_name.c_str(), '[', ']', '\\',
is_bus, is_range, bus_name, from, to, subscript_wild);
int value_bit = 0;
if (to < from) {
for (int bus_bit = to; bus_bit <= from; bus_bit++) {

View File

@ -16,6 +16,7 @@
#pragma once
#include <cstdint>
#include <string>
#include <vector>
#include <map>

View File

@ -31,7 +31,8 @@ namespace sta {
static bool
thrusIntersectPts(ExceptionThruSeq *thrus1,
ExceptionThruSeq *thrus2);
ExceptionThruSeq *thrus2,
const Network *network);
static void
insertPinPairsThruHierPin(const Pin *hpin,
const Network *network,
@ -273,23 +274,24 @@ ExceptionPath::mergeablePts(ExceptionPath *exception2,
}
bool
ExceptionPath::intersectsPts(ExceptionPath *exception) const
ExceptionPath::intersectsPts(ExceptionPath *exception,
const Network *network) const
{
ExceptionFrom *from2 = exception->from();
ExceptionThruSeq *thrus2 = exception->thrus();
ExceptionTo *to2 = exception->to();
if (((from_ == nullptr && from2 == nullptr)
|| (from_ && from2 && from_->intersectsPts(from2)))
|| (from_ && from2 && from_->intersectsPts(from2, network)))
&& ((thrus_ == nullptr && thrus2 == nullptr)
|| (thrus_ && thrus2 && thrus_->size() == thrus2->size()))
&& ((to_ == nullptr && to2 == nullptr)
|| (to_ && to2 && to_->intersectsPts(to2)))) {
|| (to_ && to2 && to_->intersectsPts(to2, network)))) {
ExceptionThruSeq::Iterator thrus_iter1(thrus_);
ExceptionThruSeq::Iterator thrus_iter2(thrus2);
while (thrus_iter1.hasNext() && thrus_iter2.hasNext()) {
ExceptionThru *thru1 = thrus_iter1.next();
ExceptionThru *thru2 = thrus_iter2.next();
if (!thru1->intersectsPts(thru2))
if (!thru1->intersectsPts(thru2, network))
return false;
}
return true;
@ -373,7 +375,8 @@ bool
ExceptionPath::resetMatch(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
const MinMaxAll *min_max)
const MinMaxAll *min_max,
const Network *network)
{
// Only the reset expception points need to match.
// For example, if the reset is -from, it matches any
@ -382,56 +385,57 @@ ExceptionPath::resetMatch(ExceptionFrom *from,
return ((from && from_
&& thrus == nullptr
&& to == nullptr
&& from_->intersectsPts(from))
&& from_->intersectsPts(from, network))
// -thru
|| (from == nullptr
&& thrus && thrus_
&& to == nullptr
&& thrusIntersectPts(thrus_, thrus))
&& thrusIntersectPts(thrus_, thrus, network))
// -to
|| (from == nullptr
&& thrus == nullptr
&& to && to_
&& to_->intersectsPts(to))
&& to_->intersectsPts(to, network))
// -from -thru
|| (from && from_
&& thrus && thrus_
&& to == nullptr
&& from_->intersectsPts(from)
&& thrusIntersectPts(thrus_, thrus))
&& from_->intersectsPts(from, network)
&& thrusIntersectPts(thrus_, thrus, network))
// -from -to
|| (from && from_
&& thrus == nullptr
&& to && to_
&& from_->intersectsPts(from)
&& to_->intersectsPts(to))
&& from_->intersectsPts(from, network)
&& to_->intersectsPts(to, network))
// -thru -to
|| (from == nullptr
&& thrus && thrus_
&& to && to_
&& thrusIntersectPts(thrus_, thrus)
&& to_->intersectsPts(to))
&& thrusIntersectPts(thrus_, thrus, network)
&& to_->intersectsPts(to, network))
// -from -thru -to
|| (from && from_
&& thrus && thrus_
&& to && to_
&& from_->intersectsPts(from)
&& thrusIntersectPts(thrus_, thrus)
&& to_->intersectsPts(to)))
&& from_->intersectsPts(from, network)
&& thrusIntersectPts(thrus_, thrus, network)
&& to_->intersectsPts(to, network)))
&& (min_max == MinMaxAll::all()
|| min_max_ == min_max);
}
static bool
thrusIntersectPts(ExceptionThruSeq *thrus1,
ExceptionThruSeq *thrus2)
ExceptionThruSeq *thrus2,
const Network *network)
{
ExceptionThruSeq::Iterator thrus_iter1(thrus1);
ExceptionThruSeq::Iterator thrus_iter2(thrus2);
while (thrus_iter1.hasNext() && thrus_iter2.hasNext()) {
ExceptionThru *thru1 = thrus_iter1.next();
ExceptionThru *thru2 = thrus_iter2.next();
if (!thru1->intersectsPts(thru2))
if (!thru1->intersectsPts(thru2, network))
return false;
}
return true;
@ -774,7 +778,8 @@ bool
FilterPath::resetMatch(ExceptionFrom *,
ExceptionThruSeq *,
ExceptionTo *,
const MinMaxAll *)
const MinMaxAll *,
const Network *)
{
return false;
}
@ -1220,12 +1225,13 @@ ExceptionFrom::clone(const Network *network)
}
bool
ExceptionFrom::intersectsPts(ExceptionFrom *from) const
ExceptionFrom::intersectsPts(ExceptionFrom *from,
const Network *network) const
{
return from->transition() == rf_
&& ((pins_ && PinSet::intersects(pins_, from->pins()))
|| (clks_ && ClockSet::intersects(clks_, from->clks()))
|| (insts_ && InstanceSet::intersects(insts_, from->instances())));
&& ((pins_ && PinSet::intersects(pins_, from->pins(), network))
|| (clks_ && ClockSet::intersects(clks_, from->clks(), ClockIndexLess()))
|| (insts_ && InstanceSet::intersects(insts_, from->instances(), network)));
}
const char *
@ -1284,13 +1290,14 @@ ExceptionTo::asString(const Network *network) const
}
bool
ExceptionTo::intersectsPts(ExceptionTo *to) const
ExceptionTo::intersectsPts(ExceptionTo *to,
const Network *network) const
{
return to->transition() == rf_
&& to->endTransition() == end_rf_
&& ((pins_ && PinSet::intersects(pins_, to->pins()))
|| (clks_ && ClockSet::intersects(clks_, to->clks()))
|| (insts_ && InstanceSet::intersects(insts_, to->instances())));
&& ((pins_ && PinSet::intersects(pins_, to->pins(), network))
|| (clks_ && ClockSet::intersects(clks_, to->clks(), ClockIndexLess()))
|| (insts_ && InstanceSet::intersects(insts_, to->instances(), network)));
}
bool
@ -1926,12 +1933,13 @@ ExceptionThru::deleteObjects(ExceptionThru *pt,
}
bool
ExceptionThru::intersectsPts(ExceptionThru *thru) const
ExceptionThru::intersectsPts(ExceptionThru *thru,
const Network *network) const
{
return thru->transition() == rf_
&& ((pins_ && PinSet::intersects(pins_, thru->pins()))
|| (nets_ && NetSet::intersects(nets_, thru->nets()))
|| (insts_ && InstanceSet::intersects(insts_, thru->instances())));
&& ((pins_ && PinSet::intersects(pins_, thru->pins(), network))
|| (nets_ && NetSet::intersects(nets_, thru->nets(), network))
|| (insts_ && InstanceSet::intersects(insts_, thru->instances(), network)));
}
size_t
@ -1973,7 +1981,7 @@ ExceptionThru::connectPinAfter(PinSet *drvrs,
for (const Pin *thru_pin : *pins_) {
if (network->isHierarchical(thru_pin)) {
PinSet *thru_pin_drvrs = network->drivers(thru_pin);
if (PinSet::intersects(drvrs, thru_pin_drvrs))
if (PinSet::intersects(drvrs, thru_pin_drvrs, network))
makePinEdges(thru_pin, network);
}
}
@ -1985,7 +1993,7 @@ ExceptionThru::connectPinAfter(PinSet *drvrs,
while (inst_pin_iter->hasNext()) {
Pin *inst_pin = inst_pin_iter->next();
PinSet *inst_pin_drvrs = network->drivers(inst_pin);
if (PinSet::intersects(drvrs, inst_pin_drvrs))
if (PinSet::intersects(drvrs, inst_pin_drvrs, network))
makePinEdges(inst_pin, network);
}
delete inst_pin_iter;
@ -1995,7 +2003,7 @@ ExceptionThru::connectPinAfter(PinSet *drvrs,
if (nets_) {
for (const Net *net : *nets_) {
PinSet *net_drvrs = network->drivers(net);
if (PinSet::intersects(drvrs, net_drvrs))
if (PinSet::intersects(drvrs, net_drvrs, network))
makeNetEdges(net, network);
}
}

View File

@ -4355,7 +4355,7 @@ Sdc::findMatchingExceptionsFirstThru(ExceptionPath *exception,
ExceptionThru *match_thru = (*match->thrus())[0];
if (match_thru->nets()->hasKey(net)
&& match->overrides(exception)
&& match->intersectsPts(exception))
&& match->intersectsPts(exception, network_))
matches.insert(match);
}
}
@ -4427,7 +4427,7 @@ Sdc::findMatchingExceptions(ExceptionPath *exception,
if (potential_matches) {
for (ExceptionPath *match : *potential_matches) {
if (match->overrides(exception)
&& match->intersectsPts(exception))
&& match->intersectsPts(exception, network_))
matches.insert(match);
}
}
@ -5072,7 +5072,7 @@ Sdc::resetPath(ExceptionFrom *from,
ExceptionPathSet::Iterator except_iter(exceptions_);
while (except_iter.hasNext()) {
ExceptionPath *match = except_iter.next();
if (match->resetMatch(from, thrus, to, min_max)) {
if (match->resetMatch(from, thrus, to, min_max, network_)) {
debugPrint(debug_, "exception_match", 3, "reset match %s",
match->asString(network_));
ExceptionPathSet expansions;
@ -5081,7 +5081,7 @@ Sdc::resetPath(ExceptionFrom *from,
ExceptionPathSet::Iterator expand_iter(expansions);
while (expand_iter.hasNext()) {
ExceptionPath *expand = expand_iter.next();
if (expand->resetMatch(from, thrus, to, min_max)) {
if (expand->resetMatch(from, thrus, to, min_max, network_)) {
unrecordPathDelayInternalStartpoints(expand->from());
unrecordPathDelayInternalEndpoints(expand);
delete expand;

View File

@ -16,9 +16,9 @@
#include "WriteSdc.hh"
#include <stdio.h>
#include <cstdio>
#include <algorithm>
#include <time.h>
#include <ctime>
#include "Zlib.hh"
#include "Report.hh"

View File

@ -16,7 +16,7 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <ctype.h>
#include <cctype>
#include "sdf/SdfReaderPvt.hh"

View File

@ -16,8 +16,8 @@
#include "sdf/SdfReader.hh"
#include <stdarg.h>
#include <ctype.h>
#include <cstdarg>
#include <cctype>
#include "Error.hh"
#include "Debug.hh"

View File

@ -16,8 +16,8 @@
#include "sdf/SdfWriter.hh"
#include <stdio.h>
#include <time.h>
#include <cstdio>
#include <ctime>
#include "Zlib.hh"
#include "StaConfig.hh" // STA_VERSION

View File

@ -16,8 +16,6 @@
#include "Bfs.hh"
#include <limits.h>
#include "Report.hh"
#include "Debug.hh"
#include "Mutex.hh"
@ -323,7 +321,7 @@ BfsIterator::remove(Vertex *vertex)
BfsFwdIterator::BfsFwdIterator(BfsIndex bfs_index,
SearchPred *search_pred,
StaState *sta) :
BfsIterator(bfs_index, 0, INT_MAX, search_pred, sta)
BfsIterator(bfs_index, 0, level_max, search_pred, sta)
{
}
@ -377,7 +375,7 @@ BfsFwdIterator::enqueueAdjacentVertices(Vertex *vertex,
BfsBkwdIterator::BfsBkwdIterator(BfsIndex bfs_index,
SearchPred *search_pred,
StaState *sta) :
BfsIterator(bfs_index, INT_MAX, 0, search_pred, sta)
BfsIterator(bfs_index, level_max, 0, search_pred, sta)
{
}

View File

@ -402,7 +402,7 @@ CheckCrpr::crprPossible(const Clock *clk1,
|| clk1->isGenerated()
|| clk2->isGenerated()
// Different non-generated clocks with the same source pins (using -add).
|| PinSet::intersects(clk1->pins(), clk2->pins()));
|| PinSet::intersects(&clk1->pins(), &clk2->pins(), network_));
}
} // namespace

View File

@ -90,7 +90,7 @@ PathEnumed::transition(const StaState *sta) const
int
PathEnumed::trIndex(const StaState *sta) const
{
return tag(sta)->trIndex();
return tag(sta)->rfIndex();
}
PathAnalysisPt *

View File

@ -64,7 +64,7 @@ protected:
TimingArc *prev_arc_;
Arrival arrival_;
VertexId vertex_id_;
unsigned int tag_index_:tag_index_bits;
TagIndex tag_index_;
};
void deletePathEnumed(PathEnumed *path);

View File

@ -193,7 +193,7 @@ PathVertex::transition(const StaState *) const
int
PathVertex::rfIndex(const StaState *) const
{
return tag_->trIndex();
return tag_->rfIndex();
}
PathAnalysisPt *
@ -567,7 +567,7 @@ VertexPathIterator::findNext()
int arrival_index;
arrival_iter_.next(tag, arrival_index);
if ((rf_ == nullptr
|| tag->trIndex() == rf_->index())
|| tag->rfIndex() == rf_->index())
&& (path_ap_ == nullptr
|| tag->pathAPIndex() == path_ap_->index())
&& (min_max_ == nullptr

View File

@ -2887,7 +2887,7 @@ Search::findTag(const RiseFall *rf,
tag_capacity_ = new_capacity;
tag_set_->reserve(new_capacity);
}
if (tag_next_ > tag_index_max)
if (tag_next_ == tag_index_max)
report_->critical(261, "max tag index exceeded");
}
if (own_states)

View File

@ -2412,6 +2412,8 @@ Sta::makeCorners()
void
Sta::makeCorners(StringSet *corner_names)
{
if (corner_names->size() > corner_count_max)
report_->error(374, "maximum corner count exceeded");
sdc_->makeCornersBefore();
parasitics_->deleteParasitics();
corners_->makeCorners(corner_names);

View File

@ -41,7 +41,7 @@ tagStateEqualCrpr(const Tag *tag1,
const Tag *tag2);
Tag::Tag(TagIndex index,
int tr_index,
int rf_index,
PathAPIndex path_ap_index,
ClkInfo *clk_info,
bool is_clk,
@ -53,13 +53,13 @@ Tag::Tag(TagIndex index,
clk_info_(clk_info),
input_delay_(input_delay),
states_(states),
index_(index),
is_clk_(is_clk),
is_filter_(false),
is_loop_(false),
is_segment_start_(is_segment_start),
own_states_(own_states),
index_(index),
tr_index_(tr_index),
rf_index_(rf_index),
path_ap_index_(path_ap_index)
{
findHash();
@ -177,7 +177,7 @@ Tag::asString(bool report_index,
const RiseFall *
Tag::transition() const
{
return RiseFall::find(tr_index_);
return RiseFall::find(rf_index_);
}
PathAnalysisPt *
@ -247,7 +247,7 @@ Tag::findHash()
{
// Common to hash_ and match_hash_.
hash_ = hash_init_value;
hashIncr(hash_, tr_index_);
hashIncr(hash_, rf_index_);
hashIncr(hash_, path_ap_index_);
hashIncr(hash_, is_clk_);
hashIncr(hash_, is_segment_start_);
@ -297,11 +297,11 @@ tagCmp(const Tag *tag1,
return 0;
if (cmp_rf) {
int tr_index1 = tag1->trIndex();
int tr_index2 = tag2->trIndex();
if (tr_index1 < tr_index2)
int rf_index1 = tag1->rfIndex();
int rf_index2 = tag2->rfIndex();
if (rf_index1 < rf_index2)
return -1;
if (tr_index1 > tr_index2)
if (rf_index1 > rf_index2)
return 1;
}
@ -350,7 +350,7 @@ tagEqual(const Tag *tag1,
const Tag *tag2)
{
return tag1 == tag2
|| (tag1->trIndex() == tag2->trIndex()
|| (tag1->rfIndex() == tag2->rfIndex()
&& tag1->pathAPIndex() == tag2->pathAPIndex()
&& tag1->clkInfo() == tag2->clkInfo()
&& tag1->isClock() == tag2->isClock()
@ -404,7 +404,7 @@ tagMatch(const Tag *tag1,
const ClkInfo *clk_info2 = tag2->clkInfo();
return tag1 == tag2
|| (clk_info1->clkEdge() == clk_info2->clkEdge()
&& tag1->trIndex() == tag2->trIndex()
&& tag1->rfIndex() == tag2->rfIndex()
&& tag1->pathAPIndex() == tag2->pathAPIndex()
&& tag1->isClock() == tag2->isClock()
&& tag1->isSegmentStart() == tag2->isSegmentStart()
@ -424,11 +424,11 @@ tagMatchCmp(const Tag *tag1,
if (tag1 == tag2)
return 0;
int tr_index1 = tag1->trIndex();
int tr_index2 = tag2->trIndex();
if (tr_index1 < tr_index2)
int rf_index1 = tag1->rfIndex();
int rf_index2 = tag2->rfIndex();
if (rf_index1 < rf_index2)
return -1;
if (tr_index1 > tr_index2)
if (rf_index1 > rf_index2)
return 1;
PathAPIndex path_ap_index1 = tag1->pathAPIndex();
@ -491,7 +491,7 @@ tagMatchNoCrpr(const Tag *tag1,
const ClkInfo *clk_info2 = tag2->clkInfo();
return tag1 == tag2
|| (clk_info1->clkEdge() == clk_info2->clkEdge()
&& tag1->trIndex() == tag2->trIndex()
&& tag1->rfIndex() == tag2->rfIndex()
&& tag1->pathAPIndex() == tag2->pathAPIndex()
&& tag1->isClock() == tag2->isClock()
&& clk_info1->isGenClkSrcPath() == clk_info2->isGenClkSrcPath()
@ -506,7 +506,7 @@ tagMatchNoPathAp(const Tag *tag1,
const ClkInfo *clk_info2 = tag2->clkInfo();
return tag1 == tag2
|| (clk_info1->clkEdge() == clk_info2->clkEdge()
&& tag1->trIndex() == tag2->trIndex()
&& tag1->rfIndex() == tag2->rfIndex()
&& tag1->isClock() == tag2->isClock()
&& tag1->isSegmentStart() == tag2->isSegmentStart()
&& clk_info1->isGenClkSrcPath() == clk_info2->isGenClkSrcPath()
@ -521,7 +521,7 @@ tagMatchCrpr(const Tag *tag1,
const ClkInfo *clk_info2 = tag2->clkInfo();
return tag1 == tag2
|| (clk_info1->clkEdge() == clk_info2->clkEdge()
&& tag1->trIndex() == tag2->trIndex()
&& tag1->rfIndex() == tag2->rfIndex()
&& tag1->isClock() == tag2->isClock()
&& tag1->isSegmentStart() == tag2->isSegmentStart()
&& clk_info1->isGenClkSrcPath() == clk_info2->isGenClkSrcPath()

View File

@ -44,7 +44,7 @@ class Tag
{
public:
Tag(TagIndex index,
int tr_index,
int rf_index,
PathAPIndex path_ap_index,
ClkInfo *clk_info,
bool is_clk,
@ -63,7 +63,7 @@ public:
const ClockEdge *clkEdge() const;
const Clock *clock() const;
const Pin *clkSrc() const;
int trIndex() const { return tr_index_; }
int rfIndex() const { return rf_index_; }
const RiseFall *transition() const;
PathAnalysisPt *pathAnalysisPt(const StaState *sta) const;
PathAPIndex pathAPIndex() const { return path_ap_index_; }
@ -89,14 +89,14 @@ private:
ExceptionStateSet *states_;
size_t hash_;
size_t match_hash_;
TagIndex index_;
bool is_clk_:1;
bool is_filter_:1;
bool is_loop_:1;
bool is_segment_start_:1;
// Indicates that states_ is owned by the tag.
bool own_states_:1;
TagIndex index_:tag_index_bits;
unsigned int tr_index_:RiseFall::index_bit_count;
unsigned int rf_index_:RiseFall::index_bit_count;
unsigned int path_ap_index_:path_ap_index_bit_count;
};

View File

@ -4909,6 +4909,7 @@ write_path_spice_cmd(PathRef *path,
writePathSpice(path, spice_filename, subckt_filename,
lib_subckt_filename, model_filename, off_path_pins,
power_name, gnd_name, sta);
delete off_path_pins;
}
void
@ -5725,6 +5726,23 @@ current_waveform(float in_slew,
return nullptr;
}
float
voltage_current(float in_slew,
float load_cap,
float voltage)
{
GateTableModel *gate_model = dynamic_cast<GateTableModel*>(self->model());
if (gate_model) {
OutputWaveforms *waveforms = gate_model->outputWaveforms();
if (waveforms) {
waveforms->setVdd(.7);
float current = waveforms->voltageCurrent(in_slew, load_cap, voltage);
return current;
}
}
return 0.0;
}
} // TimingArc methods
%extend Instance {

View File

@ -16,8 +16,8 @@
#include "Error.hh"
#include <stdlib.h>
#include <stdio.h>
#include <cstdlib>
#include <cstdio>
#include "StringUtil.hh"

View File

@ -16,7 +16,7 @@
#include "Hash.hh"
#include <string.h>
#include <cstring>
namespace sta {

View File

@ -15,7 +15,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include "PatternMatch.hh"
#include <string.h>
#include <cstring>
#include <tcl.h>
namespace sta {

View File

@ -16,8 +16,8 @@
#include "ReportStd.hh"
#include <stdlib.h>
#include <stdio.h>
#include <cstdlib>
#include <cstdio>
#include "Report.hh"

View File

@ -16,8 +16,8 @@
#include "ReportTcl.hh"
#include <stdio.h>
#include <stdlib.h>
#include <cstdio>
#include <cstdlib>
namespace sta {

View File

@ -17,8 +17,8 @@
#include "StringUtil.hh"
#include <limits>
#include <ctype.h>
#include <stdio.h>
#include <cctype>
#include <cstdio>
#include "Machine.hh"
#include "Mutex.hh"

View File

@ -16,8 +16,8 @@
#include "TokenParser.hh"
#include <ctype.h>
#include <string.h>
#include <cctype>
#include <cstring>
namespace sta {

View File

@ -16,7 +16,7 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <stdlib.h>
#include <cstdlib>
#include "PortDirection.hh"
#include "verilog/VerilogReaderPvt.hh"

View File

@ -16,7 +16,7 @@
#include "VerilogReader.hh"
#include <stdlib.h>
#include <cstdlib>
#include "Debug.hh"
#include "Report.hh"

View File

@ -16,7 +16,7 @@
#include "VerilogWriter.hh"
#include <stdlib.h>
#include <cstdlib>
#include <algorithm>
#include "Error.hh"