mirror of https://github.com/KLayout/klayout.git
Dual netlist representation (nets attached to pins and ports).
This commit is contained in:
parent
654afa3ec2
commit
e51a3a9ed9
|
|
@ -43,17 +43,66 @@ Pin::Pin (const std::string &name)
|
|||
// --------------------------------------------------------------------------------
|
||||
// Device class implementation
|
||||
|
||||
Device::Device ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
Device::Device (DeviceClass *device_class, const std::string &name)
|
||||
: m_device_class (device_class), m_name (name)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
Device::Device (const Device &other)
|
||||
{
|
||||
operator= (other);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void Device::set_name (const std::string &n)
|
||||
{
|
||||
m_name = n;
|
||||
}
|
||||
|
||||
void Device::clear_nets_per_port ()
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
// SubCircuit class implementation
|
||||
|
||||
|
|
@ -68,6 +117,22 @@ SubCircuit::SubCircuit (Circuit *circuit, const std::string &name)
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
SubCircuit::SubCircuit (const SubCircuit &other)
|
||||
{
|
||||
operator= (other);
|
||||
}
|
||||
|
||||
SubCircuit &SubCircuit::operator= (const SubCircuit &other)
|
||||
{
|
||||
if (this != &other) {
|
||||
m_name = other.m_name;
|
||||
m_circuit = other.m_circuit;
|
||||
m_trans = other.m_trans;
|
||||
m_nets_per_pin.clear ();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SubCircuit::set_name (const std::string &n)
|
||||
{
|
||||
m_name = n;
|
||||
|
|
@ -78,6 +143,35 @@ void SubCircuit::set_trans (const db::DCplxTrans &t)
|
|||
m_trans = t;
|
||||
}
|
||||
|
||||
void SubCircuit::clear_nets_per_pin ()
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
// NetPortRef class implementation
|
||||
|
||||
|
|
@ -188,11 +282,17 @@ 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 ();
|
||||
}
|
||||
}
|
||||
|
||||
void Net::add_port (const NetPortRef &port)
|
||||
{
|
||||
m_ports.push_back (port);
|
||||
if (mp_circuit) {
|
||||
mp_circuit->invalidate_nets_per_pin ();
|
||||
}
|
||||
}
|
||||
|
||||
void Net::translate_devices (const std::map<const Device *, Device *> &map)
|
||||
|
|
@ -224,13 +324,13 @@ void Net::set_circuit (Circuit *circuit)
|
|||
// Circuit class implementation
|
||||
|
||||
Circuit::Circuit ()
|
||||
: mp_netlist (0)
|
||||
: mp_netlist (0), m_nets_per_pin_valid (false)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
Circuit::Circuit (const Circuit &other)
|
||||
: mp_netlist (0)
|
||||
: mp_netlist (0), m_nets_per_pin_valid (false)
|
||||
{
|
||||
operator= (other);
|
||||
}
|
||||
|
|
@ -240,6 +340,9 @@ 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);
|
||||
|
|
@ -291,6 +394,7 @@ 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)
|
||||
|
|
@ -307,37 +411,44 @@ 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)
|
||||
|
|
@ -358,6 +469,87 @@ void Circuit::translate_device_classes (const std::map<const DeviceClass *, Devi
|
|||
}
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
const Net *Circuit::net_for_pin (const SubCircuit *sub_circuit, size_t pin_id) const
|
||||
{
|
||||
if (! m_nets_per_pin_valid) {
|
||||
const_cast<Circuit *> (this)->validate_nets_per_pin ();
|
||||
}
|
||||
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 ();
|
||||
}
|
||||
|
||||
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 ();
|
||||
}
|
||||
|
||||
for (device_iterator i = begin_devices (); i != end_devices (); ++i) {
|
||||
i->reserve_nets_per_port ();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
// DeviceClass class implementation
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ class Device;
|
|||
class DeviceClass;
|
||||
class DevicePortDefinition;
|
||||
class Netlist;
|
||||
class Net;
|
||||
/**
|
||||
* @brief The definition of a pin of a circuit
|
||||
*
|
||||
|
|
@ -102,11 +103,28 @@ 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
|
||||
*/
|
||||
|
|
@ -133,6 +151,12 @@ private:
|
|||
|
||||
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
|
||||
|
|
@ -152,11 +176,23 @@ 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
|
||||
*/
|
||||
|
|
@ -216,6 +252,12 @@ private:
|
|||
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
|
||||
|
|
@ -524,6 +566,7 @@ 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
|
||||
|
|
@ -600,11 +643,6 @@ public:
|
|||
*/
|
||||
void add_pin (const Pin &pin);
|
||||
|
||||
/**
|
||||
* @brief Deletes a pin from the circuit
|
||||
*/
|
||||
void remove_pin (Pin *pin);
|
||||
|
||||
/**
|
||||
* @brief Begin iterator for the pins of the circuit (non-const version)
|
||||
*/
|
||||
|
|
@ -621,6 +659,14 @@ public:
|
|||
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)
|
||||
*/
|
||||
|
|
@ -774,8 +820,52 @@ public:
|
|||
return m_sub_circuits.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 Gets the net for a given pin of a subcircuit
|
||||
*/
|
||||
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));
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Netlist;
|
||||
friend class Net;
|
||||
|
||||
std::string m_name;
|
||||
db::cell_index_type m_cell_index;
|
||||
|
|
@ -784,10 +874,14 @@ 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;
|
||||
|
||||
void translate_circuits (const std::map<const Circuit *, Circuit *> &map);
|
||||
void translate_device_classes (const std::map<const db::DeviceClass *, db::DeviceClass *> &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 ();
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -164,6 +164,61 @@ static std::string nets2string (const db::Circuit &c)
|
|||
return res;
|
||||
}
|
||||
|
||||
// dual form of netlist
|
||||
static std::string netlist2 (const db::Circuit &c)
|
||||
{
|
||||
std::string res;
|
||||
|
||||
std::string pins;
|
||||
for (db::Circuit::const_pin_iterator p = c.begin_pins (); p != c.end_pins (); ++p) {
|
||||
if (! pins.empty ()) {
|
||||
pins += ",";
|
||||
}
|
||||
const db::Net *net = c.net_for_pin (p->id ());
|
||||
pins += p->name ();
|
||||
pins += "=";
|
||||
pins += net ? net->name () : std::string ("(null)");
|
||||
}
|
||||
|
||||
res += c.name () + ":" + pins + "\n";
|
||||
|
||||
for (db::Circuit::const_device_iterator d = c.begin_devices (); d != c.end_devices (); ++d) {
|
||||
if (! d->device_class ()) {
|
||||
continue;
|
||||
}
|
||||
pins.clear ();
|
||||
for (size_t i = 0; i < d->device_class ()->port_definitions ().size (); ++i) {
|
||||
if (! pins.empty ()) {
|
||||
pins += ",";
|
||||
}
|
||||
const db::Net *net = c.net_for_port (d.operator-> (), i);
|
||||
pins += d->device_class ()->port_definitions () [i].name ();
|
||||
pins += "=";
|
||||
pins += net ? net->name () : std::string ("(null)");
|
||||
}
|
||||
res += " D" + d->name () + ":" + pins + "\n";
|
||||
}
|
||||
|
||||
for (db::Circuit::const_sub_circuit_iterator s = c.begin_sub_circuits (); s != c.end_sub_circuits (); ++s) {
|
||||
if (! s->circuit ()) {
|
||||
continue;
|
||||
}
|
||||
pins.clear ();
|
||||
for (size_t i = 0; i < s->circuit ()->pin_count (); ++i) {
|
||||
if (! pins.empty ()) {
|
||||
pins += ",";
|
||||
}
|
||||
pins += s->circuit ()->pin_by_id (i)->name ();
|
||||
pins += "=";
|
||||
const db::Net *net = c.net_for_pin (s.operator-> (), i);
|
||||
pins += net ? net->name () : std::string ("(null)");
|
||||
}
|
||||
res += " X" + s->name () + ":" + pins + "\n";
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
TEST(4_CircuitDevices)
|
||||
{
|
||||
db::GenericDeviceClass dc1;
|
||||
|
|
@ -178,6 +233,7 @@ TEST(4_CircuitDevices)
|
|||
dc2.add_port_definition (db::DevicePortDefinition ("B", ""));
|
||||
|
||||
std::auto_ptr<db::Circuit> c (new db::Circuit ());
|
||||
c->set_name ("c");
|
||||
db::Device *d1 = new db::Device (&dc1, "d1");
|
||||
db::Device *d2a = new db::Device (&dc2, "d2a");
|
||||
db::Device *d2b = new db::Device (&dc2, "d2b");
|
||||
|
|
@ -186,6 +242,7 @@ TEST(4_CircuitDevices)
|
|||
c->add_device (d2b);
|
||||
|
||||
db::Net *n1 = new db::Net ();
|
||||
n1->set_name ("n1");
|
||||
EXPECT_EQ (n1->circuit (), 0);
|
||||
c->add_net (n1);
|
||||
n1->add_port (db::NetPortRef (d1, 0));
|
||||
|
|
@ -193,12 +250,14 @@ TEST(4_CircuitDevices)
|
|||
EXPECT_EQ (n1->circuit (), c.get ());
|
||||
|
||||
db::Net *n2 = new db::Net ();
|
||||
n2->set_name ("n2");
|
||||
c->add_net (n2);
|
||||
n2->add_port (db::NetPortRef (d1, 1));
|
||||
n2->add_port (db::NetPortRef (d2a, 1));
|
||||
n2->add_port (db::NetPortRef (d2b, 0));
|
||||
|
||||
db::Net *n3 = new db::Net ();
|
||||
n3->set_name ("n3");
|
||||
c->add_net (n3);
|
||||
n3->add_port (db::NetPortRef (d1, 2));
|
||||
n3->add_port (db::NetPortRef (d2b, 1));
|
||||
|
|
@ -209,6 +268,13 @@ TEST(4_CircuitDevices)
|
|||
"d1:D,d2b:B\n"
|
||||
);
|
||||
|
||||
EXPECT_EQ (netlist2 (*c),
|
||||
"c:\n"
|
||||
" Dd1:S=n1,G=n2,D=n3\n"
|
||||
" Dd2a:A=n1,B=n2\n"
|
||||
" Dd2b:A=n2,B=n3\n"
|
||||
);
|
||||
|
||||
db::Circuit cc = *c;
|
||||
c.reset (0);
|
||||
EXPECT_EQ (cc.begin_nets ()->circuit (), &cc);
|
||||
|
|
@ -218,9 +284,16 @@ TEST(4_CircuitDevices)
|
|||
"d1:G,d2a:B,d2b:A\n"
|
||||
"d1:D,d2b:B\n"
|
||||
);
|
||||
|
||||
EXPECT_EQ (netlist2 (cc),
|
||||
"c:\n"
|
||||
" Dd1:S=n1,G=n2,D=n3\n"
|
||||
" Dd2a:A=n1,B=n2\n"
|
||||
" Dd2b:A=n2,B=n3\n"
|
||||
);
|
||||
}
|
||||
|
||||
static std::string netlist2string (const db::Netlist &nl)
|
||||
static std::string nl2string (const db::Netlist &nl)
|
||||
{
|
||||
std::string res;
|
||||
for (db::Netlist::const_circuit_iterator c = nl.begin_circuits (); c != nl.end_circuits (); ++c) {
|
||||
|
|
@ -230,6 +303,16 @@ static std::string netlist2string (const db::Netlist &nl)
|
|||
return res;
|
||||
}
|
||||
|
||||
// dual form of netlist
|
||||
static std::string netlist2 (const db::Netlist &nl)
|
||||
{
|
||||
std::string res;
|
||||
for (db::Netlist::const_circuit_iterator c = nl.begin_circuits (); c != nl.end_circuits (); ++c) {
|
||||
res += netlist2 (*c);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
TEST(4_NetlistSubcircuits)
|
||||
{
|
||||
std::auto_ptr<db::Netlist> nl (new db::Netlist ());
|
||||
|
|
@ -258,37 +341,44 @@ TEST(4_NetlistSubcircuits)
|
|||
c2->add_device (d);
|
||||
|
||||
db::SubCircuit *sc1 = new db::SubCircuit (c2);
|
||||
sc1->set_name ("sc1");
|
||||
c1->add_sub_circuit (sc1);
|
||||
|
||||
db::SubCircuit *sc2 = new db::SubCircuit (c2);
|
||||
sc2->set_name ("sc2");
|
||||
c1->add_sub_circuit (sc2);
|
||||
|
||||
db::Net *n2a = new db::Net ();
|
||||
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 ();
|
||||
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 ();
|
||||
n1a->set_name ("n1a");
|
||||
n1a->add_pin (db::NetPinRef (0));
|
||||
n1a->add_pin (db::NetPinRef (0, sc1));
|
||||
c1->add_net (n1a);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
EXPECT_EQ (netlist2string (*nl),
|
||||
EXPECT_EQ (nl2string (*nl),
|
||||
"[c1]\n"
|
||||
"+c1p1,c2:c2p1\n"
|
||||
"c2:c2p2,c2:c2p1\n"
|
||||
|
|
@ -298,12 +388,20 @@ TEST(4_NetlistSubcircuits)
|
|||
"D:B,+c2p2\n"
|
||||
);
|
||||
|
||||
EXPECT_EQ (netlist2 (*nl),
|
||||
"c1:c1p1=n1a,c1p2=n1c\n"
|
||||
" Xsc1:c2p1=n1a,c2p2=n1b\n"
|
||||
" Xsc2:c2p1=n1b,c2p2=n1c\n"
|
||||
"c2:c2p1=n2a,c2p2=n2b\n"
|
||||
" DD:A=n2a,B=n2b\n"
|
||||
);
|
||||
|
||||
db::Netlist nl2 = *nl;
|
||||
nl.reset (0);
|
||||
|
||||
EXPECT_EQ (nl2.begin_circuits ()->netlist (), &nl2);
|
||||
|
||||
EXPECT_EQ (netlist2string (nl2),
|
||||
EXPECT_EQ (nl2string (nl2),
|
||||
"[c1]\n"
|
||||
"+c1p1,c2:c2p1\n"
|
||||
"c2:c2p2,c2:c2p1\n"
|
||||
|
|
@ -312,6 +410,14 @@ TEST(4_NetlistSubcircuits)
|
|||
"D:A,+c2p1\n"
|
||||
"D:B,+c2p2\n"
|
||||
);
|
||||
|
||||
EXPECT_EQ (netlist2 (nl2),
|
||||
"c1:c1p1=n1a,c1p2=n1c\n"
|
||||
" Xsc1:c2p1=n1a,c2p2=n1b\n"
|
||||
" Xsc2:c2p1=n1b,c2p2=n1c\n"
|
||||
"c2:c2p1=n2a,c2p2=n2b\n"
|
||||
" DD:A=n2a,B=n2b\n"
|
||||
);
|
||||
}
|
||||
|
||||
TEST(5_SubCircuit)
|
||||
|
|
|
|||
Loading…
Reference in New Issue