sync
This commit is contained in:
parent
f2a28bdcaf
commit
ca231b29cc
|
|
@ -164,7 +164,7 @@ ArnoldiReduce::loadWork()
|
||||||
|
|
||||||
int resistor_count = 0;
|
int resistor_count = 0;
|
||||||
ConcreteParasiticDeviceSet devices;
|
ConcreteParasiticDeviceSet devices;
|
||||||
parasitic_network_->devices(devices);
|
parasitic_network_->devices(&devices);
|
||||||
ConcreteParasiticDeviceSet::Iterator device_iter(devices);
|
ConcreteParasiticDeviceSet::Iterator device_iter(devices);
|
||||||
while (device_iter.hasNext()) {
|
while (device_iter.hasNext()) {
|
||||||
ParasiticDevice *device = device_iter.next();
|
ParasiticDevice *device = device_iter.next();
|
||||||
|
|
|
||||||
|
|
@ -134,6 +134,18 @@ ConcreteParasitic::setPoleResidue(const Pin *,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ParasiticDeviceIterator *
|
||||||
|
ConcreteParasitic::deviceIterator()
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParasiticNodeIterator *
|
||||||
|
ConcreteParasitic::nodeIterator()
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ConcreteElmore::ConcreteElmore() :
|
ConcreteElmore::ConcreteElmore() :
|
||||||
|
|
@ -726,12 +738,37 @@ void
|
||||||
ConcreteParasiticNetwork::deleteDevices()
|
ConcreteParasiticNetwork::deleteDevices()
|
||||||
{
|
{
|
||||||
ConcreteParasiticDeviceSet devices1;
|
ConcreteParasiticDeviceSet devices1;
|
||||||
devices(devices1);
|
devices(&devices1);
|
||||||
devices1.deleteContents();
|
devices1.deleteContents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ParasiticNodeIterator *
|
||||||
|
ConcreteParasiticNetwork::nodeIterator()
|
||||||
|
{
|
||||||
|
ConcreteParasiticNodeSeq *nodes = new ConcreteParasiticNodeSeq();
|
||||||
|
ConcreteParasiticPinNodeMap::Iterator node_iter2(pin_nodes_);
|
||||||
|
while (node_iter2.hasNext()) {
|
||||||
|
ConcreteParasiticPinNode *node = node_iter2.next();
|
||||||
|
nodes->push_back(node);
|
||||||
|
}
|
||||||
|
ConcreteParasiticSubNodeMap::Iterator node_iter1(sub_nodes_);
|
||||||
|
while (node_iter1.hasNext()) {
|
||||||
|
ConcreteParasiticSubNode *node = node_iter1.next();
|
||||||
|
nodes->push_back(node);
|
||||||
|
}
|
||||||
|
return new ConcreteParasiticNodeSeqIterator(nodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
ParasiticDeviceIterator *
|
||||||
|
ConcreteParasiticNetwork::deviceIterator()
|
||||||
|
{
|
||||||
|
ConcreteParasiticDeviceSet *devices1 = new ConcreteParasiticDeviceSet();
|
||||||
|
devices(devices1);
|
||||||
|
return new ConcreteParasiticDeviceSetIterator(devices1);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ConcreteParasiticNetwork::devices(ConcreteParasiticDeviceSet &devices)
|
ConcreteParasiticNetwork::devices(ConcreteParasiticDeviceSet *devices)
|
||||||
{
|
{
|
||||||
// Collect devices into a set so they are only deleted once
|
// Collect devices into a set so they are only deleted once
|
||||||
// because multiple sub-nodes or pin nodes can refer to them.
|
// because multiple sub-nodes or pin nodes can refer to them.
|
||||||
|
|
@ -741,7 +778,7 @@ ConcreteParasiticNetwork::devices(ConcreteParasiticDeviceSet &devices)
|
||||||
ConcreteParasiticDeviceSeq::Iterator device_iter(node->devices());
|
ConcreteParasiticDeviceSeq::Iterator device_iter(node->devices());
|
||||||
while (device_iter.hasNext()) {
|
while (device_iter.hasNext()) {
|
||||||
ConcreteParasiticDevice *device = device_iter.next();
|
ConcreteParasiticDevice *device = device_iter.next();
|
||||||
devices.insert(device);
|
devices->insert(device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -751,7 +788,7 @@ ConcreteParasiticNetwork::devices(ConcreteParasiticDeviceSet &devices)
|
||||||
ConcreteParasiticDeviceSeq::Iterator device_iter(node->devices());
|
ConcreteParasiticDeviceSeq::Iterator device_iter(node->devices());
|
||||||
while (device_iter.hasNext()) {
|
while (device_iter.hasNext()) {
|
||||||
ConcreteParasiticDevice *device = device_iter.next();
|
ConcreteParasiticDevice *device = device_iter.next();
|
||||||
devices.insert(device);
|
devices->insert(device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1798,6 +1835,20 @@ ConcreteParasitics::makeResistor(const char *name,
|
||||||
cnode2->addDevice(resistor);
|
cnode2->addDevice(resistor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ParasiticDeviceIterator *
|
||||||
|
ConcreteParasitics::deviceIterator(Parasitic *parasitic)
|
||||||
|
{
|
||||||
|
ConcreteParasitic *cparasitic = static_cast<ConcreteParasitic*>(parasitic);
|
||||||
|
return cparasitic->deviceIterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
ParasiticNodeIterator *
|
||||||
|
ConcreteParasitics::nodeIterator(Parasitic *parasitic)
|
||||||
|
{
|
||||||
|
ConcreteParasitic *cparasitic = static_cast<ConcreteParasitic*>(parasitic);
|
||||||
|
return cparasitic->nodeIterator();
|
||||||
|
}
|
||||||
|
|
||||||
float
|
float
|
||||||
ConcreteParasitics::nodeGndCap(const ParasiticNode *node,
|
ConcreteParasitics::nodeGndCap(const ParasiticNode *node,
|
||||||
const ParasiticAnalysisPt *) const
|
const ParasiticAnalysisPt *) const
|
||||||
|
|
@ -1838,17 +1889,11 @@ ConcreteParasitics::findNode(Parasitic *parasitic,
|
||||||
return cparasitic->findNode(pin);
|
return cparasitic->findNode(pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConcreteParasiticDeviceIterator::
|
|
||||||
ConcreteParasiticDeviceIterator(ConcreteParasiticNode *node) :
|
|
||||||
iter_(node->devices())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ParasiticDeviceIterator *
|
ParasiticDeviceIterator *
|
||||||
ConcreteParasitics::deviceIterator(ParasiticNode *node) const
|
ConcreteParasitics::deviceIterator(ParasiticNode *node) const
|
||||||
{
|
{
|
||||||
ConcreteParasiticNode *cnode = static_cast<ConcreteParasiticNode*>(node);
|
ConcreteParasiticNode *cnode = static_cast<ConcreteParasiticNode*>(node);
|
||||||
return new ConcreteParasiticDeviceIterator(cnode);
|
return new ConcreteParasiticDeviceSeqIterator(cnode->devices());
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
|
|
@ -2031,4 +2076,34 @@ ConcreteParasitics::estimatePiElmore(const Pin *drvr_pin,
|
||||||
sdc_);
|
sdc_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ConcreteParasiticDeviceSeqIterator::
|
||||||
|
ConcreteParasiticDeviceSeqIterator(ConcreteParasiticDeviceSeq *devices) :
|
||||||
|
iter_(devices)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ConcreteParasiticDeviceSetIterator::
|
||||||
|
ConcreteParasiticDeviceSetIterator(ConcreteParasiticDeviceSet *devices) :
|
||||||
|
iter_(devices)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ConcreteParasiticDeviceSetIterator::~ConcreteParasiticDeviceSetIterator()
|
||||||
|
{
|
||||||
|
delete iter_.container();
|
||||||
|
}
|
||||||
|
|
||||||
|
ConcreteParasiticNodeSeqIterator::
|
||||||
|
ConcreteParasiticNodeSeqIterator(ConcreteParasiticNodeSeq *nodes) :
|
||||||
|
iter_(nodes)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ConcreteParasiticNodeSeqIterator::~ConcreteParasiticNodeSeqIterator()
|
||||||
|
{
|
||||||
|
delete iter_.container();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
||||||
|
|
@ -162,6 +162,8 @@ public:
|
||||||
virtual void makeResistor(const char *name, ParasiticNode *node1,
|
virtual void makeResistor(const char *name, ParasiticNode *node1,
|
||||||
ParasiticNode *node2,
|
ParasiticNode *node2,
|
||||||
float res, const ParasiticAnalysisPt *ap);
|
float res, const ParasiticAnalysisPt *ap);
|
||||||
|
virtual ParasiticDeviceIterator *deviceIterator(Parasitic *parasitic);
|
||||||
|
virtual ParasiticNodeIterator *nodeIterator(Parasitic *parasitic);
|
||||||
|
|
||||||
virtual const char *name(const ParasiticNode *node);
|
virtual const char *name(const ParasiticNode *node);
|
||||||
virtual const Pin *connectionPin(const ParasiticNode *node) const;
|
virtual const Pin *connectionPin(const ParasiticNode *node) const;
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ class ConcretePoleResidue;
|
||||||
class ConcreteParasiticDevice;
|
class ConcreteParasiticDevice;
|
||||||
class ConcreteParasiticPinNode;
|
class ConcreteParasiticPinNode;
|
||||||
class ConcreteParasiticSubNode;
|
class ConcreteParasiticSubNode;
|
||||||
|
class ConcreteParasiticNode;
|
||||||
|
|
||||||
typedef Map<const Pin*, float> ConcreteElmoreLoadMap;
|
typedef Map<const Pin*, float> ConcreteElmoreLoadMap;
|
||||||
typedef ConcreteElmoreLoadMap::Iterator ConcretePiElmoreLoadIterator;
|
typedef ConcreteElmoreLoadMap::Iterator ConcretePiElmoreLoadIterator;
|
||||||
|
|
@ -41,6 +42,7 @@ typedef Map<const Pin*,
|
||||||
ConcreteParasiticPinNode*> ConcreteParasiticPinNodeMap;
|
ConcreteParasiticPinNode*> ConcreteParasiticPinNodeMap;
|
||||||
typedef Vector<ConcreteParasiticDevice*> ConcreteParasiticDeviceSeq;
|
typedef Vector<ConcreteParasiticDevice*> ConcreteParasiticDeviceSeq;
|
||||||
typedef Set<ConcreteParasiticDevice*> ConcreteParasiticDeviceSet;
|
typedef Set<ConcreteParasiticDevice*> ConcreteParasiticDeviceSet;
|
||||||
|
typedef Vector<ConcreteParasiticNode*> ConcreteParasiticNodeSeq;
|
||||||
|
|
||||||
// Empty base class definitions so casts are not required on returned
|
// Empty base class definitions so casts are not required on returned
|
||||||
// objects.
|
// objects.
|
||||||
|
|
@ -78,6 +80,8 @@ public:
|
||||||
virtual void setPoleResidue(const Pin *load_pin,
|
virtual void setPoleResidue(const Pin *load_pin,
|
||||||
ComplexFloatSeq *poles,
|
ComplexFloatSeq *poles,
|
||||||
ComplexFloatSeq *residues);
|
ComplexFloatSeq *residues);
|
||||||
|
virtual ParasiticDeviceIterator *deviceIterator();
|
||||||
|
virtual ParasiticNodeIterator *nodeIterator();
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConcreteElmore
|
class ConcreteElmore
|
||||||
|
|
@ -268,7 +272,8 @@ protected:
|
||||||
class ConcreteParasiticSubNode : public ConcreteParasiticNode
|
class ConcreteParasiticSubNode : public ConcreteParasiticNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ConcreteParasiticSubNode(Net *net, int id);
|
ConcreteParasiticSubNode(Net *net,
|
||||||
|
int id);
|
||||||
virtual const char *name(const Network *network) const;
|
virtual const char *name(const Network *network) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -391,10 +396,22 @@ public:
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConcreteParasiticDeviceIterator : public ParasiticDeviceIterator
|
class ConcreteParasiticDeviceSetIterator : public ParasiticDeviceIterator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ConcreteParasiticDeviceIterator(ConcreteParasiticNode *node);
|
ConcreteParasiticDeviceSetIterator(ConcreteParasiticDeviceSet *devices);
|
||||||
|
virtual ~ConcreteParasiticDeviceSetIterator();
|
||||||
|
bool hasNext() { return iter_.hasNext(); }
|
||||||
|
ParasiticDevice *next() { return iter_.next(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
ConcreteParasiticDeviceSet::ConstIterator iter_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConcreteParasiticDeviceSeqIterator : public ParasiticDeviceIterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConcreteParasiticDeviceSeqIterator(ConcreteParasiticDeviceSeq *devices);
|
||||||
bool hasNext() { return iter_.hasNext(); }
|
bool hasNext() { return iter_.hasNext(); }
|
||||||
ParasiticDevice *next() { return iter_.next(); }
|
ParasiticDevice *next() { return iter_.next(); }
|
||||||
|
|
||||||
|
|
@ -402,6 +419,18 @@ private:
|
||||||
ConcreteParasiticDeviceSeq::ConstIterator iter_;
|
ConcreteParasiticDeviceSeq::ConstIterator iter_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ConcreteParasiticNodeSeqIterator : public ParasiticNodeIterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConcreteParasiticNodeSeqIterator(ConcreteParasiticNodeSeq *devices);
|
||||||
|
virtual ~ConcreteParasiticNodeSeqIterator();
|
||||||
|
bool hasNext() { return iter_.hasNext(); }
|
||||||
|
ParasiticNode *next() { return iter_.next(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
ConcreteParasiticNodeSeq::ConstIterator iter_;
|
||||||
|
};
|
||||||
|
|
||||||
class ConcreteParasiticNetwork : public ParasiticNetwork,
|
class ConcreteParasiticNetwork : public ParasiticNetwork,
|
||||||
public ConcreteParasitic
|
public ConcreteParasitic
|
||||||
{
|
{
|
||||||
|
|
@ -418,7 +447,10 @@ public:
|
||||||
ConcreteParasiticPinNodeMap *pinNodes() { return &pin_nodes_; }
|
ConcreteParasiticPinNodeMap *pinNodes() { return &pin_nodes_; }
|
||||||
ConcreteParasiticSubNodeMap *subNodes() { return &sub_nodes_; }
|
ConcreteParasiticSubNodeMap *subNodes() { return &sub_nodes_; }
|
||||||
void disconnectPin(const Pin *pin, Net *net);
|
void disconnectPin(const Pin *pin, Net *net);
|
||||||
void devices(ConcreteParasiticDeviceSet &devices);
|
virtual ParasiticDeviceIterator *deviceIterator();
|
||||||
|
virtual ParasiticNodeIterator *nodeIterator();
|
||||||
|
virtual void devices(// Return value.
|
||||||
|
ConcreteParasiticDeviceSet *devices);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void deleteNodes();
|
void deleteNodes();
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,8 @@ public:
|
||||||
makeParasiticNetwork(Net *net,
|
makeParasiticNetwork(Net *net,
|
||||||
bool pin_cap_included,
|
bool pin_cap_included,
|
||||||
const ParasiticAnalysisPt *ap);
|
const ParasiticAnalysisPt *ap);
|
||||||
|
virtual ParasiticDeviceIterator *deviceIterator(Parasitic *) { return NULL; }
|
||||||
|
virtual ParasiticNodeIterator *nodeIterator(Parasitic *) { return NULL; }
|
||||||
virtual bool includesPinCaps(Parasitic *parasitic) const;
|
virtual bool includesPinCaps(Parasitic *parasitic) const;
|
||||||
virtual void deleteParasiticNetwork(const Net *net,
|
virtual void deleteParasiticNetwork(const Net *net,
|
||||||
const ParasiticAnalysisPt *ap);
|
const ParasiticAnalysisPt *ap);
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ class Corner;
|
||||||
typedef std::complex<float> ComplexFloat;
|
typedef std::complex<float> ComplexFloat;
|
||||||
typedef Vector<ComplexFloat> ComplexFloatSeq;
|
typedef Vector<ComplexFloat> ComplexFloatSeq;
|
||||||
typedef Iterator<ParasiticDevice*> ParasiticDeviceIterator;
|
typedef Iterator<ParasiticDevice*> ParasiticDeviceIterator;
|
||||||
|
typedef Iterator<ParasiticNode*> ParasiticNodeIterator;
|
||||||
|
|
||||||
// Parasitics API.
|
// Parasitics API.
|
||||||
// All parasitic parameters can have multiple values, each corresponding
|
// All parasitic parameters can have multiple values, each corresponding
|
||||||
|
|
@ -171,7 +172,7 @@ public:
|
||||||
ComplexFloat &residue) const=0;
|
ComplexFloat &residue) const=0;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
// Parasitic Network (detailed parasitics, or DSPF).
|
// Parasitic Network (detailed parasitics).
|
||||||
// This api assumes that parasitic networks are not rise/fall
|
// This api assumes that parasitic networks are not rise/fall
|
||||||
// dependent because they do not include pin capacitances.
|
// dependent because they do not include pin capacitances.
|
||||||
virtual bool isParasiticNetwork(Parasitic *parasitic) const = 0;
|
virtual bool isParasiticNetwork(Parasitic *parasitic) const = 0;
|
||||||
|
|
@ -184,6 +185,8 @@ public:
|
||||||
virtual Parasitic *makeParasiticNetwork(Net *net,
|
virtual Parasitic *makeParasiticNetwork(Net *net,
|
||||||
bool pin_cap_included,
|
bool pin_cap_included,
|
||||||
const ParasiticAnalysisPt *ap) = 0;
|
const ParasiticAnalysisPt *ap) = 0;
|
||||||
|
virtual ParasiticDeviceIterator *deviceIterator(Parasitic *parasitic) = 0;
|
||||||
|
virtual ParasiticNodeIterator *nodeIterator(Parasitic *parasitic) = 0;
|
||||||
// Delete parasitic network if it exists.
|
// Delete parasitic network if it exists.
|
||||||
virtual void deleteParasiticNetwork(const Net *net,
|
virtual void deleteParasiticNetwork(const Net *net,
|
||||||
const ParasiticAnalysisPt *ap) = 0;
|
const ParasiticAnalysisPt *ap) = 0;
|
||||||
|
|
|
||||||
|
|
@ -75,9 +75,9 @@ PathEnd::pathEarlyLate(const StaState *sta) const
|
||||||
}
|
}
|
||||||
|
|
||||||
const EarlyLate *
|
const EarlyLate *
|
||||||
PathEnd::clkEarlyLate(const StaState *) const
|
PathEnd::clkEarlyLate(const StaState *sta) const
|
||||||
{
|
{
|
||||||
return NULL;
|
return checkRole(sta)->tgtClkEarlyLate();
|
||||||
}
|
}
|
||||||
|
|
||||||
const TransRiseFall *
|
const TransRiseFall *
|
||||||
|
|
@ -552,15 +552,6 @@ PathEndClkConstrained::setPath(PathEnumed *path,
|
||||||
crpr_valid_ = false;
|
crpr_valid_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const EarlyLate *
|
|
||||||
PathEndClkConstrained::clkEarlyLate(const StaState *sta) const
|
|
||||||
{
|
|
||||||
if (clk_path_.isNull())
|
|
||||||
return NULL;
|
|
||||||
else
|
|
||||||
return clk_path_.pathAnalysisPt(sta)->pathMinMax();
|
|
||||||
}
|
|
||||||
|
|
||||||
float
|
float
|
||||||
PathEndClkConstrained::sourceClkOffset(const StaState *sta) const
|
PathEndClkConstrained::sourceClkOffset(const StaState *sta) const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -239,7 +239,6 @@ private:
|
||||||
class PathEndClkConstrained : public PathEnd
|
class PathEndClkConstrained : public PathEnd
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual const EarlyLate *clkEarlyLate(const StaState *sta) const;
|
|
||||||
virtual float sourceClkOffset(const StaState *sta) const;
|
virtual float sourceClkOffset(const StaState *sta) const;
|
||||||
virtual Delay sourceClkLatency(const StaState *sta) const;
|
virtual Delay sourceClkLatency(const StaState *sta) const;
|
||||||
virtual Delay sourceClkInsertionDelay(const StaState *sta) const;
|
virtual Delay sourceClkInsertionDelay(const StaState *sta) const;
|
||||||
|
|
|
||||||
|
|
@ -747,7 +747,7 @@ WritePathSpice::writeStageVoltageSources(Stage stage,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (drvr_port->function())
|
||||||
sensitizationValues(inst, drvr_port->function(), input_port, port_values);
|
sensitizationValues(inst, drvr_port->function(), input_port, port_values);
|
||||||
int volt_index = 1;
|
int volt_index = 1;
|
||||||
debugPrint1(debug_, "write_spice", 2, "subckt %s\n", cell->name());
|
debugPrint1(debug_, "write_spice", 2, "subckt %s\n", cell->name());
|
||||||
|
|
@ -986,55 +986,6 @@ WritePathSpice::onePort(FuncExpr *expr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ParasiticNodeNameLess
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ParasiticNodeNameLess(Parasitics *parasitics);
|
|
||||||
bool operator()(const ParasiticNode *node1,
|
|
||||||
const ParasiticNode *node2) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Parasitics *parasitics_;
|
|
||||||
};
|
|
||||||
|
|
||||||
ParasiticNodeNameLess::ParasiticNodeNameLess(Parasitics *parasitics) :
|
|
||||||
parasitics_(parasitics)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
ParasiticNodeNameLess::operator()(const ParasiticNode *node1,
|
|
||||||
const ParasiticNode *node2) const
|
|
||||||
{
|
|
||||||
return stringLess(parasitics_->name(node1),
|
|
||||||
parasitics_->name(node2));
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef Set<ParasiticDevice*> ParasiticDeviceSet;
|
|
||||||
// Less uses names rather than pointers for stable results.
|
|
||||||
typedef Set<ParasiticNode*, ParasiticNodeNameLess> ParasiticNodeSet;
|
|
||||||
|
|
||||||
void
|
|
||||||
findParasiticDevicesNodes(ParasiticNode *node,
|
|
||||||
Parasitics *parasitics,
|
|
||||||
// Return values.
|
|
||||||
ParasiticNodeSet &nodes,
|
|
||||||
ParasiticDeviceSet &devices)
|
|
||||||
{
|
|
||||||
nodes.insert(node);
|
|
||||||
auto device_iter = parasitics->deviceIterator(node);
|
|
||||||
while (device_iter->hasNext()) {
|
|
||||||
auto device = device_iter->next();
|
|
||||||
if (!devices.hasKey(device)) {
|
|
||||||
devices.insert(device);
|
|
||||||
auto other_node = parasitics->otherNode(device, node);
|
|
||||||
if (other_node)
|
|
||||||
findParasiticDevicesNodes(other_node, parasitics, nodes, devices);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete device_iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
WritePathSpice::writeStageParasitics(Stage stage)
|
WritePathSpice::writeStageParasitics(Stage stage)
|
||||||
{
|
{
|
||||||
|
|
@ -1052,14 +1003,9 @@ WritePathSpice::writeStageParasitics(Stage stage)
|
||||||
net ? network_->pathName(net) : network_->pathName(drvr_pin);
|
net ? network_->pathName(net) : network_->pathName(drvr_pin);
|
||||||
initNodeMap(net_name);
|
initNodeMap(net_name);
|
||||||
streamPrint(spice_stream_, "* Net %s\n", net_name);
|
streamPrint(spice_stream_, "* Net %s\n", net_name);
|
||||||
auto node = parasitics_->findNode(parasitic, drvr_pin);
|
ParasiticDeviceIterator *device_iter = parasitics_->deviceIterator(parasitic);
|
||||||
ParasiticNodeNameLess node_name_less(parasitics_);
|
while (device_iter->hasNext()) {
|
||||||
ParasiticNodeSet nodes(node_name_less);
|
auto device = device_iter->next();
|
||||||
ParasiticDeviceSet devices;
|
|
||||||
findParasiticDevicesNodes(node, parasitics_, nodes, devices);
|
|
||||||
ParasiticDeviceSet::Iterator device_iter(devices);
|
|
||||||
while (device_iter.hasNext()) {
|
|
||||||
auto device = device_iter.next();
|
|
||||||
auto resistance = parasitics_->value(device, parasitic_ap);
|
auto resistance = parasitics_->value(device, parasitic_ap);
|
||||||
if (parasitics_->isResistor(device)) {
|
if (parasitics_->isResistor(device)) {
|
||||||
ParasiticNode *node1 = parasitics_->node1(device);
|
ParasiticNode *node1 = parasitics_->node1(device);
|
||||||
|
|
@ -1082,10 +1028,12 @@ WritePathSpice::writeStageParasitics(Stage stage)
|
||||||
cap_index++;
|
cap_index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ParasiticNodeSet::Iterator node_iter(nodes);
|
delete device_iter;
|
||||||
while (node_iter.hasNext()) {
|
ParasiticNodeIterator *node_iter = parasitics_->nodeIterator(parasitic);
|
||||||
auto node = node_iter.next();
|
while (node_iter->hasNext()) {
|
||||||
|
auto node = node_iter->next();
|
||||||
auto cap = parasitics_->nodeGndCap(node, parasitic_ap);
|
auto cap = parasitics_->nodeGndCap(node, parasitic_ap);
|
||||||
|
// Spice has a cow over zero value caps.
|
||||||
if (cap > 0.0) {
|
if (cap > 0.0) {
|
||||||
streamPrint(spice_stream_, "C%d %s 0 %.3e\n",
|
streamPrint(spice_stream_, "C%d %s 0 %.3e\n",
|
||||||
cap_index,
|
cap_index,
|
||||||
|
|
@ -1094,6 +1042,7 @@ WritePathSpice::writeStageParasitics(Stage stage)
|
||||||
cap_index++;
|
cap_index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
delete node_iter;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
streamPrint(spice_stream_, "* No parasitics found for this net.\n");
|
streamPrint(spice_stream_, "* No parasitics found for this net.\n");
|
||||||
|
|
|
||||||
16
tcl/Cmds.tcl
16
tcl/Cmds.tcl
|
|
@ -1932,7 +1932,7 @@ proc write_path_spice { args } {
|
||||||
flags {}
|
flags {}
|
||||||
|
|
||||||
if { [info exists keys(-spice_directory)] } {
|
if { [info exists keys(-spice_directory)] } {
|
||||||
set spice_dir $keys(-spice_directory)
|
set spice_dir [file_expand_tilde $keys(-spice_directory)]
|
||||||
if { ![file exists $spice_dir] } {
|
if { ![file exists $spice_dir] } {
|
||||||
sta_error "Directory $spice_dir not found.\n"
|
sta_error "Directory $spice_dir not found.\n"
|
||||||
}
|
}
|
||||||
|
|
@ -1947,7 +1947,7 @@ proc write_path_spice { args } {
|
||||||
}
|
}
|
||||||
|
|
||||||
if { [info exists keys(-lib_subckt_file)] } {
|
if { [info exists keys(-lib_subckt_file)] } {
|
||||||
set lib_subckt_file $keys(-lib_subckt_file)
|
set lib_subckt_file [file_expand_tilde $keys(-lib_subckt_file)]
|
||||||
if { ![file readable $lib_subckt_file] } {
|
if { ![file readable $lib_subckt_file] } {
|
||||||
sta_error "-lib_subckt_file $lib_subckt_file is not readable.\n"
|
sta_error "-lib_subckt_file $lib_subckt_file is not readable.\n"
|
||||||
}
|
}
|
||||||
|
|
@ -1956,7 +1956,7 @@ proc write_path_spice { args } {
|
||||||
}
|
}
|
||||||
|
|
||||||
if { [info exists keys(-lib_subckt_file)] } {
|
if { [info exists keys(-lib_subckt_file)] } {
|
||||||
set model_file $keys(-model_file)
|
set model_file [file_expand_tilde $keys(-model_file)]
|
||||||
if { ![file readable $model_file] } {
|
if { ![file readable $model_file] } {
|
||||||
sta_error "-model_file $model_file is not readable.\n"
|
sta_error "-model_file $model_file is not readable.\n"
|
||||||
}
|
}
|
||||||
|
|
@ -2003,5 +2003,15 @@ proc write_path_spice { args } {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc file_expand_tilde { filename } {
|
||||||
|
global env
|
||||||
|
|
||||||
|
if { [string range $filename 0 1] == "~/" } {
|
||||||
|
return [file join $env(HOME) [string range $filename 2 end]]
|
||||||
|
} else {
|
||||||
|
return $filename
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# sta namespace end.
|
# sta namespace end.
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue