diff --git a/src/db/db/dbLayoutToNetlistReader.cc b/src/db/db/dbLayoutToNetlistReader.cc index 47d56f2f4..52a2bfb6e 100644 --- a/src/db/db/dbLayoutToNetlistReader.cc +++ b/src/db/db/dbLayoutToNetlistReader.cc @@ -111,6 +111,7 @@ LayoutToNetlistStandardReader::read_double () bool LayoutToNetlistStandardReader::at_end () { + skip (); return (m_ex.at_end () && m_stream.at_end ()); } @@ -129,7 +130,7 @@ LayoutToNetlistStandardReader::skip () void LayoutToNetlistStandardReader::read (db::LayoutToNetlist *l2n) { try { - do_read (l2n); + do_read (0, l2n); } catch (tl::Exception &ex) { throw tl::Exception (tl::sprintf (tl::to_string (tr ("%s in line: %d of %s")), ex.msg (), m_stream.line_number (), m_path)); } @@ -144,20 +145,28 @@ static db::Region &layer_by_name (db::LayoutToNetlist *l2n, const std::string &n return *l; } -void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n, bool nested) +void LayoutToNetlistStandardReader::do_read (db::Netlist *netlist, db::LayoutToNetlist *l2n, bool nested, std::map > *id2net_per_circuit) { int version = 0; std::string description; - tl_assert (l2n->internal_layout ()); - l2n->internal_layout ()->dbu (1.0); // mainly for testing + if (l2n) { - if (l2n->internal_layout ()->cells () == 0) { - l2n->internal_layout ()->add_cell ("TOP"); + tl_assert (netlist == 0); + + tl_assert (l2n->internal_layout ()); + l2n->internal_layout ()->dbu (1.0); // mainly for testing + + if (l2n->internal_layout ()->cells () == 0) { + l2n->internal_layout ()->add_cell ("TOP"); + } + tl_assert (l2n->internal_top_cell () != 0); + + netlist = l2n->make_netlist (); + + } else { + tl_assert (netlist != 0); } - tl_assert (l2n->internal_top_cell () != 0); - - l2n->make_netlist (); while (! at_end ()) { @@ -173,14 +182,14 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n, bool nest read_word_or_quoted (description); br.done (); - } else if (test (skeys::unit_key) || test (lkeys::unit_key)) { + } else if (l2n && (test (skeys::unit_key) || test (lkeys::unit_key))) { Brace br (this); double dbu = read_double (); l2n->internal_layout ()->dbu (dbu); br.done (); - } else if (test (skeys::top_key) || test (lkeys::top_key)) { + } else if (l2n && (test (skeys::top_key) || test (lkeys::top_key))) { Brace br (this); std::string top; @@ -188,7 +197,7 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n, bool nest l2n->internal_layout ()->rename_cell (l2n->internal_top_cell ()->cell_index (), top.c_str ()); br.done (); - } else if (test (skeys::layer_key) || test (lkeys::layer_key)) { + } else if (l2n && (test (skeys::layer_key) || test (lkeys::layer_key))) { Brace br (this); std::string layer, lspec; @@ -216,7 +225,7 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n, bool nest read_word_or_quoted (templ_name); br.done (); - if (l2n->netlist ()->device_class_by_name (class_name) != 0) { + if (netlist->device_class_by_name (class_name) != 0) { throw tl::Exception (tl::to_string (tr ("Device class must be defined before being used in device"))); } @@ -227,9 +236,9 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n, bool nest db::DeviceClass *dc = dct->create (); dc->set_name (class_name); - l2n->netlist ()->add_device_class (dc); + netlist->add_device_class (dc); - } else if (test (skeys::connect_key) || test (lkeys::connect_key)) { + } else if (l2n && (test (skeys::connect_key) || test (lkeys::connect_key))) { Brace br (this); std::string l1; @@ -241,7 +250,7 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n, bool nest } br.done (); - } else if (test (skeys::global_key) || test (lkeys::global_key)) { + } else if (l2n && (test (skeys::global_key) || test (lkeys::global_key))) { Brace br (this); std::string l1; @@ -261,26 +270,36 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n, bool nest db::Circuit *circuit = new db::Circuit (); circuit->set_name (name); - l2n->netlist ()->add_circuit (circuit); + netlist->add_circuit (circuit); - db::Layout *ly = l2n->internal_layout (); - std::pair ci_old = ly->cell_by_name (name.c_str ()); - db::cell_index_type ci = ci_old.first ? ci_old.second : ly->add_cell (name.c_str ()); - circuit->set_cell_index (ci); + db::cell_index_type device_cell_index = 0; + + if (l2n) { + + db::Layout *ly = l2n->internal_layout (); + std::pair ci_old = ly->cell_by_name (name.c_str ()); + device_cell_index = ci_old.first ? ci_old.second : ly->add_cell (name.c_str ()); + circuit->set_cell_index (device_cell_index); + + } std::map > connections; - std::map id2net; + std::map id2net_local; + std::map *id2net = &id2net_local; + if (id2net_per_circuit) { + id2net = &(*id2net_per_circuit)[circuit]; + } while (br) { if (test (skeys::net_key) || test (lkeys::net_key)) { - read_net (l2n, circuit, id2net); + read_net (netlist, l2n, circuit, *id2net); } else if (test (skeys::pin_key) || test (lkeys::pin_key)) { - read_pin (l2n, circuit, id2net); + read_pin (netlist, l2n, circuit, *id2net); } else if (test (skeys::device_key) || test (lkeys::device_key)) { - read_device (l2n, circuit, id2net, connections); + read_device (netlist, l2n, circuit, *id2net, connections); } else if (test (skeys::circuit_key) || test (lkeys::circuit_key)) { - read_subcircuit (l2n, circuit, id2net, connections); + read_subcircuit (netlist, l2n, circuit, *id2net, connections); } else { throw tl::Exception (tl::to_string (tr ("Invalid keyword inside circuit definition (net, pin, device or circuit expected)"))); } @@ -288,17 +307,22 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n, bool nest } br.done (); - db::Cell &ccell = ly->cell (ci); + if (l2n) { - // connections needs to be made after the instances (because in a readonly Instances container - // the Instance pointers will invalidate when new instances are added) - for (db::Cell::const_iterator i = ccell.begin (); ! i.at_end (); ++i) { - std::map >::const_iterator c = connections.find (i->cell_inst ()); - if (c != connections.end ()) { - for (std::list::const_iterator j = c->second.begin (); j != c->second.end (); ++j) { - l2n->net_clusters ().clusters_per_cell (ci).add_connection (j->from_cluster, db::ClusterInstance (j->to_cluster, i->cell_index (), i->complex_trans (), i->prop_id ())); + db::Layout *ly = l2n->internal_layout (); + db::Cell &ccell = ly->cell (device_cell_index); + + // connections needs to be made after the instances (because in a readonly Instances container + // the Instance pointers will invalidate when new instances are added) + for (db::Cell::const_iterator i = ccell.begin (); ! i.at_end (); ++i) { + std::map >::const_iterator c = connections.find (i->cell_inst ()); + if (c != connections.end ()) { + for (std::list::const_iterator j = c->second.begin (); j != c->second.end (); ++j) { + l2n->net_clusters ().clusters_per_cell (device_cell_index).add_connection (j->from_cluster, db::ClusterInstance (j->to_cluster, i->cell_index (), i->complex_trans (), i->prop_id ())); + } } } + } } else if (test (skeys::device_key) || test (lkeys::device_key)) { @@ -309,22 +333,24 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n, bool nest db::DeviceAbstract *dm = new db::DeviceAbstract (); dm->set_name (name); - l2n->netlist ()->add_device_abstract (dm); + netlist->add_device_abstract (dm); - db::cell_index_type ci = l2n->internal_layout ()->add_cell (name.c_str ()); - dm->set_cell_index (ci); + if (l2n) { + db::cell_index_type ci = l2n->internal_layout ()->add_cell (name.c_str ()); + dm->set_cell_index (ci); + } std::string cls; read_word_or_quoted (cls); - db::DeviceClass *dc = l2n->netlist ()->device_class_by_name (cls); + db::DeviceClass *dc = netlist->device_class_by_name (cls); // use a generic device class unless the right one is registered already. bool gen_dc = (dc == 0); if (gen_dc) { dc = new db::DeviceClass (); dc->set_name (cls); - l2n->netlist ()->add_device_class (dc); + netlist->add_device_class (dc); } dm->set_device_class (dc); @@ -349,7 +375,9 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n, bool nest } - l2n->set_netlist_extracted (); + if (l2n) { + l2n->set_netlist_extracted (); + } } db::Point @@ -429,7 +457,7 @@ LayoutToNetlistStandardReader::read_geometries (Brace &br, db::LayoutToNetlist * } void -LayoutToNetlistStandardReader::read_net (db::LayoutToNetlist *l2n, db::Circuit *circuit, std::map &id2net) +LayoutToNetlistStandardReader::read_net (db::Netlist * /*netlist*/, db::LayoutToNetlist *l2n, db::Circuit *circuit, std::map &id2net) { Brace br (this); @@ -448,18 +476,22 @@ LayoutToNetlistStandardReader::read_net (db::LayoutToNetlist *l2n, db::Circuit * id2net.insert (std::make_pair (id, net)); - db::connected_clusters &cc = l2n->net_clusters ().clusters_per_cell (circuit->cell_index ()); - db::local_cluster &lc = *cc.insert (); - net->set_cluster_id (lc.id ()); + if (l2n) { - db::Cell &cell = l2n->internal_layout ()->cell (circuit->cell_index ()); - read_geometries (br, l2n, lc, cell); + db::connected_clusters &cc = l2n->net_clusters ().clusters_per_cell (circuit->cell_index ()); + db::local_cluster &lc = *cc.insert (); + net->set_cluster_id (lc.id ()); + + db::Cell &cell = l2n->internal_layout ()->cell (circuit->cell_index ()); + read_geometries (br, l2n, lc, cell); + + } br.done (); } void -LayoutToNetlistStandardReader::read_pin (db::LayoutToNetlist * /*l2n*/, db::Circuit *circuit, std::map &id2net) +LayoutToNetlistStandardReader::read_pin (db::Netlist * /*netlist*/, db::LayoutToNetlist * /*l2n*/, db::Circuit *circuit, std::map &id2net) { Brace br (this); std::string name; @@ -503,7 +535,7 @@ LayoutToNetlistStandardReader::device_model_by_name (db::Netlist *netlist, const } void -LayoutToNetlistStandardReader::read_device (db::LayoutToNetlist *l2n, db::Circuit *circuit, std::map &id2net, std::map > &connections) +LayoutToNetlistStandardReader::read_device (db::Netlist *netlist, db::LayoutToNetlist *l2n, db::Circuit *circuit, std::map &id2net, std::map > &connections) { Brace br (this); @@ -513,7 +545,7 @@ LayoutToNetlistStandardReader::read_device (db::LayoutToNetlist *l2n, db::Circui std::string dmname; read_word_or_quoted (dmname); - db::DeviceAbstract *dm = device_model_by_name (l2n->netlist (), dmname); + db::DeviceAbstract *dm = device_model_by_name (netlist, dmname); db::Device *device = new db::Device (); device->set_device_class (const_cast (dm->device_class ())); @@ -549,7 +581,7 @@ LayoutToNetlistStandardReader::read_device (db::LayoutToNetlist *l2n, db::Circui br2.done (); - db::DeviceAbstract *da = device_model_by_name (l2n->netlist (), n); + db::DeviceAbstract *da = device_model_by_name (netlist, n); device->other_abstracts ().push_back (db::DeviceAbstractRef (da, db::DVector (dbu * dx, dbu * dy))); @@ -628,53 +660,57 @@ LayoutToNetlistStandardReader::read_device (db::LayoutToNetlist *l2n, db::Circui br.done (); - db::Cell &ccell = l2n->internal_layout ()->cell (circuit->cell_index ()); + if (l2n) { - // make device cell instances - std::vector insts; + db::Cell &ccell = l2n->internal_layout ()->cell (circuit->cell_index ()); - db::CellInstArray inst (db::CellInst (dm->cell_index ()), db::Trans (db::Vector (x, y))); - ccell.insert (inst); - insts.push_back (inst); + // make device cell instances + std::vector insts; - const std::vector &other_devices = device->other_abstracts (); - for (std::vector::const_iterator i = other_devices.begin (); i != other_devices.end (); ++i) { + db::CellInstArray inst (db::CellInst (dm->cell_index ()), db::Trans (db::Vector (x, y))); + ccell.insert (inst); + insts.push_back (inst); - db::CellInstArray other_inst (db::CellInst (i->device_abstract->cell_index ()), db::Trans (db::Vector (x, y) + dbu_inv * i->offset)); - ccell.insert (other_inst); - insts.push_back (other_inst); + const std::vector &other_devices = device->other_abstracts (); + for (std::vector::const_iterator i = other_devices.begin (); i != other_devices.end (); ++i) { - } + db::CellInstArray other_inst (db::CellInst (i->device_abstract->cell_index ()), db::Trans (db::Vector (x, y) + dbu_inv * i->offset)); + ccell.insert (other_inst); + insts.push_back (other_inst); - // register cluster collections to be made later - - for (size_t tid = 0; tid < max_tid; ++tid) { - - const db::Net *net = device->net_for_terminal (tid); - if (! net) { - continue; } - if (! device->reconnected_terminals ().empty ()) { + // register cluster collections to be made later - const std::vector *tr = device->reconnected_terminals_for (tid); - if (tr) { - - for (std::vector::const_iterator i = tr->begin (); i != tr->end (); ++i) { - const db::DeviceAbstract *da = dm; - if (i->device_index > 0) { - da = device->other_abstracts () [i->device_index - 1].device_abstract; - } - Connections ref (net->cluster_id (), da->cluster_id_for_terminal (i->other_terminal_id)); - connections [insts [i->device_index]].push_back (ref); - } + for (size_t tid = 0; tid < max_tid; ++tid) { + const db::Net *net = device->net_for_terminal (tid); + if (! net) { + continue; } - } else { + if (! device->reconnected_terminals ().empty ()) { - Connections ref (net->cluster_id (), dm->cluster_id_for_terminal (tid)); - connections [insts [0]].push_back (ref); + const std::vector *tr = device->reconnected_terminals_for (tid); + if (tr) { + + for (std::vector::const_iterator i = tr->begin (); i != tr->end (); ++i) { + const db::DeviceAbstract *da = dm; + if (i->device_index > 0) { + da = device->other_abstracts () [i->device_index - 1].device_abstract; + } + Connections ref (net->cluster_id (), da->cluster_id_for_terminal (i->other_terminal_id)); + connections [insts [i->device_index]].push_back (ref); + } + + } + + } else { + + Connections ref (net->cluster_id (), dm->cluster_id_for_terminal (tid)); + connections [insts [0]].push_back (ref); + + } } @@ -682,7 +718,7 @@ LayoutToNetlistStandardReader::read_device (db::LayoutToNetlist *l2n, db::Circui } void -LayoutToNetlistStandardReader::read_subcircuit (db::LayoutToNetlist *l2n, db::Circuit *circuit, std::map &id2net, std::map > &connections) +LayoutToNetlistStandardReader::read_subcircuit (db::Netlist *netlist, db::LayoutToNetlist *l2n, db::Circuit *circuit, std::map &id2net, std::map > &connections) { Brace br (this); @@ -694,7 +730,7 @@ LayoutToNetlistStandardReader::read_subcircuit (db::LayoutToNetlist *l2n, db::Ci std::string xname; read_word_or_quoted (xname); - db::Circuit *circuit_ref = l2n->netlist ()->circuit_by_name (xname); + db::Circuit *circuit_ref = netlist->circuit_by_name (xname); if (! circuit_ref) { throw tl::Exception (tl::to_string (tr ("Not a valid device circuit name: ")) + xname); } @@ -783,14 +819,18 @@ LayoutToNetlistStandardReader::read_subcircuit (db::LayoutToNetlist *l2n, db::Ci br.done (); - double dbu = l2n->internal_layout ()->dbu (); - subcircuit->set_trans (db::DCplxTrans (mag, angle, mirror, db::DVector (dbu * x, dbu * y))); + if (l2n) { - db::CellInstArray inst (db::CellInst (circuit_ref->cell_index ()), db::ICplxTrans (mag, angle, mirror, db::Vector (x, y))); - db::Cell &ccell = l2n->internal_layout ()->cell (circuit->cell_index ()); - ccell.insert (inst); + double dbu = l2n->internal_layout ()->dbu (); + subcircuit->set_trans (db::DCplxTrans (mag, angle, mirror, db::DVector (dbu * x, dbu * y))); - connections [inst] = refs; + db::CellInstArray inst (db::CellInst (circuit_ref->cell_index ()), db::ICplxTrans (mag, angle, mirror, db::Vector (x, y))); + db::Cell &ccell = l2n->internal_layout ()->cell (circuit->cell_index ()); + ccell.insert (inst); + + connections [inst] = refs; + + } } void @@ -819,12 +859,16 @@ LayoutToNetlistStandardReader::read_abstract_terminal (db::LayoutToNetlist *l2n, tid = dc->add_terminal_definition (new_td).id (); } - db::connected_clusters &cc = l2n->net_clusters ().clusters_per_cell (dm->cell_index ()); - db::local_cluster &lc = *cc.insert (); - dm->set_cluster_id_for_terminal (tid, lc.id ()); + if (l2n) { - db::Cell &cell = l2n->internal_layout ()->cell (dm->cell_index ()); - read_geometries (br, l2n, lc, cell); + db::connected_clusters &cc = l2n->net_clusters ().clusters_per_cell (dm->cell_index ()); + db::local_cluster &lc = *cc.insert (); + dm->set_cluster_id_for_terminal (tid, lc.id ()); + + db::Cell &cell = l2n->internal_layout ()->cell (dm->cell_index ()); + read_geometries (br, l2n, lc, cell); + + } br.done (); } diff --git a/src/db/db/dbLayoutToNetlistReader.h b/src/db/db/dbLayoutToNetlistReader.h index 88965b764..35bfd4b66 100644 --- a/src/db/db/dbLayoutToNetlistReader.h +++ b/src/db/db/dbLayoutToNetlistReader.h @@ -86,7 +86,7 @@ protected: friend class l2n_std_reader::Brace; typedef l2n_std_reader::Brace Brace; - void do_read (db::LayoutToNetlist *l2n, bool nested = false); + void do_read (Netlist *netlist, db::LayoutToNetlist *l2n, bool nested = false, std::map > *id2net_per_circuit = 0); static size_t terminal_id (const db::DeviceClass *device_class, const std::string &tname); static db::DeviceAbstract *device_model_by_name (db::Netlist *netlist, const std::string &dmname); tl::TextInputStream &stream (); @@ -110,10 +110,10 @@ protected: bool at_end (); void skip (); - void read_net (db::LayoutToNetlist *l2n, db::Circuit *circuit, std::map &id2net); - void read_pin (db::LayoutToNetlist *l2n, db::Circuit *circuit, std::map &id2net); - void read_device (db::LayoutToNetlist *l2n, db::Circuit *circuit, std::map &id2net, std::map > &connections); - void read_subcircuit (db::LayoutToNetlist *l2n, db::Circuit *circuit, std::map &id2net, std::map > &connections); + void read_net (Netlist *netlist, db::LayoutToNetlist *l2n, db::Circuit *circuit, std::map &id2net); + void read_pin (Netlist *netlist, db::LayoutToNetlist *l2n, db::Circuit *circuit, std::map &id2net); + void read_device (Netlist *netlist, db::LayoutToNetlist *l2n, db::Circuit *circuit, std::map &id2net, std::map > &connections); + void read_subcircuit (Netlist *netlist, db::LayoutToNetlist *l2n, db::Circuit *circuit, std::map &id2net, std::map > &connections); void read_abstract_terminal (db::LayoutToNetlist *l2n, db::DeviceAbstract *dm, db::DeviceClass *dc); std::pair read_geometry (db::LayoutToNetlist *l2n); void read_geometries (Brace &br, db::LayoutToNetlist *l2n, db::local_cluster &lc, db::Cell &cell); diff --git a/src/db/db/dbLayoutVsSchematic.cc b/src/db/db/dbLayoutVsSchematic.cc index 1c61e153f..a2249b739 100644 --- a/src/db/db/dbLayoutVsSchematic.cc +++ b/src/db/db/dbLayoutVsSchematic.cc @@ -53,7 +53,7 @@ LayoutVsSchematic::LayoutVsSchematic () // .. nothing yet .. } -~LayoutVsSchematic () +LayoutVsSchematic::~LayoutVsSchematic () { // .. nothing yet .. } @@ -100,7 +100,7 @@ void db::LayoutVsSchematic::load (const std::string &path) db::LayoutVsSchematicStandardReader reader (stream); set_filename (path); set_name (stream.filename ()); - reader.read (this); + reader.read_lvs (this); } } diff --git a/src/db/db/dbLayoutVsSchematicReader.cc b/src/db/db/dbLayoutVsSchematicReader.cc index fb6bda526..f44f85160 100644 --- a/src/db/db/dbLayoutVsSchematicReader.cc +++ b/src/db/db/dbLayoutVsSchematicReader.cc @@ -48,6 +48,8 @@ void LayoutVsSchematicStandardReader::do_read (db::LayoutVsSchematic *lvs) { int version = 0; std::string description; + m_id2net_per_circuit_a.clear (); + m_id2net_per_circuit_b.clear (); tl_assert (lvs->internal_layout ()); lvs->internal_layout ()->dbu (1.0); // mainly for testing @@ -76,14 +78,14 @@ void LayoutVsSchematicStandardReader::do_read (db::LayoutVsSchematic *lvs) } else if (test (skeys::layout_key) || test (lkeys::layout_key)) { Brace br (this); - LayoutToNetlistStandardReader::do_read (lvs, true /*nested*/); + LayoutToNetlistStandardReader::do_read (0, lvs, true /*nested*/, &m_id2net_per_circuit_a); br.done (); } else if (test (skeys::reference_key) || test (lkeys::reference_key)) { Brace br (this); std::auto_ptr netlist (new db::Netlist ()); - read_netlist (netlist.get ()); + LayoutToNetlistStandardReader::do_read (netlist.get (), 0, true /*nested*/, &m_id2net_per_circuit_b); lvs->set_reference_netlist (netlist.release ()); br.done (); @@ -105,216 +107,6 @@ void LayoutVsSchematicStandardReader::do_read (db::LayoutVsSchematic *lvs) } } -void LayoutVsSchematicStandardReader::read_netlist (db::Netlist *netlist) -{ - Brace br (this); - while (br) { - - if (test (skeys::circuit_key) || test (lkeys::circuit_key)) { - - Brace br (this); - std::string name; - read_word_or_quoted (name); - - db::Circuit *circuit = new db::Circuit (); - circuit->set_name (name); - netlist->add_circuit (circuit); - - std::map id2net; - - while (br) { - - if (test (skeys::net_key) || test (lkeys::net_key)) { - read_net (netlist, circuit, id2net); - } else if (test (skeys::pin_key) || test (lkeys::pin_key)) { - read_pin (netlist, circuit, id2net); - } else if (test (skeys::device_key) || test (lkeys::device_key)) { - read_device (netlist, circuit, id2net); - } else if (test (skeys::circuit_key) || test (lkeys::circuit_key)) { - read_subcircuit (netlist, circuit, id2net); - } else { - throw tl::Exception (tl::to_string (tr ("Invalid keyword inside circuit definition (net, pin, device or circuit expected)"))); - } - - } - br.done (); - - } - - } - br.done (); -} - -void -LayoutVsSchematicStandardReader::read_net (db::Netlist * /*netlist*/, db::Circuit *circuit, std::map &id2net) -{ - Brace br (this); - - unsigned int id = (unsigned int) read_int (); - std::string name; - - if (test (skeys::name_key) || test (lkeys::name_key)) { - Brace br_name (this); - read_word_or_quoted (name); - br_name.done (); - } - - db::Net *net = new db::Net (); - net->set_name (name); - circuit->add_net (net); - - id2net.insert (std::make_pair (id, net)); - - br.done (); -} - -void -LayoutVsSchematicStandardReader::read_pin (db::Netlist * /*netlist*/, db::Circuit *circuit, std::map &id2net) -{ - Brace br (this); - std::string name; - read_word_or_quoted (name); - unsigned int netid = (unsigned int) read_int (); - br.done (); - - const db::Pin &pin = circuit->add_pin (name); - - db::Net *net = id2net [netid]; - if (!net) { - throw tl::Exception (tl::to_string (tr ("Not a valid net ID: ")) + tl::to_string (netid)); - } - - circuit->connect_pin (pin.id (), net); -} - - -void -LayoutVsSchematicStandardReader::read_device (db::Netlist *netlist, db::Circuit *circuit, std::map &id2net) -{ - Brace br (this); - - std::string name; - read_word_or_quoted (name); - - std::string dmname; - read_word_or_quoted (dmname); - - db::DeviceAbstract *dm = device_model_by_name (netlist, dmname); - - db::Device *device = new db::Device (); - device->set_device_class (const_cast (dm->device_class ())); - device->set_device_abstract (dm); - device->set_name (name); - circuit->add_device (device); - - size_t max_tid = 0; - - while (br) { - - if (test (skeys::terminal_key) || test (lkeys::terminal_key)) { - - Brace br2 (this); - std::string tname; - read_word_or_quoted (tname); - unsigned int netid = (unsigned int) read_int (); - br2.done (); - - size_t tid = terminal_id (dm->device_class (), tname); - max_tid = std::max (max_tid, tid + 1); - - db::Net *net = id2net [netid]; - if (!net) { - throw tl::Exception (tl::to_string (tr ("Not a valid net ID: ")) + tl::to_string (netid)); - } - - device->connect_terminal (tid, net); - - } else if (test (skeys::param_key) || test (lkeys::param_key)) { - - Brace br2 (this); - std::string pname; - read_word_or_quoted (pname); - double value = read_double (); - br2.done (); - - size_t pid = std::numeric_limits::max (); - const std::vector &pd = dm->device_class ()->parameter_definitions (); - for (std::vector::const_iterator p = pd.begin (); p != pd.end (); ++p) { - if (p->name () == pname) { - pid = p->id (); - break; - } - } - - // if no parameter with this name exists, create one - if (pid == std::numeric_limits::max ()) { - // TODO: this should only happen for generic devices - db::DeviceClass *dc = const_cast (dm->device_class ()); - pid = dc->add_parameter_definition (db::DeviceParameterDefinition (pname, std::string ())).id (); - } - - device->set_parameter_value (pid, value); - - } else { - throw tl::Exception (tl::to_string (tr ("Invalid keyword inside device definition (location, param or terminal expected)"))); - } - - } - - br.done (); -} - -void -LayoutVsSchematicStandardReader::read_subcircuit (db::Netlist *netlist, db::Circuit *circuit, std::map &id2net) -{ - Brace br (this); - - std::string name; - read_word_or_quoted (name); - - std::string xname; - read_word_or_quoted (xname); - - db::Circuit *circuit_ref = netlist->circuit_by_name (xname); - if (! circuit_ref) { - throw tl::Exception (tl::to_string (tr ("Not a valid device circuit name: ")) + xname); - } - - db::SubCircuit *subcircuit = new db::SubCircuit (circuit_ref); - subcircuit->set_name (name); - circuit->add_subcircuit (subcircuit); - - while (br) { - - if (test (skeys::pin_key) || test (lkeys::pin_key)) { - - Brace br2 (this); - std::string pname; - read_word_or_quoted (pname); - unsigned int netid = (unsigned int) read_int (); - br2.done (); - - const db::Pin *sc_pin = circuit_ref->pin_by_name (pname); - if (! sc_pin) { - throw tl::Exception (tl::to_string (tr ("Not a valid pin name: ")) + pname + tl::to_string (tr (" for circuit: ")) + circuit_ref->name ()); - } - - db::Net *net = id2net [netid]; - if (!net) { - throw tl::Exception (tl::to_string (tr ("Not a valid net ID: ")) + tl::to_string (netid)); - } - - subcircuit->connect_pin (sc_pin->id (), net); - - } else { - throw tl::Exception (tl::to_string (tr ("Invalid keyword inside subcircuit definition (location, rotation, mirror, scale or pin expected)"))); - } - - } - - br.done (); -} - bool LayoutVsSchematicStandardReader::read_status (db::NetlistCrossReference::Status &status) { if (test (skeys::match_key) || test (lkeys::match_key)) { @@ -429,17 +221,26 @@ std::pair LayoutVsSchematicStandardReader::read_non_numerica } } -static const db::Net *net_by_numerical_id (const db::Circuit *circuit, const std::pair &non) + +static const db::Net *net_by_numerical_id (const db::Circuit *circuit, const std::pair &non, std::map > &id2net_per_circuit) { if (non.second && circuit) { - const db::Net *net = 0; // @@@ circuit->net_by_numerical_id (non.first); - if (! net) { - throw tl::Exception (tl::to_string (tr ("Not a valid net id: ")) + tl::to_string (non.first)); + + std::map >::const_iterator i = id2net_per_circuit.find (circuit); + if (i != id2net_per_circuit.end ()) { + + std::map::const_iterator j = i->second.find (non.first); + if (j != i->second.end ()) { + return j->second; + } + } - return net; - } else { - return 0; + + throw tl::Exception (tl::to_string (tr ("Not a valid net id: ")) + tl::to_string (non.first)); + } + + return 0; } void LayoutVsSchematicStandardReader::read_net_pair (db::NetlistCrossReference *xref, const db::Circuit *circuit_a, const db::Circuit *circuit_b) @@ -455,7 +256,7 @@ void LayoutVsSchematicStandardReader::read_net_pair (db::NetlistCrossReference * br.done (); - xref->gen_nets (net_by_numerical_id (circuit_a, non_a), net_by_numerical_id (circuit_b, non_b), status); + xref->gen_nets (net_by_numerical_id (circuit_a, non_a, m_id2net_per_circuit_a), net_by_numerical_id (circuit_b, non_b, m_id2net_per_circuit_b), status); } static const db::Pin *pin_by_name (const db::Circuit *circuit, const std::pair &non) diff --git a/src/db/db/dbLayoutVsSchematicReader.h b/src/db/db/dbLayoutVsSchematicReader.h index 66d8849ac..0c41d4850 100644 --- a/src/db/db/dbLayoutVsSchematicReader.h +++ b/src/db/db/dbLayoutVsSchematicReader.h @@ -66,12 +66,7 @@ public: private: void do_read (db::LayoutVsSchematic *lvs); - void read_netlist (db::Netlist *netlist); bool read_status (db::NetlistCrossReference::Status &status); - void read_net (db::Netlist *netlist, db::Circuit *circuit, std::map &id2net); - void read_subcircuit (db::Netlist *netlist, db::Circuit *circuit, std::map &id2net); - void read_device (db::Netlist *netlist, db::Circuit *circuit, std::map &id2net); - void read_pin (db::Netlist *netlist, db::Circuit *circuit, std::map &id2net); void read_xref (db::NetlistCrossReference *xref); void read_xrefs_for_circuits (db::NetlistCrossReference *xref, const db::Circuit *circuit_a, const db::Circuit *circuit_b); void read_net_pair (db::NetlistCrossReference *xref, const db::Circuit *circuit_a, const db::Circuit *circuit_b); @@ -80,6 +75,8 @@ private: void read_subcircuit_pair (db::NetlistCrossReference *xref, const db::Circuit *circuit_a, const db::Circuit *circuit_b); std::pair read_non_string (); std::pair read_non_numerical (); + + std::map > m_id2net_per_circuit_a, m_id2net_per_circuit_b; }; } diff --git a/src/db/db/dbLayoutVsSchematicWriter.cc b/src/db/db/dbLayoutVsSchematicWriter.cc index 9c12ddb9f..0c90a3acb 100644 --- a/src/db/db/dbLayoutVsSchematicWriter.cc +++ b/src/db/db/dbLayoutVsSchematicWriter.cc @@ -45,6 +45,7 @@ void LayoutVsSchematicWriterBase::write (const db::LayoutVsSchematic *l2n) do_write (l2n); } +#if 0 // ------------------------------------------------------------------------------------------- namespace l2n_std_format @@ -537,6 +538,7 @@ void std_writer_impl::write (const db::LayoutVsSchematic *l2n, const db::D } } +#endif // ------------------------------------------------------------------------------------------- // LayoutVsSchematicStandardWriter implementation @@ -547,8 +549,9 @@ LayoutVsSchematicStandardWriter::LayoutVsSchematicStandardWriter (tl::OutputStre // .. nothing yet .. } -void LayoutVsSchematicStandardWriter::do_write (const db::LayoutVsSchematic *l2n) +void LayoutVsSchematicStandardWriter::do_write (const db::LayoutVsSchematic * /*lvs*/) { +#if 0 if (m_short_version) { l2n_std_format::std_writer_impl > writer (*mp_stream); writer.write (l2n); @@ -556,6 +559,7 @@ void LayoutVsSchematicStandardWriter::do_write (const db::LayoutVsSchematic *l2n l2n_std_format::std_writer_impl > writer (*mp_stream); writer.write (l2n); } +#endif } }