diff --git a/src/db/db/dbLayoutToNetlist.cc b/src/db/db/dbLayoutToNetlist.cc index 682eb4293..b2c1ae343 100644 --- a/src/db/db/dbLayoutToNetlist.cc +++ b/src/db/db/dbLayoutToNetlist.cc @@ -742,6 +742,12 @@ LayoutToNetlist::build_net (const db::Net &net, db::Layout &target, db::Cell &ta void LayoutToNetlist::build_all_nets (const db::CellMapping &cmap, db::Layout &target, const std::map &lmap, const char *net_cell_name_prefix, const tl::Variant &netname_prop, BuildNetHierarchyMode hier_mode, const char *circuit_cell_name_prefix, const char *device_cell_name_prefix) const +{ + build_nets (0, cmap, target, lmap, net_cell_name_prefix, netname_prop, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix); +} + +void +LayoutToNetlist::build_nets (const std::set *nets, const db::CellMapping &cmap, db::Layout &target, const std::map &lmap, const char *net_cell_name_prefix, const tl::Variant &netname_prop, BuildNetHierarchyMode hier_mode, const char *circuit_cell_name_prefix, const char *device_cell_name_prefix) const { if (! m_netlist_extracted) { throw tl::Exception (tl::to_string (tr ("The netlist has not been extracted yet"))); @@ -763,22 +769,26 @@ LayoutToNetlist::build_all_nets (const db::CellMapping &cmap, db::Layout &target for (db::Circuit::const_net_iterator n = c->begin_nets (); n != c->end_nets (); ++n) { - // exlude local nets in recursive mode - if (hier_mode != BNH_Disconnected && ! is_top_circuit && n->pin_count () > 0) { + // exlude local nets in recursive mode except if they are explicitly selected + if (! nets && hier_mode != BNH_Disconnected && ! is_top_circuit && n->pin_count () > 0) { continue; } - db::properties_id_type netname_propid = make_netname_propid (target, netname_prop, *n); - build_net_rec (*n, target, target.cell (target_ci), lmap, net_cell_name_prefix, netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, cell_reuse_table, db::ICplxTrans (mag)); + if (! nets || nets->find (n.operator-> ()) != nets->end ()) { + db::properties_id_type netname_propid = make_netname_propid (target, netname_prop, *n); + build_net_rec (*n, target, target.cell (target_ci), lmap, net_cell_name_prefix, netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, cell_reuse_table, db::ICplxTrans (mag)); + } } - if (hier_mode != BNH_Disconnected) { + if (hier_mode != BNH_Disconnected && ! nets) { - // with recursive nets we skip nets in subcircuits which are connected upwards. This means, nets will + // With recursive nets we skip nets in subcircuits which are connected upwards. This means, nets will // get lost if there is no connection to this pin from the outside. Hence we need to deliver nets from // subcircuits as part of the circuit which calls the subcircuit - but NOT in a subcircuit cell, because // this will just apply to nets from certain instances. But the net cell name will be formed as "subcircuit:net" + // + // In explicit selection mode we don't care about this as nets are explicitly taken or not. const db::Circuit &circuit = *c; for (db::Circuit::const_subcircuit_iterator sc = circuit.begin_subcircuits (); sc != circuit.end_subcircuits (); ++sc) { diff --git a/src/db/db/dbLayoutToNetlist.h b/src/db/db/dbLayoutToNetlist.h index fd86500ca..0c9e77a57 100644 --- a/src/db/db/dbLayoutToNetlist.h +++ b/src/db/db/dbLayoutToNetlist.h @@ -589,6 +589,11 @@ public: */ void build_all_nets (const db::CellMapping &cmap, db::Layout &target, const std::map &lmap, const char *net_cell_name_prefix, const tl::Variant &netname_prop, BuildNetHierarchyMode hier_mode, const char *circuit_cell_name_prefix, const char *device_cell_name_prefix) const; + /** + * @brief Like build_all_nets, but with the ability to select some nets + */ + void build_nets (const std::set *nets, const db::CellMapping &cmap, db::Layout &target, const std::map &lmap, const char *net_cell_name_prefix, const tl::Variant &netname_prop, BuildNetHierarchyMode hier_mode, const char *circuit_cell_name_prefix, const char *device_cell_name_prefix) const; + /** * @brief Finds the net by probing a specific location on the given layer * diff --git a/src/laybasic/laybasic/NetExportDialog.ui b/src/laybasic/laybasic/NetExportDialog.ui index 3d35742f0..dd56a1849 100644 --- a/src/laybasic/laybasic/NetExportDialog.ui +++ b/src/laybasic/laybasic/NetExportDialog.ui @@ -6,206 +6,15 @@ 0 0 - 508 - 454 + 570 + 521 Export Net Options - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 10 - - - - - - - - Produce cells for circuits - - - - - - - Cell name prefix - - - - - - - Qt::Vertical - - - - 10 - 29 - - - - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - - Produce cells for devices - - - - - - - If this option is selected, the subcircuits on a net are represented by individual cells. Otherwise the net is exported as a whole into a single cell (flattened). - - - true - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 10 - - - - - - - - This feature will export the nets to a new layout. This layout will contain the original hierarchy as far as required. Within each cell, that corresponds to a circuit, a cell is generated for each net. Each net has it's own hierarchy which can be tailored with the options below. - - - true - - - - - - - Cell name prefix - - - - - - - - - - Starting layer number for unknown layers - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 10 - 20 - - - - - - - - If this options is selected, each device will be represented by one cell made from the device name and the given prefix. Otherwise, device parts are exported as shapes inside the net. - - - true - - - - - - - - - - Net cell name prefix - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 10 - 20 - - - - - - - - - 0 - 0 - - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 10 - - - - - + QFrame::NoFrame @@ -226,24 +35,195 @@ 0 - - + + + + + + + Layer mapping + + + + + + + 0 + 0 + + + - - + + - <html><body>(<a href="int:/about/variant_notation.xml">See here for the name notation</a>)</body></html> + Starting layer number for unknown layers + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 10 + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 10 + + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + This feature will export the nets to a new layout. Nets are associated with a circuit and are put into a corresponding cell. With the options below you can tailor the way nets, net parts from subcircuits and devices are annotated. + + + true + + + + + + + Produce cells for de&vices + + + true + + + + + + + + + Cell name prefix + + + + + + + If this options is selected, each device will be represented by one cell made from the device name and the given prefix. Otherwise, device parts are exported as shapes inside the net. + + + true - - - - Net property name + + + + Net annotation + + + + + Net cell name prefix + + + + + + + Net property name + + + + + + + + + + <html><body>(<a href="int:/about/variant_notation.xml">See here for the name notation</a>)</body></html> + + + + + + + + + + + + + Produce cells for circuits + + + true + + + + + + Cell name prefix + + + + + + + + + + If this option is selected, the subcircuits parts of a net are represented by individual cells. Otherwise the net with it's subcircuit parts is exported as a whole (flattened). + + + true + + + + @@ -259,38 +239,6 @@ - - produce_circuit_cells_cb - clicked(bool) - circuit_cell_prefix - setEnabled(bool) - - - 91 - 72 - - - 266 - 100 - - - - - produce_device_cells_cb - clicked(bool) - device_cell_prefix - setEnabled(bool) - - - 98 - 176 - - - 317 - 204 - - - buttonBox accepted() diff --git a/src/laybasic/laybasic/layLayoutView.cc b/src/laybasic/laybasic/layLayoutView.cc index a59d02907..749a3ff33 100644 --- a/src/laybasic/laybasic/layLayoutView.cc +++ b/src/laybasic/laybasic/layLayoutView.cc @@ -2975,7 +2975,7 @@ LayoutView::add_layout (lay::LayoutHandle *layout_handle, bool add_cellview, boo m_active_cellview_changed_event_enabled = false; - stop (); + stop_redraw (); bool set_max_hier = (m_full_hier_new_cell || has_max_hier ()); diff --git a/src/laybasic/laybasic/layNetExportDialog.cc b/src/laybasic/laybasic/layNetExportDialog.cc index 810dd8eb0..6cb89727c 100644 --- a/src/laybasic/laybasic/layNetExportDialog.cc +++ b/src/laybasic/laybasic/layNetExportDialog.cc @@ -95,7 +95,6 @@ NetExportDialog::net_propname () void NetExportDialog::set_produce_circuit_cells (bool f) { - ui->circuit_cell_prefix->setEnabled (f); ui->produce_circuit_cells_cb->setChecked (f); } @@ -120,7 +119,6 @@ NetExportDialog::circuit_cell_prefix () void NetExportDialog::set_produce_device_cells (bool f) { - ui->device_cell_prefix->setEnabled (f); ui->produce_device_cells_cb->setChecked (f); } diff --git a/src/laybasic/laybasic/layNetlistBrowserPage.cc b/src/laybasic/laybasic/layNetlistBrowserPage.cc index 8bbda7fa2..28677f591 100644 --- a/src/laybasic/laybasic/layNetlistBrowserPage.cc +++ b/src/laybasic/laybasic/layNetlistBrowserPage.cc @@ -2492,17 +2492,52 @@ NetlistBrowserPage::clear_markers () mp_markers.clear (); } +static std::map +create_layermap (const db::LayoutToNetlist *database, db::Layout &target_layout, int ln) +{ + std::map lm; + + const db::Layout &source_layout = *database->internal_layout (); + + std::set layers_to_copy; + const db::Connectivity &conn = database->connectivity (); + for (db::Connectivity::layer_iterator layer = conn.begin_layers (); layer != conn.end_layers (); ++layer) { + layers_to_copy.insert (*layer); + } + + for (std::set::const_iterator l = layers_to_copy.begin (); l != layers_to_copy.end (); ++l) { + const db::LayerProperties &lp = source_layout.get_properties (*l); + unsigned int tl; + if (! lp.is_null ()) { + tl = target_layout.insert_layer (lp); + } else { + tl = target_layout.insert_layer (db::LayerProperties (ln++, 0, database->name (*l))); + } + lm.insert (std::make_pair (tl, (const_cast (database))->layer_by_index (*l))); + } + + return lm; +} + void NetlistBrowserPage::export_selected () { - std::auto_ptr dialog (new lay::NetExportDialog (this)); - if (dialog->exec (mp_plugin_root)) { - // @@@ + std::vector nets = selected_nets (); + if (nets.empty ()) { + return; } + + export_nets (&nets); } void NetlistBrowserPage::export_all () +{ + export_nets (0); +} + +void +NetlistBrowserPage::export_nets (const std::vector *nets) { if (! mp_view || ! mp_database.get () || ! mp_database->internal_layout ()) { return; @@ -2529,37 +2564,19 @@ NetlistBrowserPage::export_all () db::cell_index_type target_top_index = target_layout.add_cell (source_layout.cell_name (source_top.cell_index ())); db::CellMapping cm = database->cell_mapping_into (target_layout, target_layout.cell (target_top_index)); + std::map lm = create_layermap (database, target_layout, dialog->start_layer_number ()); - std::map lm; - { - // create a layer mapping - - std::set layers_to_copy; - const db::Connectivity &conn = database->connectivity (); - for (db::Connectivity::layer_iterator layer = conn.begin_layers (); layer != conn.end_layers (); ++layer) { - layers_to_copy.insert (*layer); - } - - int ln = dialog->start_layer_number (); - - for (std::set::const_iterator l = layers_to_copy.begin (); l != layers_to_copy.end (); ++l) { - const db::LayerProperties &lp = source_layout.get_properties (*l); - unsigned int tl; - if (! lp.is_null ()) { - tl = target_layout.insert_layer (lp); - } else { - tl = target_layout.insert_layer (db::LayerProperties (ln++, 0, database->name (*l))); - } - lm.insert (std::make_pair (tl, database->layer_by_index (*l))); - } + std::set net_set; + if (nets) { + net_set.insert (nets->begin (), nets->end ()); } - database->build_all_nets (cm, target_layout, lm, - dialog->net_prefix ().empty () ? 0 : dialog->net_prefix ().c_str (), - dialog->net_propname (), - dialog->produce_circuit_cells () ? db::LayoutToNetlist::BNH_SubcircuitCells : db::LayoutToNetlist::BNH_Flatten, - dialog->produce_circuit_cells () ? dialog->circuit_cell_prefix ().c_str () : 0, - dialog->produce_device_cells () ? dialog->device_cell_prefix ().c_str () : 0); + database->build_nets (nets ? &net_set : 0, cm, target_layout, lm, + dialog->net_prefix ().empty () ? 0 : dialog->net_prefix ().c_str (), + dialog->net_propname (), + dialog->produce_circuit_cells () ? db::LayoutToNetlist::BNH_SubcircuitCells : db::LayoutToNetlist::BNH_Flatten, + dialog->produce_circuit_cells () ? dialog->circuit_cell_prefix ().c_str () : 0, + dialog->produce_device_cells () ? dialog->device_cell_prefix ().c_str () : 0); view->zoom_fit (); view->max_hier (); diff --git a/src/laybasic/laybasic/layNetlistBrowserPage.h b/src/laybasic/laybasic/layNetlistBrowserPage.h index d9dcceba2..8945541b8 100644 --- a/src/laybasic/laybasic/layNetlistBrowserPage.h +++ b/src/laybasic/laybasic/layNetlistBrowserPage.h @@ -358,6 +358,7 @@ private: void layer_list_changed (int); bool produce_highlights_for_net(const db::Net *net, size_t &n_markers, const std::map &display_by_lp, const std::vector &tv); db::ICplxTrans trans_for_net (const db::Net *net); + void export_nets (const std::vector *nets); }; } // namespace lay