diff --git a/src/db/db/dbNetlist.cc b/src/db/db/dbNetlist.cc index 61b954c79..2f9d43a2c 100644 --- a/src/db/db/dbNetlist.cc +++ b/src/db/db/dbNetlist.cc @@ -29,48 +29,17 @@ namespace db // Pin class implementation Pin::Pin () + : m_id (0) { // .. nothing yet .. } Pin::Pin (Circuit *circuit, const std::string &name) - : m_circuit (circuit), m_name (name) + : m_circuit (circuit), m_name (name), m_id (0) { // .. nothing yet .. } -// -------------------------------------------------------------------------------- -// Port class implementation - -Port::Port () -{ - // .. nothing yet .. -} - -Port::Port (Device *device, port_id_type port_id) - : m_device (device), m_port_id (port_id) -{ - // .. nothing yet .. -} - -const DevicePortDefinition * -Port::port_def () const -{ - const DeviceClass *dc = device_class (); - if (dc && m_port_id < dc->port_definitions ().size ()) { - return &dc->port_definitions ()[m_port_id]; - } else { - return 0; - } -} - -const DeviceClass * -Port::device_class () const -{ - const Device *device = m_device.get (); - return device ? device->device_class () : 0; -} - // -------------------------------------------------------------------------------- // Device class implementation @@ -102,12 +71,30 @@ NetPortRef::NetPortRef () // .. nothing yet .. } -NetPortRef::NetPortRef (Port *port) - : m_port (port) +NetPortRef::NetPortRef (Device *device, size_t port_id) + : m_device (device), m_port_id (port_id) { // .. nothing yet .. } +const DevicePortDefinition * +NetPortRef::port_def () const +{ + const DeviceClass *dc = device_class (); + if (dc && m_port_id < dc->port_definitions ().size ()) { + return &dc->port_definitions ()[m_port_id]; + } else { + return 0; + } +} + +const DeviceClass * +NetPortRef::device_class () const +{ + const Device *device = m_device.get (); + return device ? device->device_class () : 0; +} + // -------------------------------------------------------------------------------- // NetPinRef class implementation @@ -116,18 +103,23 @@ NetPinRef::NetPinRef () // .. nothing yet .. } -NetPinRef::NetPinRef (Pin *pin) - : m_pin (pin) +NetPinRef::NetPinRef (size_t pin_id) + : m_pin_id (pin_id) { // .. nothing yet .. } -NetPinRef::NetPinRef (Pin *pin, SubCircuit *circuit) - : m_pin (pin), m_subcircuit (circuit) +NetPinRef::NetPinRef (size_t pin_id, SubCircuit *circuit) + : m_pin_id (pin_id), m_subcircuit (circuit) { // .. nothing yet .. } +const Pin *NetPinRef::pin () const +{ + return m_subcircuit->circuit ()->pin_by_id (m_pin_id); +} + // -------------------------------------------------------------------------------- // Net class implementation @@ -173,6 +165,24 @@ void Net::add_port (const NetPortRef &port) m_ports.push_back (port); } +void Net::translate_devices (const std::map &map) +{ + for (port_list::iterator i = m_ports.begin (); i != m_ports.end (); ++i) { + std::map::const_iterator m = map.find (i->device ()); + tl_assert (m != map.end ()); + i->set_device (m->second); + } +} + +void Net::translate_subcircuits (const std::map &map) +{ + for (pin_list::iterator i = m_pins.begin (); i != m_pins.end (); ++i) { + std::map::const_iterator m = map.find (i->subcircuit ()); + tl_assert (m != map.end ()); + i->set_subcircuit (m->second); + } +} + // -------------------------------------------------------------------------------- // Circuit class implementation @@ -189,23 +199,47 @@ Circuit::Circuit (const Circuit &other) Circuit &Circuit::operator= (const Circuit &other) { if (this != &other) { + m_name = other.m_name; + for (const_pin_iterator i = other.begin_pins (); i != other.end_pins (); ++i) { - add_pin (new Pin (*i)); + add_pin (*i); } + + std::map device_table; for (const_device_iterator i = other.begin_devices (); i != other.end_devices (); ++i) { - add_device (new Device (*i)); - } - for (const_net_iterator i = other.begin_nets (); i != other.end_nets (); ++i) { - add_net (new Net (*i)); + Device *d = new Device (*i); + device_table [i.operator-> ()] = d; + add_device (d); } + + std::map sc_table; for (const_sub_circuit_iterator i = other.begin_sub_circuits (); i != other.end_sub_circuits (); ++i) { - add_sub_circuit (new SubCircuit (*i)); + SubCircuit *sc = new SubCircuit (*i); + sc_table [i.operator-> ()] = sc; + add_sub_circuit (sc); } + + for (const_net_iterator i = other.begin_nets (); i != other.end_nets (); ++i) { + Net *n = new Net (*i); + n->translate_devices (device_table); + n->translate_subcircuits (sc_table); + add_net (n); + } + } return *this; } +const Pin *Circuit::pin_by_id (size_t id) const +{ + if (id >= m_pins.size ()) { + return 0; + } else { + return &m_pins [id]; + } +} + void Circuit::clear () { m_name.clear (); @@ -225,14 +259,10 @@ void Circuit::set_cell_index (const db::cell_index_type ci) m_cell_index = ci; } -void Circuit::add_pin (Pin *pin) +void Circuit::add_pin (const Pin &pin) { m_pins.push_back (pin); -} - -void Circuit::remove_pin (Pin *pin) -{ - m_pins.erase (pin); + m_pins.back ().set_id (m_pins.size () - 1); } void Circuit::add_net (Net *net) @@ -265,6 +295,24 @@ void Circuit::remove_sub_circuit (SubCircuit *sub_circuit) m_sub_circuits.erase (sub_circuit); } +void Circuit::translate_circuits (const std::map &map) +{ + for (sub_circuit_iterator i = m_sub_circuits.begin (); i != m_sub_circuits.end (); ++i) { + std::map::const_iterator m = map.find (i->circuit ()); + tl_assert (m != map.end ()); + i->set_circuit (m->second); + } +} + +void Circuit::translate_device_classes (const std::map &map) +{ + for (device_iterator i = m_devices.begin (); i != m_devices.end (); ++i) { + std::map::const_iterator m = map.find (i->device_class ()); + tl_assert (m != map.end ()); + i->set_device_class (m->second); + } +} + // -------------------------------------------------------------------------------- // DeviceClass class implementation @@ -341,16 +389,28 @@ Netlist::Netlist (const Netlist &other) Netlist &Netlist::operator= (const Netlist &other) { if (this != &other) { - for (const_circuit_iterator i = other.begin_circuits (); i != other.end_circuits (); ++i) { - add_circuit (new Circuit (*i)); - } + std::map dct; m_device_classes.clear (); for (const_device_class_iterator dc = other.begin_device_classes (); dc != other.end_device_classes (); ++dc) { - m_device_classes.push_back (dc->clone ()); + DeviceClass *dc_new = dc->clone (); + dct [dc.operator-> ()] = dc_new; + m_device_classes.push_back (dc_new); } - } + std::map ct; + for (const_circuit_iterator i = other.begin_circuits (); i != other.end_circuits (); ++i) { + Circuit *ct_new = new Circuit (*i); + ct_new->translate_device_classes (dct); + ct [i.operator-> ()] = ct_new; + add_circuit (ct_new); + } + + for (circuit_iterator i = begin_circuits (); i != end_circuits (); ++i) { + i->translate_circuits (ct); + } + + } return *this; } diff --git a/src/db/db/dbNetlist.h b/src/db/db/dbNetlist.h index 958a91263..84e541049 100644 --- a/src/db/db/dbNetlist.h +++ b/src/db/db/dbNetlist.h @@ -26,8 +26,12 @@ #include "dbCommon.h" #include "dbTypes.h" #include "tlObjectCollection.h" +#include "tlVector.h" #include +#include +#include + namespace db { @@ -43,7 +47,6 @@ class DevicePortDefinition; * A pin is some place other nets can connect to a circuit. */ class DB_PUBLIC Pin - : public tl::Object { public: /** @@ -72,66 +75,25 @@ public: return m_name; } + /** + * @brief Gets the ID of the pin (only pins inside circuits have valid ID's) + */ + size_t id () const + { + return m_id; + } + private: + friend class Circuit; + tl::weak_ptr m_circuit; std::string m_name; -}; + size_t m_id; -/** - * @brief The definition of a port of a device - * - * A port is a connection a device can make. This is the port - * of an actual device. It corresponds to a device class by - * the port ID which is essentially the index of the port - * in the device classes' port list. - */ -class DB_PUBLIC Port - : public tl::Object -{ -public: - typedef size_t port_id_type; - - /** - * @brief Default constructor - */ - Port (); - - /** - * @brief Creates a port of the given device and port ID - */ - Port (Device *device, port_id_type port_id); - - /** - * @brief Gets the device reference - */ - const Device *device () const + void set_id (size_t id) { - return m_device.get (); + m_id = id; } - - /** - * @brief Gets the port id - */ - port_id_type port_id () const - { - return m_port_id; - } - - /** - * @brief Gets the port definition - * - * Returns 0 if the port is not a valid port reference. - */ - const DevicePortDefinition *port_def () const; - - /** - * @brief Returns the device class - */ - const DeviceClass *device_class () const; - -private: - tl::weak_ptr m_device; - port_id_type m_port_id; }; /** @@ -160,6 +122,14 @@ public: return m_device_class.get (); } + /** + * @brief Sets the device class + */ + void set_device_class (DeviceClass *cls) + { + m_device_class.reset (cls); + } + private: tl::weak_ptr m_device_class; }; @@ -199,6 +169,13 @@ public: return m_circuit.get (); } + /** + * @brief Sets the circuit reference + */ + void set_circuit (Circuit *c) + { + m_circuit.reset (c); + } private: tl::weak_ptr m_circuit; @@ -211,6 +188,7 @@ private: */ class DB_PUBLIC NetPortRef { +public: /** * @brief Default constructor */ @@ -219,26 +197,55 @@ class DB_PUBLIC NetPortRef /** * @brief Creates a pin reference to the given pin of the current circuit */ - NetPortRef (Port *port); + NetPortRef (Device *device, size_t port_id); /** - * @brief Gets the port reference + * @brief Gets the device reference */ - Port *port () + Device *device () { - return m_port.get (); + return m_device.get (); } /** - * @brief Gets the port reference (const version) + * @brief Gets the device reference (const version) */ - const Port *port () const + const Device *device () const { - return m_port.get (); + return m_device.get (); } + /** + * @brief Sets the device reference + */ + void set_device (Device *d) + { + m_device.reset (d); + } + + /** + * @brief Gets the port index + */ + size_t port_id () const + { + return m_port_id; + } + + /** + * @brief Gets the port definition + * + * Returns 0 if the port is not a valid port reference. + */ + const DevicePortDefinition *port_def () const; + + /** + * @brief Returns the device class + */ + const DeviceClass *device_class () const; + private: - tl::weak_ptr m_port; + tl::weak_ptr m_device; + size_t m_port_id; }; /** @@ -250,6 +257,7 @@ private: */ class DB_PUBLIC NetPinRef { +public: /** * @brief Default constructor */ @@ -258,29 +266,26 @@ class DB_PUBLIC NetPinRef /** * @brief Creates a pin reference to the given pin of the current circuit */ - NetPinRef (Pin *pin); + NetPinRef (size_t pin_id); /** * @brief Creates a pin reference to the given pin of the given subcircuit */ - NetPinRef (Pin *pin, SubCircuit *circuit); - - /** - * @brief Gets the pin reference - */ - Pin *pin () - { - return m_pin.get (); - } + NetPinRef (size_t pin_id, SubCircuit *circuit); /** * @brief Gets the pin reference (const version) */ - const Pin *pin () const + size_t pin_id () const { - return m_pin.get (); + return m_pin_id; } + /** + * @brief Gets the pin reference from the pin id + */ + const Pin *pin () const; + /** * @brief Gets the subcircuit reference */ @@ -297,8 +302,16 @@ class DB_PUBLIC NetPinRef return m_subcircuit.get (); } + /** + * @brief Sets the subcircuit reference + */ + void set_subcircuit (SubCircuit *s) + { + m_subcircuit.reset (s); + } + private: - tl::weak_ptr m_pin; + size_t m_pin_id; tl::weak_ptr m_subcircuit; }; @@ -394,9 +407,14 @@ public: } private: + friend class Circuit; + port_list m_ports; pin_list m_pins; std::string m_name; + + void translate_devices (const std::map &map); + void translate_subcircuits (const std::map &map); }; /** @@ -409,7 +427,7 @@ class DB_PUBLIC Circuit : public tl::Object { public: - typedef tl::shared_collection pin_list; + typedef tl::vector pin_list; typedef pin_list::const_iterator const_pin_iterator; typedef pin_list::iterator pin_iterator; typedef tl::shared_collection device_list; @@ -477,7 +495,7 @@ public: * * The circuit takes over ownership of the object. */ - void add_pin (Pin *pin); + void add_pin (const Pin &pin); /** * @brief Deletes a pin from the circuit @@ -500,6 +518,11 @@ public: return m_pins.end (); } + /** + * @brief Gets the pin by ID (the ID is basically the index) + */ + const Pin *pin_by_id (size_t id) const; + /** * @brief Begin iterator for the pins of the circuit (const version) */ @@ -649,12 +672,17 @@ public: } private: + friend class Netlist; + std::string m_name; db::cell_index_type m_cell_index; net_list m_nets; pin_list m_pins; device_list m_devices; sub_circuit_list m_sub_circuits; + + void translate_circuits (const std::map &map); + void translate_device_classes (const std::map &map); }; /** @@ -726,6 +754,8 @@ class DB_PUBLIC DeviceClass : public tl::Object { public: + typedef size_t port_id_type; + /** * @brief Constructor *