mirror of https://github.com/KLayout/klayout.git
861 lines
22 KiB
C++
861 lines
22 KiB
C++
|
|
/*
|
|
|
|
KLayout Layout Viewer
|
|
Copyright (C) 2006-2024 Matthias Koefferlein
|
|
|
|
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 2 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, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
#ifndef _HDR_dbCircuit
|
|
#define _HDR_dbCircuit
|
|
|
|
#include "dbCommon.h"
|
|
#include "dbTypes.h"
|
|
#include "dbNet.h"
|
|
#include "dbDevice.h"
|
|
#include "dbPin.h"
|
|
#include "dbSubCircuit.h"
|
|
#include "dbNetlistUtils.h"
|
|
#include "dbPolygon.h"
|
|
#include "dbMemStatistics.h"
|
|
|
|
#include "tlObject.h"
|
|
#include "tlObjectCollection.h"
|
|
#include "tlVector.h"
|
|
#include "gsiObject.h"
|
|
|
|
namespace db
|
|
{
|
|
|
|
class Netlist;
|
|
class Layout;
|
|
|
|
/**
|
|
* @brief An iterator wrapper for the child and parent circuit iterator
|
|
*/
|
|
template <class Iter, class Value>
|
|
struct DB_PUBLIC_TEMPLATE dereferencing_iterator
|
|
: public Iter
|
|
{
|
|
public:
|
|
typedef Value *pointer;
|
|
typedef Value &reference;
|
|
typedef typename Iter::difference_type difference_type;
|
|
|
|
dereferencing_iterator () { }
|
|
dereferencing_iterator (const dereferencing_iterator &d) : Iter (d) { }
|
|
dereferencing_iterator (const Iter &d) : Iter (d) { }
|
|
dereferencing_iterator &operator= (const dereferencing_iterator &d)
|
|
{
|
|
Iter::operator= (d);
|
|
return *this;
|
|
}
|
|
|
|
dereferencing_iterator operator+ (difference_type offset) const
|
|
{
|
|
return dereferencing_iterator (Iter::operator+ (offset));
|
|
}
|
|
|
|
dereferencing_iterator &operator+= (difference_type offset)
|
|
{
|
|
Iter::operator+= (offset);
|
|
return *this;
|
|
}
|
|
|
|
pointer operator-> () const { return Iter::operator* (); }
|
|
reference operator* () const { return *Iter::operator* (); }
|
|
};
|
|
|
|
/**
|
|
* @brief A circuit
|
|
*
|
|
* A circuit is a list of nets, of subcircuit references and actual
|
|
* devices.
|
|
*/
|
|
class DB_PUBLIC Circuit
|
|
: public db::NetlistObject, public gsi::ObjectBase
|
|
{
|
|
public:
|
|
typedef std::list<Pin> pin_list;
|
|
typedef pin_list::const_iterator const_pin_iterator;
|
|
typedef pin_list::iterator pin_iterator;
|
|
typedef tl::shared_collection<Device> device_list;
|
|
typedef device_list::const_iterator const_device_iterator;
|
|
typedef device_list::iterator device_iterator;
|
|
typedef tl::shared_collection<Net> net_list;
|
|
typedef net_list::const_iterator const_net_iterator;
|
|
typedef net_list::iterator net_iterator;
|
|
typedef tl::shared_collection<SubCircuit> subcircuit_list;
|
|
typedef subcircuit_list::const_iterator const_subcircuit_iterator;
|
|
typedef subcircuit_list::iterator subcircuit_iterator;
|
|
typedef tl::weak_collection<SubCircuit>::const_iterator const_refs_iterator;
|
|
typedef tl::weak_collection<SubCircuit>::iterator refs_iterator;
|
|
typedef dereferencing_iterator<tl::vector<Circuit *>::const_iterator, Circuit> child_circuit_iterator;
|
|
typedef dereferencing_iterator<tl::vector<const Circuit *>::const_iterator, const Circuit> const_child_circuit_iterator;
|
|
typedef dereferencing_iterator<tl::vector<Circuit *>::const_iterator, Circuit> parent_circuit_iterator;
|
|
typedef dereferencing_iterator<tl::vector<const Circuit *>::const_iterator, const Circuit> const_parent_circuit_iterator;
|
|
|
|
/**
|
|
* @brief Constructor
|
|
*
|
|
* Creates an empty circuit.
|
|
*/
|
|
Circuit ();
|
|
|
|
/**
|
|
* @brief Constructor
|
|
*
|
|
* Creates a circuit corresponding to a layout cell
|
|
*/
|
|
Circuit (const db::Layout &layout, db::cell_index_type ci);
|
|
|
|
/**
|
|
* @brief Copy constructor
|
|
*/
|
|
Circuit (const Circuit &other);
|
|
|
|
/**
|
|
* @brief Destructor
|
|
*/
|
|
~Circuit ();
|
|
|
|
/**
|
|
* @brief Assignment
|
|
*/
|
|
Circuit &operator= (const Circuit &other);
|
|
|
|
/**
|
|
* @brief Gets the netlist the circuit lives in
|
|
* This pointer is 0 if the circuit is not part of a netlist.
|
|
*/
|
|
Netlist *netlist ()
|
|
{
|
|
return mp_netlist;
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the netlist the circuit lives in (const version)
|
|
* This pointer is 0 if the circuit is not part of a netlist.
|
|
*/
|
|
const Netlist *netlist () const
|
|
{
|
|
return mp_netlist;
|
|
}
|
|
|
|
/**
|
|
* @brief Clears the circuit
|
|
*/
|
|
void clear ();
|
|
|
|
/**
|
|
* @brief Sets the name of the circuit
|
|
*/
|
|
void set_name (const std::string &name);
|
|
|
|
/**
|
|
* @brief Gets the name of the circuit
|
|
*/
|
|
const std::string &name () const
|
|
{
|
|
return m_name;
|
|
}
|
|
|
|
/**
|
|
* @brief Sets the boundary
|
|
*/
|
|
void set_boundary (const db::DPolygon &boundary);
|
|
|
|
/**
|
|
* @brief Gets the boundary
|
|
*/
|
|
const db::DPolygon &boundary () const
|
|
{
|
|
return m_boundary;
|
|
}
|
|
|
|
/**
|
|
* @brief Sets or resets the "don't purge" flag
|
|
* This flag will prevent "purge" from deleting this circuit. It is set by "blank".
|
|
*/
|
|
void set_dont_purge (bool dp);
|
|
|
|
/**
|
|
* @brief Gets or resets the "don't purge" flag
|
|
*/
|
|
bool dont_purge () const
|
|
{
|
|
return m_dont_purge;
|
|
}
|
|
|
|
/**
|
|
* @brief The index of the circuit in the netlist
|
|
* CAUTION: this attribute is used for internal purposes and may not be valid always.
|
|
*/
|
|
size_t index () const
|
|
{
|
|
return m_index;
|
|
}
|
|
|
|
/**
|
|
* @brief Sets the layout cell reference for this circuit
|
|
*
|
|
* The layout cell reference links a circuit to a layout cell.
|
|
*/
|
|
void set_cell_index (const db::cell_index_type ci);
|
|
|
|
/**
|
|
* @brief Gets the layout cell index
|
|
*/
|
|
db::cell_index_type cell_index () const
|
|
{
|
|
return m_cell_index;
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the references to this circuit (begin, non-const version)
|
|
* This iterator will deliver all subcircuits referencing this circuit
|
|
*/
|
|
refs_iterator begin_refs ()
|
|
{
|
|
return m_refs.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the references to this circuit (end, non-const version)
|
|
* This iterator will deliver all subcircuits referencing this circuit
|
|
*/
|
|
refs_iterator end_refs ()
|
|
{
|
|
return m_refs.end ();
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the references to this circuit (begin, const version)
|
|
* This iterator will deliver all subcircuits referencing this circuit
|
|
*/
|
|
const_refs_iterator begin_refs () const
|
|
{
|
|
return m_refs.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the references to this circuit (end, const version)
|
|
* This iterator will deliver all subcircuits referencing this circuit
|
|
*/
|
|
const_refs_iterator end_refs () const
|
|
{
|
|
return m_refs.end ();
|
|
}
|
|
|
|
/**
|
|
* @brief Returns a value indicating whether the circuit has references
|
|
*/
|
|
bool has_refs () const
|
|
{
|
|
return begin_refs () != end_refs ();
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the child circuits iterator (begin)
|
|
* The child circuits are the circuits referenced by all subcircuits
|
|
* in the circuit.
|
|
*/
|
|
child_circuit_iterator begin_children ();
|
|
|
|
/**
|
|
* @brief Gets the child circuits iterator (end)
|
|
*/
|
|
child_circuit_iterator end_children ();
|
|
|
|
/**
|
|
* @brief Gets the child circuits iterator (begin, const version)
|
|
* The child circuits are the circuits referenced by all subcircuits
|
|
* in the circuit.
|
|
*/
|
|
const_child_circuit_iterator begin_children () const;
|
|
|
|
/**
|
|
* @brief Gets the child circuits iterator (end, const version)
|
|
*/
|
|
const_child_circuit_iterator end_children () const;
|
|
|
|
/**
|
|
* @brief Gets the parent circuits iterator (begin)
|
|
* The parents circuits are the circuits referencing this circuit via subcircuits.
|
|
*/
|
|
parent_circuit_iterator begin_parents ();
|
|
|
|
/**
|
|
* @brief Gets the parent circuits iterator (end)
|
|
*/
|
|
parent_circuit_iterator end_parents ();
|
|
|
|
/**
|
|
* @brief Gets the parent circuits iterator (begin, const version)
|
|
* The parents circuits are the circuits referencing this circuit via subcircuits.
|
|
*/
|
|
const_parent_circuit_iterator begin_parents () const;
|
|
|
|
/**
|
|
* @brief Gets the parent circuits iterator (end, const version)
|
|
*/
|
|
const_parent_circuit_iterator end_parents () const;
|
|
|
|
/**
|
|
* @brief Clears the pins
|
|
*/
|
|
void clear_pins ();
|
|
|
|
/**
|
|
* @brief Adds a pin to this circuit
|
|
*/
|
|
Pin &add_pin (const std::string &name);
|
|
|
|
/**
|
|
* @brief Adds a pin to this circuit
|
|
* This version uses the given pin as the template.
|
|
*/
|
|
Pin &add_pin (const Pin &pin);
|
|
|
|
/**
|
|
* @brief Removes the pin with the given ID
|
|
*/
|
|
void remove_pin (size_t id);
|
|
|
|
/**
|
|
* @brief Begin iterator for the pins of the circuit (non-const version)
|
|
*/
|
|
pin_iterator begin_pins ()
|
|
{
|
|
return m_pins.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief End iterator for the pins of the circuit (non-const version)
|
|
*/
|
|
pin_iterator end_pins ()
|
|
{
|
|
return m_pins.end ();
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the pin count
|
|
*/
|
|
size_t pin_count () const
|
|
{
|
|
return m_pins.size ();
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the pin by ID (the ID is basically the index)
|
|
*/
|
|
const Pin *pin_by_id (size_t id) const;
|
|
|
|
/**
|
|
* @brief Gets the pin by ID (the ID is basically the index) - non-const version
|
|
*/
|
|
Pin *pin_by_id (size_t id)
|
|
{
|
|
return const_cast<Pin *> (((const db::Circuit *) this)->pin_by_id (id));
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the pin by name
|
|
*
|
|
* If there is no pin with that name, null is returned.
|
|
* NOTE: this is a linear search, so it's performance may not be good for many pins.
|
|
*/
|
|
const Pin *pin_by_name (const std::string &name) const;
|
|
|
|
/**
|
|
* @brief Gets the pin by name - non-const version
|
|
*/
|
|
Pin *pin_by_name (const std::string &name)
|
|
{
|
|
return const_cast<Pin *> (((const db::Circuit *) this)->pin_by_name (name));
|
|
}
|
|
|
|
/**
|
|
* @brief Begin iterator for the pins of the circuit (const version)
|
|
*/
|
|
const_pin_iterator begin_pins () const
|
|
{
|
|
return m_pins.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief End iterator for the pins of the circuit (const version)
|
|
*/
|
|
const_pin_iterator end_pins () const
|
|
{
|
|
return m_pins.end ();
|
|
}
|
|
|
|
/**
|
|
* @brief Adds a net to this circuit
|
|
*
|
|
* The circuit takes over ownership of the object.
|
|
*/
|
|
void add_net (Net *net);
|
|
|
|
/**
|
|
* @brief Deletes a net from the circuit
|
|
*/
|
|
void remove_net (Net *net);
|
|
|
|
/**
|
|
* @brief Joins the second net with the first one and removes the second net
|
|
*/
|
|
void join_nets (Net *net, Net *with);
|
|
|
|
/**
|
|
* @brief Gets the number of nets
|
|
*/
|
|
size_t net_count () const
|
|
{
|
|
return m_nets.size ();
|
|
}
|
|
|
|
/**
|
|
* @brief Begin iterator for the nets of the circuit (non-const version)
|
|
*/
|
|
net_iterator begin_nets ()
|
|
{
|
|
return m_nets.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief End iterator for the nets of the circuit (non-const version)
|
|
*/
|
|
net_iterator end_nets ()
|
|
{
|
|
return m_nets.end ();
|
|
}
|
|
|
|
/**
|
|
* @brief Begin iterator for the nets of the circuit (const version)
|
|
*/
|
|
const_net_iterator begin_nets () const
|
|
{
|
|
return m_nets.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief End iterator for the nets of the circuit (const version)
|
|
*/
|
|
const_net_iterator end_nets () const
|
|
{
|
|
return m_nets.end ();
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the net from a given cluster ID (const version)
|
|
*
|
|
* If the cluster ID is not valid, null is returned.
|
|
*/
|
|
const Net *net_by_cluster_id (size_t cluster_id) const
|
|
{
|
|
return (const_cast<Circuit *> (this)->net_by_cluster_id (cluster_id));
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the net from a given cluster ID (non-const version)
|
|
*
|
|
* If the cluster ID is not valid, null is returned.
|
|
*/
|
|
Net *net_by_cluster_id (size_t cluster_id)
|
|
{
|
|
return m_net_by_cluster_id.object_by (cluster_id);
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the net from a given name (const version)
|
|
*
|
|
* If the name is not valid, null is returned.
|
|
*/
|
|
const Net *net_by_name (const std::string &name) const
|
|
{
|
|
return (const_cast<Circuit *> (this)->net_by_name (name));
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the net from a given name (non-const version)
|
|
*
|
|
* If the name is not valid, null is returned.
|
|
*/
|
|
Net *net_by_name (const std::string &name);
|
|
|
|
/**
|
|
* @brief Adds a device to this circuit
|
|
*
|
|
* The circuit takes over ownership of the object.
|
|
*/
|
|
void add_device (Device *device);
|
|
|
|
/**
|
|
* @brief Deletes a device from the circuit
|
|
*/
|
|
void remove_device (Device *device);
|
|
|
|
/**
|
|
* @brief Gets the number of devices
|
|
*/
|
|
size_t device_count () const
|
|
{
|
|
return m_devices.size ();
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the device from a given ID (const version)
|
|
*
|
|
* If the ID is not valid, null is returned.
|
|
*/
|
|
const Device *device_by_id (size_t id) const
|
|
{
|
|
return (const_cast<Circuit *> (this)->device_by_id (id));
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the device from a given ID (non-const version)
|
|
*
|
|
* If the ID is not valid, null is returned.
|
|
*/
|
|
Device *device_by_id (size_t id)
|
|
{
|
|
return m_device_by_id.object_by (id);
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the device from a given name (const version)
|
|
*
|
|
* If the name is not valid, null is returned.
|
|
*/
|
|
const Device *device_by_name (const std::string &name) const
|
|
{
|
|
return (const_cast<Circuit *> (this)->device_by_name (name));
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the device from a given name (non-const version)
|
|
*
|
|
* If the name is not valid, null is returned.
|
|
*/
|
|
Device *device_by_name (const std::string &name);
|
|
|
|
/**
|
|
* @brief Begin iterator for the devices of the circuit (non-const version)
|
|
*/
|
|
device_iterator begin_devices ()
|
|
{
|
|
return m_devices.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief End iterator for the devices of the circuit (non-const version)
|
|
*/
|
|
device_iterator end_devices ()
|
|
{
|
|
return m_devices.end ();
|
|
}
|
|
|
|
/**
|
|
* @brief Begin iterator for the devices of the circuit (const version)
|
|
*/
|
|
const_device_iterator begin_devices () const
|
|
{
|
|
return m_devices.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief End iterator for the devices of the circuit (const version)
|
|
*/
|
|
const_device_iterator end_devices () const
|
|
{
|
|
return m_devices.end ();
|
|
}
|
|
|
|
/**
|
|
* @brief Adds a subcircuit to this circuit
|
|
*
|
|
* The circuit takes over ownership of the object.
|
|
*/
|
|
void add_subcircuit (SubCircuit *subcircuit);
|
|
|
|
/**
|
|
* @brief Deletes a subcircuit from the circuit
|
|
*/
|
|
void remove_subcircuit (SubCircuit *subcircuit);
|
|
|
|
/**
|
|
* @brief Gets the number of subcircuits
|
|
*/
|
|
size_t subcircuit_count () const
|
|
{
|
|
return m_subcircuits.size ();
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the subcircuit from a given ID (const version)
|
|
*
|
|
* If the ID is not valid, null is returned.
|
|
*/
|
|
const SubCircuit *subcircuit_by_id (size_t id) const
|
|
{
|
|
return (const_cast<Circuit *> (this)->subcircuit_by_id (id));
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the subcircuit from a given ID (non-const version)
|
|
*
|
|
* If the ID is not valid, null is returned.
|
|
*/
|
|
SubCircuit *subcircuit_by_id (size_t id)
|
|
{
|
|
return m_subcircuit_by_id.object_by (id);
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the subcircuit from a given name (const version)
|
|
*
|
|
* If the name is not valid, null is returned.
|
|
*/
|
|
const SubCircuit *subcircuit_by_name (const std::string &name) const
|
|
{
|
|
return (const_cast<Circuit *> (this)->subcircuit_by_name (name));
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the subcircuit from a given name (non-const version)
|
|
*
|
|
* If the name is not valid, null is returned.
|
|
*/
|
|
SubCircuit *subcircuit_by_name (const std::string &name);
|
|
|
|
/**
|
|
* @brief Begin iterator for the subcircuits of the circuit (non-const version)
|
|
*/
|
|
subcircuit_iterator begin_subcircuits ()
|
|
{
|
|
return m_subcircuits.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief End iterator for the subcircuits of the circuit (non-const version)
|
|
*/
|
|
subcircuit_iterator end_subcircuits ()
|
|
{
|
|
return m_subcircuits.end ();
|
|
}
|
|
|
|
/**
|
|
* @brief Begin iterator for the subcircuits of the circuit (const version)
|
|
*/
|
|
const_subcircuit_iterator begin_subcircuits () const
|
|
{
|
|
return m_subcircuits.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief End iterator for the subcircuits of the circuit (const version)
|
|
*/
|
|
const_subcircuit_iterator end_subcircuits () const
|
|
{
|
|
return m_subcircuits.end ();
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the connected net for a pin with the given id
|
|
*
|
|
* Returns 0 if the pin is not connected to a net.
|
|
*/
|
|
const Net *net_for_pin (size_t pin_id) const;
|
|
|
|
/**
|
|
* @brief Gets the connected net for a pin with the given id (non-const version)
|
|
*
|
|
* Returns 0 if the pin is not connected to a net.
|
|
*/
|
|
Net *net_for_pin (size_t pin_id)
|
|
{
|
|
return const_cast<Net *> (((const Circuit *) this)->net_for_pin (pin_id));
|
|
}
|
|
|
|
/**
|
|
* @brief Connects the given pin to the given net
|
|
* If the net is 0 the pin is disconnected.
|
|
* If non-null, a NetPinRef object will be inserted into the
|
|
* net and connected with the given pin.
|
|
*/
|
|
void connect_pin (size_t pin_id, Net *net);
|
|
|
|
/**
|
|
* @brief Adds a pin to the given net
|
|
* The pin will be added to the net. If there is already a pin
|
|
* on the net, the existing and new pin will be joined.
|
|
* This usually implies that nets further up in the hierarchy
|
|
* are joined too.
|
|
*/
|
|
void join_pin_with_net (size_t pin_id, Net *net);
|
|
|
|
/**
|
|
* @brief Renames the pin with the given ID
|
|
*/
|
|
void rename_pin (size_t pin_id, const std::string &name);
|
|
|
|
/**
|
|
* @brief Purge unused nets
|
|
*
|
|
* This method will purge all nets which return "is_passive".
|
|
* Pins on these nets will also be removed.
|
|
*/
|
|
void purge_nets ();
|
|
|
|
/**
|
|
* @brief Purge unused nets but
|
|
*
|
|
* This method will purge all nets which return "is_passive".
|
|
* Pins on these nets will be kept but their net will be 0.
|
|
*/
|
|
void purge_nets_keep_pins ();
|
|
|
|
/**
|
|
* @brief Purges invalid devices
|
|
*
|
|
* This method will purge all invalid devices, i.e. those
|
|
* whose terminals are all connected to the same net.
|
|
*/
|
|
void purge_devices ();
|
|
|
|
/**
|
|
* @brief Combine devices
|
|
*
|
|
* This method will combine devices that can be combined according
|
|
* to their device classes "combine_devices" method.
|
|
*/
|
|
void combine_devices ();
|
|
|
|
/**
|
|
* @brief Flattens the given subcircuit
|
|
*
|
|
* The subcircuit is resolved into the parent circuit and finally removed.
|
|
* Net, device and subcircuit names are decorated with the subcircuit's name
|
|
* if required.
|
|
*/
|
|
void flatten_subcircuit (SubCircuit *subcircuit);
|
|
|
|
/**
|
|
* @brief Blanks out the circuit
|
|
*
|
|
* This will remove all innards of the circuit (nets, devices, subcircuits)
|
|
* and circuits which will itself are not longer be called after this.
|
|
* This operation will eventually leave a blackbox model of the circuit
|
|
* containing only pins.
|
|
*/
|
|
void blank ();
|
|
|
|
/**
|
|
* @brief Gets a value indicating whether the circuit is empty
|
|
*/
|
|
bool is_empty () const;
|
|
|
|
/**
|
|
* @brief Generate memory statistics
|
|
*/
|
|
void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self = false, void *parent = 0) const
|
|
{
|
|
if (! no_self) {
|
|
stat->add (typeid (*this), (void *) this, sizeof (*this), sizeof (*this), parent, purpose, cat);
|
|
}
|
|
|
|
db::mem_stat (stat, purpose, cat, m_name, true, (void *) this);
|
|
db::mem_stat (stat, purpose, cat, m_boundary, true, (void *) this);
|
|
db::mem_stat (stat, purpose, cat, m_nets, true, (void *) this);
|
|
db::mem_stat (stat, purpose, cat, m_pins, true, (void *) this);
|
|
db::mem_stat (stat, purpose, cat, m_pin_by_id, true, (void *) this);
|
|
db::mem_stat (stat, purpose, cat, m_devices, true, (void *) this);
|
|
db::mem_stat (stat, purpose, cat, m_subcircuits, true, (void *) this);
|
|
db::mem_stat (stat, purpose, cat, m_pin_refs, true, (void *) this);
|
|
db::mem_stat (stat, purpose, cat, m_device_by_id, true, (void *) this);
|
|
db::mem_stat (stat, purpose, cat, m_subcircuit_by_id, true, (void *) this);
|
|
db::mem_stat (stat, purpose, cat, m_net_by_cluster_id, true, (void *) this);
|
|
db::mem_stat (stat, purpose, cat, m_device_by_name, true, (void *) this);
|
|
db::mem_stat (stat, purpose, cat, m_subcircuit_by_name, true, (void *) this);
|
|
db::mem_stat (stat, purpose, cat, m_net_by_name, true, (void *) this);
|
|
db::mem_stat (stat, purpose, cat, m_refs, true, (void *) this);
|
|
}
|
|
|
|
private:
|
|
friend class Netlist;
|
|
friend class Net;
|
|
friend class SubCircuit;
|
|
friend class Device;
|
|
|
|
std::string m_name;
|
|
db::DPolygon m_boundary;
|
|
bool m_dont_purge;
|
|
db::cell_index_type m_cell_index;
|
|
net_list m_nets;
|
|
pin_list m_pins;
|
|
std::vector<pin_list::iterator> m_pin_by_id;
|
|
device_list m_devices;
|
|
subcircuit_list m_subcircuits;
|
|
Netlist *mp_netlist;
|
|
std::vector<Net::pin_iterator> m_pin_refs;
|
|
object_by_attr<Circuit, Circuit::device_iterator, id_attribute<Device> > m_device_by_id;
|
|
object_by_attr<Circuit, Circuit::subcircuit_iterator, id_attribute<SubCircuit> > m_subcircuit_by_id;
|
|
object_by_attr<Circuit, Circuit::net_iterator, cluster_id_attribute<Net> > m_net_by_cluster_id;
|
|
object_by_attr<Circuit, Circuit::device_iterator, name_attribute<Device> > m_device_by_name;
|
|
object_by_attr<Circuit, Circuit::subcircuit_iterator, name_attribute<SubCircuit> > m_subcircuit_by_name;
|
|
object_by_attr<Circuit, Circuit::net_iterator, name_attribute<Net> > m_net_by_name;
|
|
tl::weak_collection<SubCircuit> m_refs;
|
|
size_t m_index;
|
|
|
|
void set_index (size_t index)
|
|
{
|
|
m_index = index;
|
|
}
|
|
|
|
void set_pin_ref_for_pin (size_t ppin_id, Net::pin_iterator iter);
|
|
|
|
void register_ref (SubCircuit *sc);
|
|
void unregister_ref (SubCircuit *sc);
|
|
|
|
void translate_circuits (const std::map<const Circuit *, Circuit *> &map);
|
|
void translate_device_classes (const std::map<const DeviceClass *, DeviceClass *> &map);
|
|
void translate_device_abstracts (const std::map<const DeviceAbstract *, DeviceAbstract *> &map);
|
|
void set_netlist (Netlist *netlist);
|
|
bool combine_parallel_devices (const db::DeviceClass &cls);
|
|
bool combine_serial_devices (const db::DeviceClass &cls);
|
|
void do_purge_nets (bool keep_pins);
|
|
void join_pins (size_t pin_id, size_t with);
|
|
void devices_changed ();
|
|
void subcircuits_changed ();
|
|
void nets_changed ();
|
|
};
|
|
|
|
/**
|
|
* @brief Memory statistics for Circuit
|
|
*/
|
|
inline void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, const Circuit &x, bool no_self, void *parent)
|
|
{
|
|
x.mem_stat (stat, purpose, cat, no_self, parent);
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|