OpenSTA/parasitics/ConcreteParasiticsPvt.hh

447 lines
13 KiB
C++

// OpenSTA, Static Timing Analyzer
// Copyright (c) 2020, Parallax Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#pragma once
#include "Parasitics.hh"
namespace sta {
class ConcretePoleResidue;
class ConcreteParasiticDevice;
class ConcreteParasiticPinNode;
class ConcreteParasiticSubNode;
class ConcreteParasiticNode;
typedef Map<const Pin*, float> ConcreteElmoreLoadMap;
typedef ConcreteElmoreLoadMap::Iterator ConcretePiElmoreLoadIterator;
typedef Map<const Pin*, ConcretePoleResidue*> ConcretePoleResidueMap;
typedef std::pair<const Net*, int> NetId;
struct NetIdLess
{
bool operator()(const NetId *net_id1,
const NetId *net_id2) const;
};
typedef Map<NetId*, ConcreteParasiticSubNode*,
NetIdLess > ConcreteParasiticSubNodeMap;
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.
class Parasitic {};
class ParasiticNode {};
class ParasiticDevice {};
class ParasiticNetwork {};
// Base class for parasitics.
class ConcreteParasitic : public Parasitic
{
public:
virtual ~ConcreteParasitic();
virtual float capacitance() const = 0;
virtual bool isPiElmore() const;
virtual bool isPiModel() const;
virtual bool isPiPoleResidue() const;
virtual bool isPoleResidue() const;
virtual bool isParasiticNetwork() const;
virtual void piModel(float &c2,
float &rpi,
float &c1) const;
virtual void setPiModel(float c2,
float rpi,
float c1);
virtual bool isReducedParasiticNetwork() const;
virtual void setIsReduced(bool reduced);
virtual void findElmore(const Pin *load_pin,
float &elmore,
bool &exists) const;
virtual void setElmore(const Pin *load_pin,
float elmore);
virtual Parasitic *findPoleResidue(const Pin *load_pin) const;
virtual void setPoleResidue(const Pin *load_pin,
ComplexFloatSeq *poles,
ComplexFloatSeq *residues);
virtual ParasiticDeviceIterator *deviceIterator();
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
{
public:
ConcretePi(float c2,
float rpi,
float c1);
float capacitance() const;
void piModel(float &c2,
float &rpi,
float &c1) const;
void setPiModel(float c2,
float rpi,
float c1);
bool isReducedParasiticNetwork() const { return is_reduced_; }
void setIsReduced(bool reduced);
protected:
float c2_;
float rpi_;
float c1_;
bool is_reduced_;
};
// 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 bool isPiElmore() const { return true; }
virtual bool isPiModel() const { return true; }
virtual float capacitance() const;
virtual void piModel(float &c2, float &rpi, float &c1) const;
virtual void setPiModel(float c2, float rpi, float c1);
virtual bool isReducedParasiticNetwork() const;
virtual void setIsReduced(bool reduced);
virtual void findElmore(const Pin *load_pin, float &elmore,
bool &exists) const;
virtual void setElmore(const Pin *load_pin, float elmore);
};
// PiElmore from wireload model estimate.
class ConcretePiElmoreEstimated : public ConcretePi,
public ConcreteParasitic
{
public:
ConcretePiElmoreEstimated(float c2,
float rpi,
float c1,
float elmore_res,
float elmore_cap,
bool elmore_use_load_cap,
const RiseFall *rf,
const OperatingConditions *op_cond,
const Corner *corner,
const MinMax *min_max,
Sdc *sdc);
virtual float capacitance() const;
virtual bool isPiElmore() const { return true; }
virtual bool isPiModel() const { return true; }
virtual void piModel(float &c2, float &rpi, float &c1) const;
virtual void findElmore(const Pin *load_pin, float &elmore,
bool &exists) const;
virtual void setElmore(const Pin *load_pin, float elmore);
private:
float elmore_res_;
float elmore_cap_;
bool elmore_use_load_cap_;
const RiseFall *rf_;
const OperatingConditions *op_cond_;
const Corner *corner_;
const MinMax *min_max_;
Sdc *sdc_;
};
class ConcretePoleResidue : public ConcreteParasitic
{
public:
ConcretePoleResidue(ComplexFloatSeq *poles,
ComplexFloatSeq *residues);
virtual ~ConcretePoleResidue();
virtual bool isPoleResidue() const { return true; }
size_t poleResidueCount() const;
void poleResidue(int index, ComplexFloat &pole, ComplexFloat &residue) const;
void setPoleResidue(ComplexFloatSeq *poles, ComplexFloatSeq *residues);
float capacitance() const { return 0.0; }
using ConcreteParasitic::setPoleResidue;
private:
ComplexFloatSeq *poles_;
ComplexFloatSeq *residues_;
};
// Pi model for a driver pin and the pole/residues to each load.
class ConcretePiPoleResidue : public ConcretePi,
public ConcreteParasitic
{
public:
ConcretePiPoleResidue(float c2,
float rpi,
float c1);
virtual ~ConcretePiPoleResidue();
virtual bool isPiPoleResidue() const { return true; }
virtual bool isPiModel() const { return true; }
virtual float capacitance() const;
virtual void piModel(float &c2,
float &rpi,
float &c1) const;
virtual void setPiModel(float c2,
float rpi,
float c1);
virtual bool isReducedParasiticNetwork() const;
virtual void setIsReduced(bool reduced);
virtual Parasitic *findPoleResidue(const Pin *load_pin) const;
virtual void setPoleResidue(const Pin *load_pin,
ComplexFloatSeq *poles,
ComplexFloatSeq *residues);
void deleteLoad(const Pin *load_pin);
private:
ConcretePoleResidueMap *load_pole_residue_;
};
class ConcreteParasiticNode : public ParasiticNode
{
public:
virtual ~ConcreteParasiticNode() {}
float capacitance() const;
virtual const char *name(const Network *network) const = 0;
virtual bool isPinNode() const { return false; }
ConcreteParasiticDeviceSeq *devices() { return &devices_; }
void incrCapacitance(float cap);
void addDevice(ConcreteParasiticDevice *device);
protected:
ConcreteParasiticNode();
float cap_;
ConcreteParasiticDeviceSeq devices_;
friend class ConcreteParasiticNetwork;
};
class ConcreteParasiticSubNode : public ConcreteParasiticNode
{
public:
ConcreteParasiticSubNode(const Net *net,
int id);
virtual const char *name(const Network *network) const;
private:
const Net *net_;
int id_;
};
class ConcreteParasiticPinNode : public ConcreteParasiticNode
{
public:
ConcreteParasiticPinNode(const Pin *pin);
const Pin *pin() const { return pin_; }
virtual bool isPinNode() const { return true; }
virtual const char *name(const Network *network) const;
private:
const Pin *pin_;
};
class ConcreteParasiticDevice : public ParasiticDevice
{
public:
ConcreteParasiticDevice(const char *name,
ConcreteParasiticNode *node,
float value);
virtual ~ConcreteParasiticDevice();
virtual bool isResistor() const { return false; }
virtual bool isCouplingCap() const { return false; }
const char *name() const { return name_; }
float value() const { return value_; }
ConcreteParasiticNode *node1() const { return node_; }
virtual ConcreteParasiticNode *node2() const = 0;
virtual ParasiticNode *otherNode(ParasiticNode *node) const = 0;
virtual void replaceNode(ConcreteParasiticNode *from_node,
ConcreteParasiticNode *to_node) = 0;
protected:
const char *name_;
ConcreteParasiticNode *node_;
float value_;
friend class ConcreteParasiticNetwork;
};
class ConcreteParasiticResistor : public ConcreteParasiticDevice
{
public:
ConcreteParasiticResistor(const char *name,
ConcreteParasiticNode *node,
ConcreteParasiticNode *other_node,
float res);
virtual bool isResistor() const { return true; }
virtual ConcreteParasiticNode *node2() const { return other_node_; }
virtual ParasiticNode *otherNode(ParasiticNode *node) const;
virtual void replaceNode(ConcreteParasiticNode *from_node,
ConcreteParasiticNode *to_node);
private:
ConcreteParasiticNode *other_node_;
};
// Base class for coupling capacitors.
class ConcreteCouplingCap : public ConcreteParasiticDevice
{
public:
ConcreteCouplingCap(const char *name,
ConcreteParasiticNode *node,
float cap);
virtual bool isCouplingCap() const { return true; }
virtual ConcreteParasiticNode *node2() const { return nullptr; }
virtual void replaceNode(ConcreteParasiticNode *from_node,
ConcreteParasiticNode *to_node);
};
class ConcreteCouplingCapInt : public ConcreteCouplingCap
{
public:
ConcreteCouplingCapInt(const char *name,
ConcreteParasiticNode *node,
ConcreteParasiticNode *other_node,
float cap);
virtual bool isCouplingCap() const { return true; }
virtual ConcreteParasiticNode *node2() const { return other_node_; }
virtual ParasiticNode *otherNode(ParasiticNode *node) const;
virtual void replaceNode(ConcreteParasiticNode *from_node,
ConcreteParasiticNode *to_node);
private:
ConcreteParasiticNode *other_node_;
};
class ConcreteCouplingCapExtNode : public ConcreteCouplingCap
{
public:
ConcreteCouplingCapExtNode(const char *name,
ConcreteParasiticNode *node,
Net *other_node_net,
int other_node_id,
float cap);
virtual bool isCouplingCap() const { return true; }
virtual ParasiticNode *otherNode(ParasiticNode *node) const;
virtual void replaceNode(ConcreteParasiticNode *from_node,
ConcreteParasiticNode *to_node);
private:
};
class ConcreteCouplingCapExtPin : public ConcreteCouplingCap
{
public:
ConcreteCouplingCapExtPin(const char *name,
ConcreteParasiticNode *node,
Pin *other_node_pin,
float cap);
virtual bool isCouplingCap() const { return true; }
virtual ParasiticNode *otherNode(ParasiticNode *node) const;
virtual void replaceNode(ConcreteParasiticNode *from_node,
ConcreteParasiticNode *to_node);
private:
};
class ConcreteParasiticDeviceSetIterator : public ParasiticDeviceIterator
{
public:
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(); }
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
{
public:
ConcreteParasiticNetwork(bool includes_pin_caps);
virtual ~ConcreteParasiticNetwork();
virtual bool isParasiticNetwork() const { return true; }
bool includesPinCaps() const { return includes_pin_caps_; }
ConcreteParasiticNode *ensureParasiticNode(const Net *net,
int id);
ConcreteParasiticNode *findNode(const Pin *pin);
ConcreteParasiticNode *ensureParasiticNode(const Pin *pin);
virtual float capacitance() const;
ConcreteParasiticPinNodeMap *pinNodes() { return &pin_nodes_; }
ConcreteParasiticSubNodeMap *subNodes() { return &sub_nodes_; }
void disconnectPin(const Pin *pin,
Net *net);
virtual ParasiticDeviceIterator *deviceIterator();
virtual ParasiticNodeIterator *nodeIterator();
virtual void devices(// Return value.
ConcreteParasiticDeviceSet *devices);
private:
void deleteNodes();
void deleteDevices();
ConcreteParasiticSubNodeMap sub_nodes_;
ConcreteParasiticPinNodeMap pin_nodes_;
unsigned max_node_id_:31;
bool includes_pin_caps_:1;
};
} // namespace