This commit is contained in:
James Cherry 2019-01-25 18:06:24 -08:00
parent f2a28bdcaf
commit ca231b29cc
10 changed files with 156 additions and 93 deletions

View File

@ -164,7 +164,7 @@ ArnoldiReduce::loadWork()
int resistor_count = 0;
ConcreteParasiticDeviceSet devices;
parasitic_network_->devices(devices);
parasitic_network_->devices(&devices);
ConcreteParasiticDeviceSet::Iterator device_iter(devices);
while (device_iter.hasNext()) {
ParasiticDevice *device = device_iter.next();

View File

@ -134,6 +134,18 @@ ConcreteParasitic::setPoleResidue(const Pin *,
{
}
ParasiticDeviceIterator *
ConcreteParasitic::deviceIterator()
{
return NULL;
}
ParasiticNodeIterator *
ConcreteParasitic::nodeIterator()
{
return NULL;
}
////////////////////////////////////////////////////////////////
ConcreteElmore::ConcreteElmore() :
@ -726,12 +738,37 @@ void
ConcreteParasiticNetwork::deleteDevices()
{
ConcreteParasiticDeviceSet devices1;
devices(devices1);
devices(&devices1);
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
ConcreteParasiticNetwork::devices(ConcreteParasiticDeviceSet &devices)
ConcreteParasiticNetwork::devices(ConcreteParasiticDeviceSet *devices)
{
// Collect devices into a set so they are only deleted once
// 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());
while (device_iter.hasNext()) {
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());
while (device_iter.hasNext()) {
ConcreteParasiticDevice *device = device_iter.next();
devices.insert(device);
devices->insert(device);
}
}
}
@ -1798,6 +1835,20 @@ ConcreteParasitics::makeResistor(const char *name,
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
ConcreteParasitics::nodeGndCap(const ParasiticNode *node,
const ParasiticAnalysisPt *) const
@ -1838,17 +1889,11 @@ ConcreteParasitics::findNode(Parasitic *parasitic,
return cparasitic->findNode(pin);
}
ConcreteParasiticDeviceIterator::
ConcreteParasiticDeviceIterator(ConcreteParasiticNode *node) :
iter_(node->devices())
{
}
ParasiticDeviceIterator *
ConcreteParasitics::deviceIterator(ParasiticNode *node) const
{
ConcreteParasiticNode *cnode = static_cast<ConcreteParasiticNode*>(node);
return new ConcreteParasiticDeviceIterator(cnode);
return new ConcreteParasiticDeviceSeqIterator(cnode->devices());
}
const char *
@ -2031,4 +2076,34 @@ ConcreteParasitics::estimatePiElmore(const Pin *drvr_pin,
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

View File

@ -162,6 +162,8 @@ public:
virtual void makeResistor(const char *name, ParasiticNode *node1,
ParasiticNode *node2,
float res, const ParasiticAnalysisPt *ap);
virtual ParasiticDeviceIterator *deviceIterator(Parasitic *parasitic);
virtual ParasiticNodeIterator *nodeIterator(Parasitic *parasitic);
virtual const char *name(const ParasiticNode *node);
virtual const Pin *connectionPin(const ParasiticNode *node) const;

View File

@ -25,6 +25,7 @@ class ConcretePoleResidue;
class ConcreteParasiticDevice;
class ConcreteParasiticPinNode;
class ConcreteParasiticSubNode;
class ConcreteParasiticNode;
typedef Map<const Pin*, float> ConcreteElmoreLoadMap;
typedef ConcreteElmoreLoadMap::Iterator ConcretePiElmoreLoadIterator;
@ -41,6 +42,7 @@ typedef Map<const Pin*,
ConcreteParasiticPinNode*> ConcreteParasiticPinNodeMap;
typedef Vector<ConcreteParasiticDevice*> ConcreteParasiticDeviceSeq;
typedef Set<ConcreteParasiticDevice*> ConcreteParasiticDeviceSet;
typedef Vector<ConcreteParasiticNode*> ConcreteParasiticNodeSeq;
// Empty base class definitions so casts are not required on returned
// objects.
@ -78,6 +80,8 @@ public:
virtual void setPoleResidue(const Pin *load_pin,
ComplexFloatSeq *poles,
ComplexFloatSeq *residues);
virtual ParasiticDeviceIterator *deviceIterator();
virtual ParasiticNodeIterator *nodeIterator();
};
class ConcreteElmore
@ -268,7 +272,8 @@ protected:
class ConcreteParasiticSubNode : public ConcreteParasiticNode
{
public:
ConcreteParasiticSubNode(Net *net, int id);
ConcreteParasiticSubNode(Net *net,
int id);
virtual const char *name(const Network *network) const;
private:
@ -391,10 +396,22 @@ public:
private:
};
class ConcreteParasiticDeviceIterator : public ParasiticDeviceIterator
class ConcreteParasiticDeviceSetIterator : public ParasiticDeviceIterator
{
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(); }
ParasiticDevice *next() { return iter_.next(); }
@ -402,6 +419,18 @@ private:
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,
public ConcreteParasitic
{
@ -418,7 +447,10 @@ public:
ConcreteParasiticPinNodeMap *pinNodes() { return &pin_nodes_; }
ConcreteParasiticSubNodeMap *subNodes() { return &sub_nodes_; }
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:
void deleteNodes();

View File

@ -126,6 +126,8 @@ public:
makeParasiticNetwork(Net *net,
bool pin_cap_included,
const ParasiticAnalysisPt *ap);
virtual ParasiticDeviceIterator *deviceIterator(Parasitic *) { return NULL; }
virtual ParasiticNodeIterator *nodeIterator(Parasitic *) { return NULL; }
virtual bool includesPinCaps(Parasitic *parasitic) const;
virtual void deleteParasiticNetwork(const Net *net,
const ParasiticAnalysisPt *ap);

View File

@ -33,6 +33,7 @@ class Corner;
typedef std::complex<float> ComplexFloat;
typedef Vector<ComplexFloat> ComplexFloatSeq;
typedef Iterator<ParasiticDevice*> ParasiticDeviceIterator;
typedef Iterator<ParasiticNode*> ParasiticNodeIterator;
// Parasitics API.
// All parasitic parameters can have multiple values, each corresponding
@ -171,7 +172,7 @@ public:
ComplexFloat &residue) const=0;
////////////////////////////////////////////////////////////////
// Parasitic Network (detailed parasitics, or DSPF).
// Parasitic Network (detailed parasitics).
// This api assumes that parasitic networks are not rise/fall
// dependent because they do not include pin capacitances.
virtual bool isParasiticNetwork(Parasitic *parasitic) const = 0;
@ -184,6 +185,8 @@ public:
virtual Parasitic *makeParasiticNetwork(Net *net,
bool pin_cap_included,
const ParasiticAnalysisPt *ap) = 0;
virtual ParasiticDeviceIterator *deviceIterator(Parasitic *parasitic) = 0;
virtual ParasiticNodeIterator *nodeIterator(Parasitic *parasitic) = 0;
// Delete parasitic network if it exists.
virtual void deleteParasiticNetwork(const Net *net,
const ParasiticAnalysisPt *ap) = 0;

View File

@ -75,9 +75,9 @@ PathEnd::pathEarlyLate(const StaState *sta) const
}
const EarlyLate *
PathEnd::clkEarlyLate(const StaState *) const
PathEnd::clkEarlyLate(const StaState *sta) const
{
return NULL;
return checkRole(sta)->tgtClkEarlyLate();
}
const TransRiseFall *
@ -552,15 +552,6 @@ PathEndClkConstrained::setPath(PathEnumed *path,
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
PathEndClkConstrained::sourceClkOffset(const StaState *sta) const
{

View File

@ -239,7 +239,6 @@ private:
class PathEndClkConstrained : public PathEnd
{
public:
virtual const EarlyLate *clkEarlyLate(const StaState *sta) const;
virtual float sourceClkOffset(const StaState *sta) const;
virtual Delay sourceClkLatency(const StaState *sta) const;
virtual Delay sourceClkInsertionDelay(const StaState *sta) const;

View File

@ -747,7 +747,7 @@ WritePathSpice::writeStageVoltageSources(Stage stage,
}
}
}
else
else if (drvr_port->function())
sensitizationValues(inst, drvr_port->function(), input_port, port_values);
int volt_index = 1;
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
WritePathSpice::writeStageParasitics(Stage stage)
{
@ -1052,14 +1003,9 @@ WritePathSpice::writeStageParasitics(Stage stage)
net ? network_->pathName(net) : network_->pathName(drvr_pin);
initNodeMap(net_name);
streamPrint(spice_stream_, "* Net %s\n", net_name);
auto node = parasitics_->findNode(parasitic, drvr_pin);
ParasiticNodeNameLess node_name_less(parasitics_);
ParasiticNodeSet nodes(node_name_less);
ParasiticDeviceSet devices;
findParasiticDevicesNodes(node, parasitics_, nodes, devices);
ParasiticDeviceSet::Iterator device_iter(devices);
while (device_iter.hasNext()) {
auto device = device_iter.next();
ParasiticDeviceIterator *device_iter = parasitics_->deviceIterator(parasitic);
while (device_iter->hasNext()) {
auto device = device_iter->next();
auto resistance = parasitics_->value(device, parasitic_ap);
if (parasitics_->isResistor(device)) {
ParasiticNode *node1 = parasitics_->node1(device);
@ -1082,10 +1028,12 @@ WritePathSpice::writeStageParasitics(Stage stage)
cap_index++;
}
}
ParasiticNodeSet::Iterator node_iter(nodes);
while (node_iter.hasNext()) {
auto node = node_iter.next();
delete device_iter;
ParasiticNodeIterator *node_iter = parasitics_->nodeIterator(parasitic);
while (node_iter->hasNext()) {
auto node = node_iter->next();
auto cap = parasitics_->nodeGndCap(node, parasitic_ap);
// Spice has a cow over zero value caps.
if (cap > 0.0) {
streamPrint(spice_stream_, "C%d %s 0 %.3e\n",
cap_index,
@ -1094,6 +1042,7 @@ WritePathSpice::writeStageParasitics(Stage stage)
cap_index++;
}
}
delete node_iter;
}
else {
streamPrint(spice_stream_, "* No parasitics found for this net.\n");

View File

@ -1932,7 +1932,7 @@ proc write_path_spice { args } {
flags {}
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] } {
sta_error "Directory $spice_dir not found.\n"
}
@ -1947,7 +1947,7 @@ proc write_path_spice { args } {
}
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] } {
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)] } {
set model_file $keys(-model_file)
set model_file [file_expand_tilde $keys(-model_file)]
if { ![file readable $model_file] } {
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.
}