mirror of https://github.com/KLayout/klayout.git
Added netlist editing features.
This commit is contained in:
parent
e51a3a9ed9
commit
9a9482d7c7
|
|
@ -48,6 +48,15 @@ Device::Device ()
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
Device::~Device ()
|
||||
{
|
||||
for (std::vector<Net::port_iterator>::const_iterator p = m_port_refs.begin (); p != m_port_refs.end (); ++p) {
|
||||
if (*p != Net::port_iterator () && (*p)->net ()) {
|
||||
(*p)->net ()->erase_port (*p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device::Device (DeviceClass *device_class, const std::string &name)
|
||||
: m_device_class (device_class), m_name (name)
|
||||
{
|
||||
|
|
@ -64,7 +73,6 @@ Device &Device::operator= (const Device &other)
|
|||
if (this != &other) {
|
||||
m_name = other.m_name;
|
||||
m_device_class = other.m_device_class;
|
||||
m_nets_per_port.clear ();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -74,32 +82,41 @@ void Device::set_name (const std::string &n)
|
|||
m_name = n;
|
||||
}
|
||||
|
||||
void Device::clear_nets_per_port ()
|
||||
void Device::set_port_ref_for_port (size_t port_id, Net::port_iterator iter)
|
||||
{
|
||||
m_nets_per_port.clear ();
|
||||
}
|
||||
|
||||
void Device::reserve_nets_per_port ()
|
||||
{
|
||||
if (m_device_class.get ()) {
|
||||
m_nets_per_port.clear ();
|
||||
m_nets_per_port.resize (m_device_class->port_definitions ().size (), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Device::set_net_for_port (size_t port_id, const Net *net)
|
||||
{
|
||||
if (port_id < m_nets_per_port.size ()) {
|
||||
m_nets_per_port [port_id] = net;
|
||||
if (m_port_refs.size () < port_id + 1) {
|
||||
m_port_refs.resize (port_id + 1, Net::port_iterator ());
|
||||
}
|
||||
m_port_refs [port_id] = iter;
|
||||
}
|
||||
|
||||
const Net *Device::net_for_port (size_t port_id) const
|
||||
{
|
||||
if (port_id < m_nets_per_port.size ()) {
|
||||
return m_nets_per_port [port_id];
|
||||
} else {
|
||||
return 0;
|
||||
if (port_id < m_port_refs.size ()) {
|
||||
Net::port_iterator p = m_port_refs [port_id];
|
||||
if (p != Net::port_iterator ()) {
|
||||
return p->net ();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Device::connect_port (size_t port_id, Net *net)
|
||||
{
|
||||
if (net_for_port (port_id) == net) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (port_id < m_port_refs.size ()) {
|
||||
Net::port_iterator p = m_port_refs [port_id];
|
||||
if (p != Net::port_iterator () && p->net ()) {
|
||||
p->net ()->erase_port (p);
|
||||
}
|
||||
m_port_refs [port_id] = Net::port_iterator ();
|
||||
}
|
||||
|
||||
if (net) {
|
||||
net->add_port (NetPortRef (this, port_id));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -111,6 +128,15 @@ SubCircuit::SubCircuit ()
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
SubCircuit::~SubCircuit()
|
||||
{
|
||||
for (std::vector<Net::pin_iterator>::const_iterator p = m_pin_refs.begin (); p != m_pin_refs.end (); ++p) {
|
||||
if (*p != Net::pin_iterator () && (*p)->net ()) {
|
||||
(*p)->net ()->erase_pin (*p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SubCircuit::SubCircuit (Circuit *circuit, const std::string &name)
|
||||
: m_circuit (circuit), m_name (name)
|
||||
{
|
||||
|
|
@ -128,7 +154,6 @@ SubCircuit &SubCircuit::operator= (const SubCircuit &other)
|
|||
m_name = other.m_name;
|
||||
m_circuit = other.m_circuit;
|
||||
m_trans = other.m_trans;
|
||||
m_nets_per_pin.clear ();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -143,32 +168,41 @@ void SubCircuit::set_trans (const db::DCplxTrans &t)
|
|||
m_trans = t;
|
||||
}
|
||||
|
||||
void SubCircuit::clear_nets_per_pin ()
|
||||
void SubCircuit::set_pin_ref_for_pin (size_t pin_id, Net::pin_iterator iter)
|
||||
{
|
||||
m_nets_per_pin.clear ();
|
||||
}
|
||||
|
||||
void SubCircuit::reserve_nets_per_pin ()
|
||||
{
|
||||
if (m_circuit.get ()) {
|
||||
m_nets_per_pin.clear ();
|
||||
m_nets_per_pin.resize (m_circuit->pin_count (), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void SubCircuit::set_net_for_pin (size_t pin_id, const Net *net)
|
||||
{
|
||||
if (pin_id < m_nets_per_pin.size ()) {
|
||||
m_nets_per_pin [pin_id] = net;
|
||||
if (m_pin_refs.size () < pin_id + 1) {
|
||||
m_pin_refs.resize (pin_id + 1, Net::pin_iterator ());
|
||||
}
|
||||
m_pin_refs [pin_id] = iter;
|
||||
}
|
||||
|
||||
const Net *SubCircuit::net_for_pin (size_t pin_id) const
|
||||
{
|
||||
if (pin_id < m_nets_per_pin.size ()) {
|
||||
return m_nets_per_pin [pin_id];
|
||||
} else {
|
||||
return 0;
|
||||
if (pin_id < m_pin_refs.size ()) {
|
||||
Net::pin_iterator p = m_pin_refs [pin_id];
|
||||
if (p != Net::pin_iterator ()) {
|
||||
return p->net ();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SubCircuit::connect_pin (size_t pin_id, Net *net)
|
||||
{
|
||||
if (net_for_pin (pin_id) == net) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pin_id < m_pin_refs.size ()) {
|
||||
Net::pin_iterator p = m_pin_refs [pin_id];
|
||||
if (p != Net::pin_iterator () && p->net ()) {
|
||||
p->net ()->erase_pin (p);
|
||||
}
|
||||
m_pin_refs [pin_id] = Net::pin_iterator ();
|
||||
}
|
||||
|
||||
if (net) {
|
||||
net->add_pin (NetPinRef (this, pin_id));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -176,16 +210,32 @@ const Net *SubCircuit::net_for_pin (size_t pin_id) const
|
|||
// NetPortRef class implementation
|
||||
|
||||
NetPortRef::NetPortRef ()
|
||||
: m_port_id (0), mp_device (0), mp_net (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
NetPortRef::NetPortRef (Device *device, size_t port_id)
|
||||
: m_device (device), m_port_id (port_id)
|
||||
: m_port_id (port_id), mp_device (device), mp_net (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
NetPortRef::NetPortRef (const NetPortRef &other)
|
||||
: m_port_id (other.m_port_id), mp_device (other.mp_device), mp_net (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
NetPortRef &NetPortRef::operator= (const NetPortRef &other)
|
||||
{
|
||||
if (this != &other) {
|
||||
m_port_id = other.m_port_id;
|
||||
mp_device = other.mp_device;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
const DevicePortDefinition *
|
||||
NetPortRef::port_def () const
|
||||
{
|
||||
|
|
@ -200,38 +250,53 @@ NetPortRef::port_def () const
|
|||
const DeviceClass *
|
||||
NetPortRef::device_class () const
|
||||
{
|
||||
const Device *device = m_device.get ();
|
||||
return device ? device->device_class () : 0;
|
||||
return mp_device ? mp_device->device_class () : 0;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
// NetPinRef class implementation
|
||||
|
||||
NetPinRef::NetPinRef ()
|
||||
: m_pin_id (0), mp_subcircuit (0), mp_net (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
NetPinRef::NetPinRef (size_t pin_id)
|
||||
: m_pin_id (pin_id)
|
||||
: m_pin_id (pin_id), mp_subcircuit (0), mp_net (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
NetPinRef::NetPinRef (size_t pin_id, SubCircuit *circuit)
|
||||
: m_pin_id (pin_id), m_subcircuit (circuit)
|
||||
NetPinRef::NetPinRef (SubCircuit *circuit, size_t pin_id)
|
||||
: m_pin_id (pin_id), mp_subcircuit (circuit), mp_net (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
NetPinRef::NetPinRef (const NetPinRef &other)
|
||||
: m_pin_id (other.m_pin_id), mp_subcircuit (other.mp_subcircuit), mp_net (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
NetPinRef &NetPinRef::operator= (const NetPinRef &other)
|
||||
{
|
||||
if (this != &other) {
|
||||
m_pin_id = other.m_pin_id;
|
||||
mp_subcircuit = other.mp_subcircuit;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
const Pin *NetPinRef::pin (const db::Circuit *c) const
|
||||
{
|
||||
if (! m_subcircuit.get ()) {
|
||||
if (! mp_subcircuit) {
|
||||
tl_assert (c != 0);
|
||||
return c->pin_by_id (m_pin_id);
|
||||
} else {
|
||||
tl_assert (m_subcircuit->circuit () != 0);
|
||||
return m_subcircuit->circuit ()->pin_by_id (m_pin_id);
|
||||
tl_assert (mp_subcircuit->circuit () != 0);
|
||||
return mp_subcircuit->circuit ()->pin_by_id (m_pin_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -253,20 +318,41 @@ Net::Net (const Net &other)
|
|||
Net &Net::operator= (const Net &other)
|
||||
{
|
||||
if (this != &other) {
|
||||
|
||||
clear ();
|
||||
|
||||
m_name = other.m_name;
|
||||
m_pins = other.m_pins;
|
||||
m_ports = other.m_ports;
|
||||
m_cluster_id = other.m_cluster_id;
|
||||
|
||||
for (const_pin_iterator i = other.begin_pins (); i != other.end_pins (); ++i) {
|
||||
add_pin (*i);
|
||||
}
|
||||
|
||||
for (const_port_iterator i = other.begin_ports (); i != other.end_ports (); ++i) {
|
||||
add_port (*i);
|
||||
}
|
||||
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Net::~Net ()
|
||||
{
|
||||
clear ();
|
||||
}
|
||||
|
||||
void Net::clear ()
|
||||
{
|
||||
m_name.clear ();
|
||||
m_ports.clear ();
|
||||
m_pins.clear ();
|
||||
m_cluster_id = 0;
|
||||
|
||||
while (! m_ports.empty ()) {
|
||||
erase_port (begin_ports ());
|
||||
}
|
||||
|
||||
while (! m_pins.empty ()) {
|
||||
erase_pin (begin_pins ());
|
||||
}
|
||||
}
|
||||
|
||||
void Net::set_name (const std::string &name)
|
||||
|
|
@ -282,37 +368,46 @@ void Net::set_cluster_id (size_t ci)
|
|||
void Net::add_pin (const NetPinRef &pin)
|
||||
{
|
||||
m_pins.push_back (pin);
|
||||
if (mp_circuit) {
|
||||
mp_circuit->invalidate_nets_per_pin ();
|
||||
NetPinRef &new_pin = m_pins.back ();
|
||||
new_pin.set_net (this);
|
||||
|
||||
if (! pin.subcircuit ()) {
|
||||
if (mp_circuit) {
|
||||
mp_circuit->set_pin_ref_for_pin (new_pin.pin_id (), --m_pins.end ());
|
||||
}
|
||||
} else {
|
||||
new_pin.subcircuit ()->set_pin_ref_for_pin (new_pin.pin_id (), --m_pins.end ());
|
||||
}
|
||||
}
|
||||
|
||||
void Net::erase_pin (pin_iterator iter)
|
||||
{
|
||||
if (iter->subcircuit ()) {
|
||||
iter->subcircuit ()->set_pin_ref_for_pin (iter->pin_id (), pin_iterator ());
|
||||
} else if (mp_circuit) {
|
||||
mp_circuit->set_pin_ref_for_pin (iter->pin_id (), pin_iterator ());
|
||||
}
|
||||
m_pins.erase (iter);
|
||||
}
|
||||
|
||||
void Net::add_port (const NetPortRef &port)
|
||||
{
|
||||
if (! port.device ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_ports.push_back (port);
|
||||
if (mp_circuit) {
|
||||
mp_circuit->invalidate_nets_per_pin ();
|
||||
}
|
||||
NetPortRef &new_port = m_ports.back ();
|
||||
new_port.set_net (this);
|
||||
new_port.device ()->set_port_ref_for_port (new_port.port_id (), --m_ports.end ());
|
||||
}
|
||||
|
||||
void Net::translate_devices (const std::map<const Device *, Device *> &map)
|
||||
void Net::erase_port (port_iterator iter)
|
||||
{
|
||||
for (port_list::iterator i = m_ports.begin (); i != m_ports.end (); ++i) {
|
||||
std::map<const Device *, Device *>::const_iterator m = map.find (i->device ());
|
||||
tl_assert (m != map.end ());
|
||||
i->set_device (m->second);
|
||||
}
|
||||
}
|
||||
|
||||
void Net::translate_subcircuits (const std::map<const SubCircuit *, SubCircuit *> &map)
|
||||
{
|
||||
for (pin_list::iterator i = m_pins.begin (); i != m_pins.end (); ++i) {
|
||||
if (i->subcircuit ()) {
|
||||
std::map<const SubCircuit *, SubCircuit *>::const_iterator m = map.find (i->subcircuit ());
|
||||
tl_assert (m != map.end ());
|
||||
i->set_subcircuit (m->second);
|
||||
}
|
||||
if (iter->device ()) {
|
||||
iter->device ()->set_port_ref_for_port (iter->port_id (), port_iterator ());
|
||||
}
|
||||
m_ports.erase (iter);
|
||||
}
|
||||
|
||||
void Net::set_circuit (Circuit *circuit)
|
||||
|
|
@ -324,13 +419,13 @@ void Net::set_circuit (Circuit *circuit)
|
|||
// Circuit class implementation
|
||||
|
||||
Circuit::Circuit ()
|
||||
: mp_netlist (0), m_nets_per_pin_valid (false)
|
||||
: mp_netlist (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
Circuit::Circuit (const Circuit &other)
|
||||
: mp_netlist (0), m_nets_per_pin_valid (false)
|
||||
: mp_netlist (0)
|
||||
{
|
||||
operator= (other);
|
||||
}
|
||||
|
|
@ -340,9 +435,6 @@ Circuit &Circuit::operator= (const Circuit &other)
|
|||
if (this != &other) {
|
||||
|
||||
m_name = other.m_name;
|
||||
m_nets_per_pin_valid = false;
|
||||
m_nets_per_pin.clear ();
|
||||
invalidate_nets_per_pin ();
|
||||
|
||||
for (const_pin_iterator i = other.begin_pins (); i != other.end_pins (); ++i) {
|
||||
add_pin (*i);
|
||||
|
|
@ -363,13 +455,33 @@ Circuit &Circuit::operator= (const Circuit &other)
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
// translate the net
|
||||
Net *n = new Net ();
|
||||
n->set_cluster_id (i->cluster_id ());
|
||||
n->set_name (i->name ());
|
||||
add_net (n);
|
||||
|
||||
for (Net::const_port_iterator p = i->begin_ports (); p != i->end_ports (); ++p) {
|
||||
std::map<const Device *, Device *>::const_iterator m = device_table.find (p->device ());
|
||||
tl_assert (m != device_table.end ());
|
||||
n->add_port (NetPortRef (m->second, p->port_id ()));
|
||||
}
|
||||
|
||||
for (Net::const_pin_iterator p = i->begin_pins (); p != i->end_pins (); ++p) {
|
||||
if (! p->subcircuit ()) {
|
||||
n->add_pin (NetPinRef (p->pin_id ()));
|
||||
} else {
|
||||
std::map<const SubCircuit *, SubCircuit *>::const_iterator m = sc_table.find (p->subcircuit ());
|
||||
tl_assert (m != sc_table.end ());
|
||||
n->add_pin (NetPinRef (m->second, p->pin_id ()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -394,7 +506,6 @@ void Circuit::clear ()
|
|||
m_devices.clear ();
|
||||
m_nets.clear ();
|
||||
m_sub_circuits.clear ();
|
||||
invalidate_nets_per_pin ();
|
||||
}
|
||||
|
||||
void Circuit::set_name (const std::string &name)
|
||||
|
|
@ -411,44 +522,37 @@ void Circuit::add_pin (const Pin &pin)
|
|||
{
|
||||
m_pins.push_back (pin);
|
||||
m_pins.back ().set_id (m_pins.size () - 1);
|
||||
invalidate_nets_per_pin ();
|
||||
}
|
||||
|
||||
void Circuit::add_net (Net *net)
|
||||
{
|
||||
m_nets.push_back (net);
|
||||
net->set_circuit (this);
|
||||
invalidate_nets_per_pin ();
|
||||
}
|
||||
|
||||
void Circuit::remove_net (Net *net)
|
||||
{
|
||||
m_nets.erase (net);
|
||||
invalidate_nets_per_pin ();
|
||||
}
|
||||
|
||||
void Circuit::add_device (Device *device)
|
||||
{
|
||||
m_devices.push_back (device);
|
||||
invalidate_nets_per_pin ();
|
||||
}
|
||||
|
||||
void Circuit::remove_device (Device *device)
|
||||
{
|
||||
m_devices.erase (device);
|
||||
invalidate_nets_per_pin ();
|
||||
}
|
||||
|
||||
void Circuit::add_sub_circuit (SubCircuit *sub_circuit)
|
||||
{
|
||||
m_sub_circuits.push_back (sub_circuit);
|
||||
invalidate_nets_per_pin ();
|
||||
}
|
||||
|
||||
void Circuit::remove_sub_circuit (SubCircuit *sub_circuit)
|
||||
{
|
||||
m_sub_circuits.erase (sub_circuit);
|
||||
invalidate_nets_per_pin ();
|
||||
}
|
||||
|
||||
void Circuit::translate_circuits (const std::map<const Circuit *, Circuit *> &map)
|
||||
|
|
@ -469,85 +573,42 @@ void Circuit::translate_device_classes (const std::map<const DeviceClass *, Devi
|
|||
}
|
||||
}
|
||||
|
||||
void Circuit::set_pin_ref_for_pin (size_t pin_id, Net::pin_iterator iter)
|
||||
{
|
||||
if (m_pin_refs.size () < pin_id + 1) {
|
||||
m_pin_refs.resize (pin_id + 1, Net::pin_iterator ());
|
||||
}
|
||||
m_pin_refs [pin_id] = iter;
|
||||
}
|
||||
|
||||
const Net *Circuit::net_for_pin (size_t pin_id) const
|
||||
{
|
||||
if (! m_nets_per_pin_valid) {
|
||||
const_cast<Circuit *> (this)->validate_nets_per_pin ();
|
||||
}
|
||||
if (pin_id >= m_nets_per_pin.size ()) {
|
||||
return 0;
|
||||
} else {
|
||||
return m_nets_per_pin [pin_id];
|
||||
if (pin_id < m_pin_refs.size ()) {
|
||||
Net::pin_iterator p = m_pin_refs [pin_id];
|
||||
if (p != Net::pin_iterator ()) {
|
||||
return p->net ();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Net *Circuit::net_for_pin (const SubCircuit *sub_circuit, size_t pin_id) const
|
||||
void Circuit::connect_pin (size_t pin_id, Net *net)
|
||||
{
|
||||
if (! m_nets_per_pin_valid) {
|
||||
const_cast<Circuit *> (this)->validate_nets_per_pin ();
|
||||
if (net_for_pin (pin_id) == net) {
|
||||
return;
|
||||
}
|
||||
return sub_circuit->net_for_pin (pin_id);
|
||||
}
|
||||
|
||||
const Net *Circuit::net_for_port (const Device *device, size_t port_id) const
|
||||
{
|
||||
if (! m_nets_per_pin_valid) {
|
||||
const_cast<Circuit *> (this)->validate_nets_per_pin ();
|
||||
}
|
||||
return device->net_for_port (port_id);
|
||||
}
|
||||
|
||||
void Circuit::invalidate_nets_per_pin ()
|
||||
{
|
||||
if (m_nets_per_pin_valid) {
|
||||
|
||||
m_nets_per_pin_valid = false;
|
||||
m_nets_per_pin.clear ();
|
||||
|
||||
for (sub_circuit_iterator i = begin_sub_circuits (); i != end_sub_circuits (); ++i) {
|
||||
i->clear_nets_per_pin ();
|
||||
if (pin_id < m_pin_refs.size ()) {
|
||||
Net::pin_iterator p = m_pin_refs [pin_id];
|
||||
if (p != Net::pin_iterator () && p->net ()) {
|
||||
p->net ()->erase_pin (p);
|
||||
}
|
||||
|
||||
for (device_iterator i = begin_devices (); i != end_devices (); ++i) {
|
||||
i->clear_nets_per_port ();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Circuit::validate_nets_per_pin ()
|
||||
{
|
||||
m_nets_per_pin.clear ();
|
||||
m_nets_per_pin.resize (m_pins.size (), 0);
|
||||
|
||||
for (sub_circuit_iterator i = begin_sub_circuits (); i != end_sub_circuits (); ++i) {
|
||||
i->reserve_nets_per_pin ();
|
||||
m_pin_refs [pin_id] = Net::pin_iterator ();
|
||||
}
|
||||
|
||||
for (device_iterator i = begin_devices (); i != end_devices (); ++i) {
|
||||
i->reserve_nets_per_port ();
|
||||
if (net) {
|
||||
net->add_pin (NetPinRef (pin_id));
|
||||
}
|
||||
|
||||
for (net_iterator n = begin_nets (); n != end_nets (); ++n) {
|
||||
|
||||
for (Net::const_pin_iterator p = n->begin_pins (); p != n->end_pins (); ++p) {
|
||||
size_t id = p->pin_id ();
|
||||
if (p->subcircuit () == 0) {
|
||||
if (id < m_nets_per_pin.size ()) {
|
||||
m_nets_per_pin [id] = n.operator-> ();
|
||||
}
|
||||
} else {
|
||||
(const_cast<SubCircuit *> (p->subcircuit ()))->set_net_for_pin (id, n.operator-> ());
|
||||
}
|
||||
}
|
||||
|
||||
for (Net::const_port_iterator p = n->begin_ports (); p != n->end_ports (); ++p) {
|
||||
(const_cast<Device *> (p->device ()))->set_net_for_port (p->port_id (), n.operator-> ());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
m_nets_per_pin_valid = true;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -38,235 +38,13 @@ namespace db
|
|||
{
|
||||
|
||||
class Circuit;
|
||||
class SubCircuit;
|
||||
class Pin;
|
||||
class Device;
|
||||
class DeviceClass;
|
||||
class DevicePortDefinition;
|
||||
class Netlist;
|
||||
class Net;
|
||||
/**
|
||||
* @brief The definition of a pin of a circuit
|
||||
*
|
||||
* A pin is some place other nets can connect to a circuit.
|
||||
*/
|
||||
class DB_PUBLIC Pin
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*/
|
||||
Pin ();
|
||||
|
||||
/**
|
||||
* @brief Creates a pin with the given name.
|
||||
*/
|
||||
Pin (const std::string &name);
|
||||
|
||||
/**
|
||||
* @brief Gets the name of the pin
|
||||
*/
|
||||
const std::string &name () const
|
||||
{
|
||||
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<Circuit> m_circuit;
|
||||
std::string m_name;
|
||||
size_t m_id;
|
||||
|
||||
void set_id (size_t id)
|
||||
{
|
||||
m_id = id;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An actual device
|
||||
*
|
||||
* This class represents the incarnation of a specific device.
|
||||
* The device has a class which specifies a type. This class
|
||||
* is intended for subclassing.
|
||||
* A specific device subclass is supposed to correspond to
|
||||
* a specific device class.
|
||||
*/
|
||||
class DB_PUBLIC Device
|
||||
: public tl::Object
|
||||
{
|
||||
public:
|
||||
typedef tl::vector<const Net *> connected_net_list;
|
||||
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*/
|
||||
Device ();
|
||||
|
||||
/**
|
||||
* @brief The constructor
|
||||
*/
|
||||
Device (DeviceClass *device_class, const std::string &name = std::string ());
|
||||
|
||||
/**
|
||||
* @brief Copy constructor
|
||||
*/
|
||||
Device (const Device &other);
|
||||
|
||||
/**
|
||||
* @brief Assignment
|
||||
*/
|
||||
Device &operator= (const Device &other);
|
||||
|
||||
/**
|
||||
* @brief Gets the device class
|
||||
*/
|
||||
const DeviceClass *device_class () const
|
||||
{
|
||||
return m_device_class.get ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the name
|
||||
*/
|
||||
void set_name (const std::string &n);
|
||||
|
||||
/**
|
||||
* @brief Gets the name
|
||||
*/
|
||||
const std::string &name () const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Circuit;
|
||||
|
||||
tl::weak_ptr<DeviceClass> m_device_class;
|
||||
std::string m_name;
|
||||
mutable connected_net_list m_nets_per_port;
|
||||
|
||||
void clear_nets_per_port ();
|
||||
void reserve_nets_per_port ();
|
||||
void set_net_for_port (size_t port_id, const Net *net);
|
||||
const Net *net_for_port (size_t port_id) const;
|
||||
|
||||
/**
|
||||
* @brief Sets the device class
|
||||
*/
|
||||
void set_device_class (DeviceClass *dc)
|
||||
{
|
||||
m_device_class.reset (dc);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A subcircuit of a circuit
|
||||
*
|
||||
* This class essentially is a reference to another circuit
|
||||
*/
|
||||
class DB_PUBLIC SubCircuit
|
||||
: public tl::Object
|
||||
{
|
||||
public:
|
||||
typedef tl::vector<const Net *> connected_net_list;
|
||||
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*/
|
||||
SubCircuit ();
|
||||
|
||||
/**
|
||||
* @brief Copy constructor
|
||||
*/
|
||||
SubCircuit (const SubCircuit &other);
|
||||
|
||||
/**
|
||||
* @brief Assignment
|
||||
*/
|
||||
SubCircuit &operator= (const SubCircuit &other);
|
||||
|
||||
/**
|
||||
* @brief Creates a subcircuit reference to the given circuit
|
||||
*/
|
||||
SubCircuit (Circuit *circuit, const std::string &name = std::string ());
|
||||
|
||||
/**
|
||||
* @brief Gets the circuit the reference points to (const version)
|
||||
*/
|
||||
const Circuit *circuit () const
|
||||
{
|
||||
return m_circuit.get ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the circuit the reference points to (non-const version)
|
||||
*/
|
||||
Circuit *circuit ()
|
||||
{
|
||||
return m_circuit.get ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the name of the subcircuit
|
||||
*
|
||||
* The name is one way to identify the subcircuit. The transformation is
|
||||
* another one.
|
||||
*/
|
||||
void set_name (const std::string &n);
|
||||
|
||||
/**
|
||||
* @brief Gets the name of the subcircuit
|
||||
*/
|
||||
const std::string &name () const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the transformation describing the subcircuit
|
||||
*
|
||||
* The transformation is a natural description of a subcircuit
|
||||
* (in contrast to the name) when deriving it from a layout.
|
||||
*/
|
||||
void set_trans (const db::DCplxTrans &trans);
|
||||
|
||||
/**
|
||||
* @brief Gets the transformation describing the subcircuit
|
||||
*/
|
||||
const db::DCplxTrans &trans () const
|
||||
{
|
||||
return m_trans;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Circuit;
|
||||
|
||||
tl::weak_ptr<Circuit> m_circuit;
|
||||
std::string m_name;
|
||||
db::DCplxTrans m_trans;
|
||||
mutable connected_net_list m_nets_per_pin;
|
||||
|
||||
void clear_nets_per_pin ();
|
||||
void reserve_nets_per_pin ();
|
||||
void set_net_for_pin (size_t pin_id, const Net *net);
|
||||
const Net *net_for_pin (size_t pin_id) const;
|
||||
|
||||
/**
|
||||
* @brief Sets the circuit reference
|
||||
*/
|
||||
void set_circuit (Circuit *c)
|
||||
{
|
||||
m_circuit.reset (c);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A reference to a port of a device
|
||||
|
|
@ -286,12 +64,22 @@ public:
|
|||
*/
|
||||
NetPortRef (Device *device, size_t port_id);
|
||||
|
||||
/**
|
||||
* @brief Copy constructor
|
||||
*/
|
||||
NetPortRef (const NetPortRef &other);
|
||||
|
||||
/**
|
||||
* @brief Assignment
|
||||
*/
|
||||
NetPortRef &operator= (const NetPortRef &other);
|
||||
|
||||
/**
|
||||
* @brief Gets the device reference
|
||||
*/
|
||||
Device *device ()
|
||||
{
|
||||
return m_device.get ();
|
||||
return mp_device;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -299,15 +87,7 @@ public:
|
|||
*/
|
||||
const Device *device () const
|
||||
{
|
||||
return m_device.get ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the device reference
|
||||
*/
|
||||
void set_device (Device *d)
|
||||
{
|
||||
m_device.reset (d);
|
||||
return mp_device;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -330,9 +110,36 @@ public:
|
|||
*/
|
||||
const DeviceClass *device_class () const;
|
||||
|
||||
/**
|
||||
* @brief Gets the net the port lives in
|
||||
*/
|
||||
Net *net ()
|
||||
{
|
||||
return mp_net;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the net the port lives in (const version)
|
||||
*/
|
||||
const Net *net () const
|
||||
{
|
||||
return mp_net;
|
||||
}
|
||||
|
||||
private:
|
||||
tl::weak_ptr<Device> m_device;
|
||||
friend class Net;
|
||||
|
||||
size_t m_port_id;
|
||||
Device *mp_device;
|
||||
Net *mp_net;
|
||||
|
||||
/**
|
||||
* @brief Sets the net the port lives in
|
||||
*/
|
||||
void set_net (Net *net)
|
||||
{
|
||||
mp_net = net;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -358,7 +165,17 @@ public:
|
|||
/**
|
||||
* @brief Creates a pin reference to the given pin of the given subcircuit
|
||||
*/
|
||||
NetPinRef (size_t pin_id, SubCircuit *circuit);
|
||||
NetPinRef (SubCircuit *circuit, size_t pin_id);
|
||||
|
||||
/**
|
||||
* @brief Copy constructor
|
||||
*/
|
||||
NetPinRef (const NetPinRef &other);
|
||||
|
||||
/**
|
||||
* @brief Assignment
|
||||
*/
|
||||
NetPinRef &operator= (const NetPinRef &other);
|
||||
|
||||
/**
|
||||
* @brief Gets the pin reference (const version)
|
||||
|
|
@ -381,7 +198,7 @@ public:
|
|||
*/
|
||||
SubCircuit *subcircuit ()
|
||||
{
|
||||
return m_subcircuit.get ();
|
||||
return mp_subcircuit;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -389,20 +206,39 @@ public:
|
|||
*/
|
||||
const SubCircuit *subcircuit () const
|
||||
{
|
||||
return m_subcircuit.get ();
|
||||
return mp_subcircuit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the subcircuit reference
|
||||
* @brief Gets the net the pin lives in
|
||||
*/
|
||||
void set_subcircuit (SubCircuit *s)
|
||||
Net *net ()
|
||||
{
|
||||
m_subcircuit.reset (s);
|
||||
return mp_net;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the net the pin lives in (const version)
|
||||
*/
|
||||
const Net *net () const
|
||||
{
|
||||
return mp_net;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Net;
|
||||
|
||||
size_t m_pin_id;
|
||||
tl::weak_ptr<SubCircuit> m_subcircuit;
|
||||
SubCircuit *mp_subcircuit;
|
||||
Net *mp_net;
|
||||
|
||||
/**
|
||||
* @brief Sets the net the port lives in
|
||||
*/
|
||||
void set_net (Net *net)
|
||||
{
|
||||
mp_net = net;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -416,12 +252,13 @@ class DB_PUBLIC Net
|
|||
public:
|
||||
typedef std::list<NetPortRef> port_list;
|
||||
typedef port_list::const_iterator const_port_iterator;
|
||||
typedef port_list::iterator port_iterator;
|
||||
typedef std::list<NetPinRef> pin_list;
|
||||
typedef pin_list::const_iterator const_pin_iterator;
|
||||
typedef pin_list::iterator pin_iterator;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* Creates an empty circuit.
|
||||
*/
|
||||
Net ();
|
||||
|
|
@ -431,6 +268,11 @@ public:
|
|||
*/
|
||||
Net (const Net &other);
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~Net ();
|
||||
|
||||
/**
|
||||
* @brief Assignment
|
||||
*/
|
||||
|
|
@ -493,6 +335,11 @@ public:
|
|||
*/
|
||||
void add_pin (const NetPinRef &pin);
|
||||
|
||||
/**
|
||||
* @brief Erases the given pin from this net
|
||||
*/
|
||||
void erase_pin (pin_iterator iter);
|
||||
|
||||
/**
|
||||
* @brief Begin iterator for the pins of the net (const version)
|
||||
*/
|
||||
|
|
@ -509,11 +356,32 @@ public:
|
|||
return m_pins.end ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Begin iterator for the pins of the net (non-const version)
|
||||
*/
|
||||
pin_iterator begin_pins ()
|
||||
{
|
||||
return m_pins.begin ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief End iterator for the pins of the net (non-const version)
|
||||
*/
|
||||
pin_iterator end_pins ()
|
||||
{
|
||||
return m_pins.end ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds a port to this net
|
||||
*/
|
||||
void add_port (const NetPortRef &port);
|
||||
|
||||
/**
|
||||
* @brief Erases the given port from this net
|
||||
*/
|
||||
void erase_port (port_iterator iter);
|
||||
|
||||
/**
|
||||
* @brief Begin iterator for the ports of the net (const version)
|
||||
*/
|
||||
|
|
@ -530,6 +398,22 @@ public:
|
|||
return m_ports.end ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Begin iterator for the ports of the net (non-const version)
|
||||
*/
|
||||
port_iterator begin_ports ()
|
||||
{
|
||||
return m_ports.begin ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief End iterator for the ports of the net (non-const version)
|
||||
*/
|
||||
port_iterator end_ports ()
|
||||
{
|
||||
return m_ports.end ();
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Circuit;
|
||||
|
||||
|
|
@ -539,11 +423,290 @@ private:
|
|||
size_t m_cluster_id;
|
||||
Circuit *mp_circuit;
|
||||
|
||||
void translate_devices (const std::map<const Device *, Device *> &map);
|
||||
void translate_subcircuits (const std::map<const SubCircuit *, SubCircuit *> &map);
|
||||
void set_circuit (Circuit *circuit);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The definition of a pin of a circuit
|
||||
*
|
||||
* A pin is some place other nets can connect to a circuit.
|
||||
*/
|
||||
class DB_PUBLIC Pin
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*/
|
||||
Pin ();
|
||||
|
||||
/**
|
||||
* @brief Creates a pin with the given name.
|
||||
*/
|
||||
Pin (const std::string &name);
|
||||
|
||||
/**
|
||||
* @brief Gets the name of the pin
|
||||
*/
|
||||
const std::string &name () const
|
||||
{
|
||||
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<Circuit> m_circuit;
|
||||
std::string m_name;
|
||||
size_t m_id;
|
||||
|
||||
void set_id (size_t id)
|
||||
{
|
||||
m_id = id;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An actual device
|
||||
*
|
||||
* This class represents the incarnation of a specific device.
|
||||
* The device has a class which specifies a type. This class
|
||||
* is intended for subclassing.
|
||||
* A specific device subclass is supposed to correspond to
|
||||
* a specific device class.
|
||||
*/
|
||||
class DB_PUBLIC Device
|
||||
: public tl::Object
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*/
|
||||
Device ();
|
||||
|
||||
/**
|
||||
* @brief The constructor
|
||||
*/
|
||||
Device (DeviceClass *device_class, const std::string &name = std::string ());
|
||||
|
||||
/**
|
||||
* @brief Copy constructor
|
||||
*/
|
||||
Device (const Device &other);
|
||||
|
||||
/**
|
||||
* @brief Assignment
|
||||
*/
|
||||
Device &operator= (const Device &other);
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~Device ();
|
||||
|
||||
/**
|
||||
* @brief Gets the device class
|
||||
*/
|
||||
const DeviceClass *device_class () const
|
||||
{
|
||||
return m_device_class.get ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the name
|
||||
*/
|
||||
void set_name (const std::string &n);
|
||||
|
||||
/**
|
||||
* @brief Gets the name
|
||||
*/
|
||||
const std::string &name () const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the net attached to a specific port
|
||||
* Returns 0 if no net is attached.
|
||||
*/
|
||||
const Net *net_for_port (size_t port_id) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the net attached to a specific port (non-const version)
|
||||
* Returns 0 if no net is attached.
|
||||
*/
|
||||
Net *net_for_port (size_t port_id)
|
||||
{
|
||||
return const_cast<Net *> (((const Device *) this)->net_for_port (port_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Connects the given port to the given net
|
||||
* If the net is 0 the port is disconnected.
|
||||
* If non-null, a NetPortRef object will be inserted into the
|
||||
* net and connected with the given port.
|
||||
*/
|
||||
void connect_port (size_t port_id, Net *net);
|
||||
|
||||
private:
|
||||
friend class Circuit;
|
||||
friend class Net;
|
||||
|
||||
tl::weak_ptr<DeviceClass> m_device_class;
|
||||
std::string m_name;
|
||||
std::vector<Net::port_iterator> m_port_refs;
|
||||
|
||||
/**
|
||||
* @brief Sets the port reference for a specific port
|
||||
*/
|
||||
void set_port_ref_for_port (size_t port_id, Net::port_iterator iter);
|
||||
|
||||
/**
|
||||
* @brief Sets the device class
|
||||
*/
|
||||
void set_device_class (DeviceClass *dc)
|
||||
{
|
||||
m_device_class.reset (dc);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A subcircuit of a circuit
|
||||
*
|
||||
* This class essentially is a reference to another circuit
|
||||
*/
|
||||
class DB_PUBLIC SubCircuit
|
||||
: public tl::Object
|
||||
{
|
||||
public:
|
||||
typedef tl::vector<const Net *> connected_net_list;
|
||||
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*/
|
||||
SubCircuit ();
|
||||
|
||||
/**
|
||||
* @brief Copy constructor
|
||||
*/
|
||||
SubCircuit (const SubCircuit &other);
|
||||
|
||||
/**
|
||||
* @brief Assignment
|
||||
*/
|
||||
SubCircuit &operator= (const SubCircuit &other);
|
||||
|
||||
/**
|
||||
* @brief Creates a subcircuit reference to the given circuit
|
||||
*/
|
||||
SubCircuit (Circuit *circuit, const std::string &name = std::string ());
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~SubCircuit ();
|
||||
|
||||
/**
|
||||
* @brief Gets the circuit the reference points to (const version)
|
||||
*/
|
||||
const Circuit *circuit () const
|
||||
{
|
||||
return m_circuit.get ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the circuit the reference points to (non-const version)
|
||||
*/
|
||||
Circuit *circuit ()
|
||||
{
|
||||
return m_circuit.get ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the name of the subcircuit
|
||||
*
|
||||
* The name is one way to identify the subcircuit. The transformation is
|
||||
* another one.
|
||||
*/
|
||||
void set_name (const std::string &n);
|
||||
|
||||
/**
|
||||
* @brief Gets the name of the subcircuit
|
||||
*/
|
||||
const std::string &name () const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the transformation describing the subcircuit
|
||||
*
|
||||
* The transformation is a natural description of a subcircuit
|
||||
* (in contrast to the name) when deriving it from a layout.
|
||||
*/
|
||||
void set_trans (const db::DCplxTrans &trans);
|
||||
|
||||
/**
|
||||
* @brief Gets the transformation describing the subcircuit
|
||||
*/
|
||||
const db::DCplxTrans &trans () const
|
||||
{
|
||||
return m_trans;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the net attached to a specific pin
|
||||
* Returns 0 if no net is attached.
|
||||
*/
|
||||
const Net *net_for_pin (size_t pin_id) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the net attached to a specific pin (non-const version)
|
||||
* Returns 0 if no net is attached.
|
||||
*/
|
||||
Net *net_for_pin (size_t pin_id)
|
||||
{
|
||||
return const_cast<Net *> (((const SubCircuit *) 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);
|
||||
|
||||
private:
|
||||
friend class Circuit;
|
||||
friend class Net;
|
||||
|
||||
tl::weak_ptr<Circuit> m_circuit;
|
||||
std::string m_name;
|
||||
db::DCplxTrans m_trans;
|
||||
std::vector<Net::pin_iterator> m_pin_refs;
|
||||
|
||||
/**
|
||||
* @brief Sets the pin reference for a specific pin
|
||||
*/
|
||||
void set_pin_ref_for_pin (size_t ppin_id, Net::pin_iterator iter);
|
||||
|
||||
/**
|
||||
* @brief Sets the circuit reference
|
||||
*/
|
||||
void set_circuit (Circuit *c)
|
||||
{
|
||||
m_circuit.reset (c);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A circuit
|
||||
*
|
||||
|
|
@ -566,7 +729,6 @@ public:
|
|||
typedef tl::shared_collection<SubCircuit> sub_circuit_list;
|
||||
typedef sub_circuit_list::const_iterator const_sub_circuit_iterator;
|
||||
typedef sub_circuit_list::iterator sub_circuit_iterator;
|
||||
typedef tl::vector<const Net *> connected_net_list;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
|
|
@ -838,30 +1000,12 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the net for a given pin of a subcircuit
|
||||
* @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.
|
||||
*/
|
||||
const Net *net_for_pin (const SubCircuit *sub_circuit, size_t pin_id) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the net for a given pin of a subcircuit (non-const version)
|
||||
*/
|
||||
Net *net_for_pin (SubCircuit *sub_circuit, size_t pin_id)
|
||||
{
|
||||
return const_cast<Net *> (((const Circuit *) this)->net_for_pin (sub_circuit, pin_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the net for a given port of a device
|
||||
*/
|
||||
const Net *net_for_port (const Device *device, size_t port_id) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the net for a given port of a device (non-const version)
|
||||
*/
|
||||
Net *net_for_port (Device *device, size_t port_id)
|
||||
{
|
||||
return const_cast<Net *> (((const Circuit *) this)->net_for_port (device, port_id));
|
||||
}
|
||||
void connect_pin (size_t pin_id, Net *net);
|
||||
|
||||
private:
|
||||
friend class Netlist;
|
||||
|
|
@ -874,14 +1018,16 @@ private:
|
|||
device_list m_devices;
|
||||
sub_circuit_list m_sub_circuits;
|
||||
Netlist *mp_netlist;
|
||||
connected_net_list m_nets_per_pin;
|
||||
bool m_nets_per_pin_valid;
|
||||
std::vector<Net::pin_iterator> m_pin_refs;
|
||||
|
||||
/**
|
||||
* @brief Sets the pin reference for a specific pin
|
||||
*/
|
||||
void set_pin_ref_for_pin (size_t ppin_id, Net::pin_iterator iter);
|
||||
|
||||
void translate_circuits (const std::map<const Circuit *, Circuit *> &map);
|
||||
void translate_device_classes (const std::map<const DeviceClass *, DeviceClass *> &map);
|
||||
void set_netlist (Netlist *netlist);
|
||||
void invalidate_nets_per_pin ();
|
||||
void validate_nets_per_pin ();
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ static std::string netlist2 (const db::Circuit &c)
|
|||
if (! pins.empty ()) {
|
||||
pins += ",";
|
||||
}
|
||||
const db::Net *net = c.net_for_port (d.operator-> (), i);
|
||||
const db::Net *net = d->net_for_port (i);
|
||||
pins += d->device_class ()->port_definitions () [i].name ();
|
||||
pins += "=";
|
||||
pins += net ? net->name () : std::string ("(null)");
|
||||
|
|
@ -210,7 +210,7 @@ static std::string netlist2 (const db::Circuit &c)
|
|||
}
|
||||
pins += s->circuit ()->pin_by_id (i)->name ();
|
||||
pins += "=";
|
||||
const db::Net *net = c.net_for_pin (s.operator-> (), i);
|
||||
const db::Net *net = s->net_for_pin (i);
|
||||
pins += net ? net->name () : std::string ("(null)");
|
||||
}
|
||||
res += " X" + s->name () + ":" + pins + "\n";
|
||||
|
|
@ -234,6 +234,11 @@ TEST(4_CircuitDevices)
|
|||
|
||||
std::auto_ptr<db::Circuit> c (new db::Circuit ());
|
||||
c->set_name ("c");
|
||||
|
||||
EXPECT_EQ (netlist2 (*c),
|
||||
"c:\n"
|
||||
);
|
||||
|
||||
db::Device *d1 = new db::Device (&dc1, "d1");
|
||||
db::Device *d2a = new db::Device (&dc2, "d2a");
|
||||
db::Device *d2b = new db::Device (&dc2, "d2b");
|
||||
|
|
@ -241,6 +246,13 @@ TEST(4_CircuitDevices)
|
|||
c->add_device (d2a);
|
||||
c->add_device (d2b);
|
||||
|
||||
EXPECT_EQ (netlist2 (*c),
|
||||
"c:\n"
|
||||
" Dd1:S=(null),G=(null),D=(null)\n"
|
||||
" Dd2a:A=(null),B=(null)\n"
|
||||
" Dd2b:A=(null),B=(null)\n"
|
||||
);
|
||||
|
||||
db::Net *n1 = new db::Net ();
|
||||
n1->set_name ("n1");
|
||||
EXPECT_EQ (n1->circuit (), 0);
|
||||
|
|
@ -256,6 +268,13 @@ TEST(4_CircuitDevices)
|
|||
n2->add_port (db::NetPortRef (d2a, 1));
|
||||
n2->add_port (db::NetPortRef (d2b, 0));
|
||||
|
||||
EXPECT_EQ (netlist2 (*c),
|
||||
"c:\n"
|
||||
" Dd1:S=n1,G=n2,D=(null)\n"
|
||||
" Dd2a:A=n1,B=n2\n"
|
||||
" Dd2b:A=n2,B=(null)\n"
|
||||
);
|
||||
|
||||
db::Net *n3 = new db::Net ();
|
||||
n3->set_name ("n3");
|
||||
c->add_net (n3);
|
||||
|
|
@ -349,34 +368,34 @@ TEST(4_NetlistSubcircuits)
|
|||
c1->add_sub_circuit (sc2);
|
||||
|
||||
db::Net *n2a = new db::Net ();
|
||||
c2->add_net (n2a);
|
||||
n2a->set_name ("n2a");
|
||||
n2a->add_pin (db::NetPinRef (0));
|
||||
n2a->add_port (db::NetPortRef (d, 0));
|
||||
c2->add_net (n2a);
|
||||
|
||||
db::Net *n2b = new db::Net ();
|
||||
c2->add_net (n2b);
|
||||
n2b->set_name ("n2b");
|
||||
n2b->add_port (db::NetPortRef (d, 1));
|
||||
n2b->add_pin (db::NetPinRef (1));
|
||||
c2->add_net (n2b);
|
||||
|
||||
db::Net *n1a = new db::Net ();
|
||||
c1->add_net (n1a);
|
||||
n1a->set_name ("n1a");
|
||||
n1a->add_pin (db::NetPinRef (0));
|
||||
n1a->add_pin (db::NetPinRef (0, sc1));
|
||||
c1->add_net (n1a);
|
||||
n1a->add_pin (db::NetPinRef (sc1, 0));
|
||||
|
||||
db::Net *n1b = new db::Net ();
|
||||
n1b->set_name ("n1b");
|
||||
n1b->add_pin (db::NetPinRef (1, sc1));
|
||||
n1b->add_pin (db::NetPinRef (0, sc2));
|
||||
c1->add_net (n1b);
|
||||
n1b->set_name ("n1b");
|
||||
n1b->add_pin (db::NetPinRef (sc1, 1));
|
||||
n1b->add_pin (db::NetPinRef (sc2, 0));
|
||||
|
||||
db::Net *n1c = new db::Net ();
|
||||
n1c->set_name ("n1c");
|
||||
n1c->add_pin (db::NetPinRef (1, sc2));
|
||||
n1c->add_pin (db::NetPinRef (1));
|
||||
c1->add_net (n1c);
|
||||
n1c->set_name ("n1c");
|
||||
n1c->add_pin (db::NetPinRef (sc2, 1));
|
||||
n1c->add_pin (db::NetPinRef (1));
|
||||
|
||||
EXPECT_EQ (nl2string (*nl),
|
||||
"[c1]\n"
|
||||
|
|
@ -396,6 +415,18 @@ TEST(4_NetlistSubcircuits)
|
|||
" DD:A=n2a,B=n2b\n"
|
||||
);
|
||||
|
||||
// check netlist
|
||||
for (db::Netlist::circuit_iterator c = nl->begin_circuits (); c != nl->end_circuits (); ++c) {
|
||||
for (db::Circuit::net_iterator n = c->begin_nets (); n != c->end_nets (); ++n) {
|
||||
for (db::Net::port_iterator i = n->begin_ports (); i != n->end_ports (); ++i) {
|
||||
EXPECT_EQ (i->net (), n.operator-> ());
|
||||
}
|
||||
for (db::Net::pin_iterator i = n->begin_pins (); i != n->end_pins (); ++i) {
|
||||
EXPECT_EQ (i->net (), n.operator-> ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
db::Netlist nl2 = *nl;
|
||||
nl.reset (0);
|
||||
|
||||
|
|
@ -418,6 +449,18 @@ TEST(4_NetlistSubcircuits)
|
|||
"c2:c2p1=n2a,c2p2=n2b\n"
|
||||
" DD:A=n2a,B=n2b\n"
|
||||
);
|
||||
|
||||
// check netlist
|
||||
for (db::Netlist::circuit_iterator c = nl2.begin_circuits (); c != nl2.end_circuits (); ++c) {
|
||||
for (db::Circuit::net_iterator n = c->begin_nets (); n != c->end_nets (); ++n) {
|
||||
for (db::Net::port_iterator i = n->begin_ports (); i != n->end_ports (); ++i) {
|
||||
EXPECT_EQ (i->net (), n.operator-> ());
|
||||
}
|
||||
for (db::Net::pin_iterator i = n->begin_pins (); i != n->end_pins (); ++i) {
|
||||
EXPECT_EQ (i->net (), n.operator-> ());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(5_SubCircuit)
|
||||
|
|
@ -451,3 +494,170 @@ TEST(6_Net)
|
|||
EXPECT_EQ (n.name (), "");
|
||||
EXPECT_EQ (int (n.cluster_id ()), 0);
|
||||
}
|
||||
|
||||
TEST(7_NetPortsEditing)
|
||||
{
|
||||
db::Circuit c;
|
||||
db::GenericDeviceClass dc;
|
||||
dc.add_port_definition (db::DevicePortDefinition ("A", ""));
|
||||
dc.add_port_definition (db::DevicePortDefinition ("B", ""));
|
||||
|
||||
db::Device *d1 = new db::Device (&dc, "D1");
|
||||
c.add_device (d1);
|
||||
db::Device *d2 = new db::Device (&dc, "D2");
|
||||
c.add_device (d2);
|
||||
|
||||
db::Net *n1 = new db::Net ();
|
||||
n1->set_name ("n1");
|
||||
c.add_net (n1);
|
||||
|
||||
db::Net *n2 = new db::Net ();
|
||||
n2->set_name ("n2");
|
||||
c.add_net (n2);
|
||||
|
||||
d1->connect_port (0, n1);
|
||||
d1->connect_port (1, n2);
|
||||
|
||||
d2->connect_port (1, n1);
|
||||
d2->connect_port (0, n2);
|
||||
|
||||
EXPECT_EQ (d1->net_for_port (0), n1);
|
||||
EXPECT_EQ (d1->net_for_port (1), n2);
|
||||
EXPECT_EQ (d2->net_for_port (0), n2);
|
||||
EXPECT_EQ (d2->net_for_port (1), n1);
|
||||
|
||||
EXPECT_EQ (net2string (*n1, &c), "D1:A,D2:B");
|
||||
EXPECT_EQ (net2string (*n2, &c), "D1:B,D2:A");
|
||||
|
||||
d1->connect_port (0, n2);
|
||||
d1->connect_port (1, n1);
|
||||
|
||||
EXPECT_EQ (d1->net_for_port (0), n2);
|
||||
EXPECT_EQ (d1->net_for_port (1), n1);
|
||||
|
||||
EXPECT_EQ (net2string (*n1, &c), "D2:B,D1:B");
|
||||
EXPECT_EQ (net2string (*n2, &c), "D2:A,D1:A");
|
||||
|
||||
d1->connect_port (0, 0);
|
||||
EXPECT_EQ (d1->net_for_port (0), 0);
|
||||
|
||||
EXPECT_EQ (net2string (*n1, &c), "D2:B,D1:B");
|
||||
EXPECT_EQ (net2string (*n2, &c), "D2:A");
|
||||
|
||||
delete d1;
|
||||
d1 = 0;
|
||||
|
||||
EXPECT_EQ (c.begin_devices ()->name (), "D2");
|
||||
EXPECT_EQ (++c.begin_devices () == c.end_devices (), true);
|
||||
|
||||
EXPECT_EQ (net2string (*n1, &c), "D2:B");
|
||||
EXPECT_EQ (net2string (*n2, &c), "D2:A");
|
||||
|
||||
delete n1;
|
||||
n1 = 0;
|
||||
|
||||
EXPECT_EQ (c.begin_nets ()->name (), "n2");
|
||||
EXPECT_EQ (++c.begin_nets () == c.end_nets (), true);
|
||||
|
||||
EXPECT_EQ (net2string (*n2, &c), "D2:A");
|
||||
|
||||
EXPECT_EQ (d2->net_for_port (0), n2);
|
||||
EXPECT_EQ (d2->net_for_port (1), 0);
|
||||
}
|
||||
|
||||
TEST(8_NetSubCircuitsEditing)
|
||||
{
|
||||
db::Circuit c;
|
||||
c.set_name ("c");
|
||||
c.add_pin (db::Pin ("X"));
|
||||
c.add_pin (db::Pin ("Y"));
|
||||
|
||||
db::Circuit cc1;
|
||||
cc1.set_name ("sc1");
|
||||
cc1.add_pin (db::Pin ("A"));
|
||||
cc1.add_pin (db::Pin ("B"));
|
||||
|
||||
db::Circuit cc2;
|
||||
cc2.set_name ("sc2");
|
||||
cc2.add_pin (db::Pin ("A"));
|
||||
cc2.add_pin (db::Pin ("B"));
|
||||
|
||||
db::SubCircuit *sc1 = new db::SubCircuit (&cc1, "sc1");
|
||||
c.add_sub_circuit (sc1);
|
||||
|
||||
db::SubCircuit *sc2 = new db::SubCircuit (&cc2, "sc2");
|
||||
c.add_sub_circuit (sc2);
|
||||
|
||||
db::Net *n1 = new db::Net ();
|
||||
n1->set_name ("n1");
|
||||
c.add_net (n1);
|
||||
|
||||
db::Net *n2 = new db::Net ();
|
||||
n2->set_name ("n2");
|
||||
c.add_net (n2);
|
||||
|
||||
c.connect_pin (0, n1);
|
||||
EXPECT_EQ (c.net_for_pin (0), n1);
|
||||
EXPECT_EQ (c.net_for_pin (1), 0);
|
||||
|
||||
sc1->connect_pin (0, n1);
|
||||
sc1->connect_pin (1, n2);
|
||||
|
||||
sc2->connect_pin (1, n1);
|
||||
sc2->connect_pin (0, n2);
|
||||
|
||||
EXPECT_EQ (sc1->net_for_pin (0), n1);
|
||||
EXPECT_EQ (sc1->net_for_pin (1), n2);
|
||||
EXPECT_EQ (sc2->net_for_pin (0), n2);
|
||||
EXPECT_EQ (sc2->net_for_pin (1), n1);
|
||||
|
||||
EXPECT_EQ (net2string (*n1, &c), "+X,sc1:A,sc2:B");
|
||||
EXPECT_EQ (net2string (*n2, &c), "sc1:B,sc2:A");
|
||||
|
||||
c.connect_pin (0, 0);
|
||||
EXPECT_EQ (c.net_for_pin (0), 0);
|
||||
|
||||
EXPECT_EQ (net2string (*n1, &c), "sc1:A,sc2:B");
|
||||
EXPECT_EQ (net2string (*n2, &c), "sc1:B,sc2:A");
|
||||
|
||||
sc1->connect_pin (0, n2);
|
||||
sc1->connect_pin (1, n1);
|
||||
|
||||
EXPECT_EQ (sc1->net_for_pin (0), n2);
|
||||
EXPECT_EQ (sc1->net_for_pin (1), n1);
|
||||
|
||||
EXPECT_EQ (net2string (*n1, &c), "sc2:B,sc1:B");
|
||||
EXPECT_EQ (net2string (*n2, &c), "sc2:A,sc1:A");
|
||||
|
||||
sc1->connect_pin (0, 0);
|
||||
EXPECT_EQ (sc1->net_for_pin (0), 0);
|
||||
|
||||
EXPECT_EQ (net2string (*n1, &c), "sc2:B,sc1:B");
|
||||
EXPECT_EQ (net2string (*n2, &c), "sc2:A");
|
||||
|
||||
delete sc1;
|
||||
sc1 = 0;
|
||||
|
||||
EXPECT_EQ (c.begin_sub_circuits ()->name (), "sc2");
|
||||
EXPECT_EQ (++c.begin_sub_circuits () == c.end_sub_circuits (), true);
|
||||
|
||||
EXPECT_EQ (net2string (*n1, &c), "sc2:B");
|
||||
EXPECT_EQ (net2string (*n2, &c), "sc2:A");
|
||||
|
||||
c.connect_pin (1, n1);
|
||||
EXPECT_EQ (net2string (*n1, &c), "sc2:B,+Y");
|
||||
EXPECT_EQ (c.net_for_pin (1), n1);
|
||||
|
||||
delete n1;
|
||||
n1 = 0;
|
||||
|
||||
EXPECT_EQ (c.net_for_pin (1), 0);
|
||||
|
||||
EXPECT_EQ (c.begin_nets ()->name (), "n2");
|
||||
EXPECT_EQ (++c.begin_nets () == c.end_nets (), true);
|
||||
|
||||
EXPECT_EQ (net2string (*n2, &c), "sc2:A");
|
||||
|
||||
EXPECT_EQ (sc2->net_for_pin (0), n2);
|
||||
EXPECT_EQ (sc2->net_for_pin (1), 0);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue