diff --git a/src/db/db/dbDeepShapeStore.cc b/src/db/db/dbDeepShapeStore.cc index 1e0c1e96b..f6e180560 100644 --- a/src/db/db/dbDeepShapeStore.cc +++ b/src/db/db/dbDeepShapeStore.cc @@ -514,6 +514,18 @@ void DeepShapeStore::make_layout (unsigned int layout_index, const db::Recursive m_layout_map[std::make_pair (si, trans)] = layout_index; } +static unsigned int init_layer (db::Layout &layout, const db::RecursiveShapeIterator &si) +{ + unsigned int layer_index = layout.insert_layer (); + + if (si.layout () && si.layer () < si.layout ()->layers ()) { + // try to preserve the layer properties + layout.set_properties (layer_index, si.layout ()->get_properties (si.layer ())); + } + + return layer_index; +} + DeepLayer DeepShapeStore::create_polygon_layer (const db::RecursiveShapeIterator &si, double max_area_ratio, size_t max_vertex_count, const db::ICplxTrans &trans) { if (max_area_ratio == 0.0) { @@ -528,7 +540,7 @@ DeepLayer DeepShapeStore::create_polygon_layer (const db::RecursiveShapeIterator db::Layout &layout = m_layouts[layout_index]->layout; db::HierarchyBuilder &builder = m_layouts[layout_index]->builder; - unsigned int layer_index = layout.insert_layer (); + unsigned int layer_index = init_layer (layout, si); builder.set_target_layer (layer_index); // The chain of operators for producing clipped and reduced polygon references @@ -571,7 +583,7 @@ DeepLayer DeepShapeStore::create_custom_layer (const db::RecursiveShapeIterator db::Layout &layout = m_layouts[layout_index]->layout; db::HierarchyBuilder &builder = m_layouts[layout_index]->builder; - unsigned int layer_index = layout.insert_layer (); + unsigned int layer_index = init_layer (layout, si); builder.set_target_layer (layer_index); // Build the working hierarchy from the recursive shape iterator @@ -624,7 +636,7 @@ DeepLayer DeepShapeStore::create_edge_layer (const db::RecursiveShapeIterator &s db::Layout &layout = m_layouts[layout_index]->layout; db::HierarchyBuilder &builder = m_layouts[layout_index]->builder; - unsigned int layer_index = layout.insert_layer (); + unsigned int layer_index = init_layer (layout, si); builder.set_target_layer (layer_index); // The chain of operators for producing edges @@ -654,7 +666,7 @@ DeepLayer DeepShapeStore::create_edge_pair_layer (const db::RecursiveShapeIterat db::Layout &layout = m_layouts[layout_index]->layout; db::HierarchyBuilder &builder = m_layouts[layout_index]->builder; - unsigned int layer_index = layout.insert_layer (); + unsigned int layer_index = init_layer (layout, si); builder.set_target_layer (layer_index); // The chain of operators for producing the edge pairs diff --git a/src/db/db/dbLayoutToNetlistFormatDefs.h b/src/db/db/dbLayoutToNetlistFormatDefs.h index abb314ec7..5ef78581c 100644 --- a/src/db/db/dbLayoutToNetlistFormatDefs.h +++ b/src/db/db/dbLayoutToNetlistFormatDefs.h @@ -52,7 +52,7 @@ namespace db * description() - an arbitrary description text [short key: B] * unit() - specifies the database unit [short key: U] * top() - specifies the name of the top circuit [short key: W] - * layer() - define a layer [short key: L] + * layer( ?) - define a layer [short key: L] * connect( ...) - connects layer1 with the following layers [short key: C] * global( ...) * - connects the shapes of the layer with the given global diff --git a/src/db/db/dbLayoutToNetlistReader.cc b/src/db/db/dbLayoutToNetlistReader.cc index bee6bcb16..2fe2f04f3 100644 --- a/src/db/db/dbLayoutToNetlistReader.cc +++ b/src/db/db/dbLayoutToNetlistReader.cc @@ -201,9 +201,21 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n) } else if (test (skeys::layer_key) || test (lkeys::layer_key)) { Brace br (this); - std::string layer; + std::string layer, lspec; read_word_or_quoted (layer); - delete l2n->make_layer (layer); + if (br) { + read_word_or_quoted (lspec); + } + + std::auto_ptr region (l2n->make_layer (layer)); + if (! lspec.empty ()) { + unsigned int layer_index = l2n->layer_of (*region); + tl::Extractor ex (lspec.c_str ()); + db::LayerProperties lp; + lp.read (ex); + l2n->internal_layout ()->set_properties (layer_index, lp); + } + br.done (); } else if (test (skeys::class_key) || test (lkeys::class_key)) { diff --git a/src/db/db/dbLayoutToNetlistWriter.cc b/src/db/db/dbLayoutToNetlistWriter.cc index 3f386cf44..03233afd2 100644 --- a/src/db/db/dbLayoutToNetlistWriter.cc +++ b/src/db/db/dbLayoutToNetlistWriter.cc @@ -123,7 +123,12 @@ void std_writer_impl::write (const db::LayoutToNetlist *l2n) *mp_stream << endl << "# Mask layers" << endl; } for (db::Connectivity::layer_iterator l = l2n->connectivity ().begin_layers (); l != l2n->connectivity ().end_layers (); ++l) { - *mp_stream << Keys::layer_key << "(" << name_for_layer (l2n, *l) << ")" << endl; + *mp_stream << Keys::layer_key << "(" << name_for_layer (l2n, *l); + db::LayerProperties lp = ly->get_properties (*l); + if (! lp.is_null ()) { + *mp_stream << " " << tl::to_word_or_quoted_string (lp.to_string ()); + } + *mp_stream << ")" << endl; } if (! Keys::is_short ()) { diff --git a/src/laybasic/laybasic/layNetlistBrowserPage.cc b/src/laybasic/laybasic/layNetlistBrowserPage.cc index 638d19bef..849f2e364 100644 --- a/src/laybasic/laybasic/layNetlistBrowserPage.cc +++ b/src/laybasic/laybasic/layNetlistBrowserPage.cc @@ -1754,8 +1754,17 @@ NetlistBrowserPage::set_highlight_style (QColor color, int line_width, int verte void NetlistBrowserPage::set_view (lay::LayoutView *view, unsigned int cv_index) { + if (mp_view) { + mp_view->layer_list_changed_event.remove (this, &NetlistBrowserPage::layer_list_changed); + } + mp_view = view; m_cv_index = cv_index; + + if (mp_view) { + mp_view->layer_list_changed_event.add (this, &NetlistBrowserPage::layer_list_changed); + } + update_highlights (); } @@ -1777,6 +1786,12 @@ NetlistBrowserPage::set_max_shape_count (size_t max_shape_count) } } +void +NetlistBrowserPage::layer_list_changed (int) +{ + update_highlights (); +} + void NetlistBrowserPage::anchor_clicked (const QString &a) { @@ -2052,29 +2067,26 @@ NetlistBrowserPage::show_all (bool f) void NetlistBrowserPage::set_l2ndb (db::LayoutToNetlist *database) { - if (database != mp_database.get ()) { - - mp_database.reset (database); - clear_markers (); - highlight_nets (std::vector ()); - - if (! database) { - directory_tree->setModel (0); - return; - } - - // NOTE: with the tree as the parent, the tree will take over ownership of the model - NetlistBrowserModel *new_model = new NetlistBrowserModel (directory_tree, database, &m_colorizer); - - directory_tree->setModel (new_model); - connect (directory_tree->selectionModel (), SIGNAL (currentChanged (const QModelIndex &, const QModelIndex &)), this, SLOT (current_index_changed (const QModelIndex &))); - connect (directory_tree->selectionModel (), SIGNAL (selectionChanged (const QItemSelection &, const QItemSelection &)), this, SLOT (net_selection_changed ())); - - directory_tree->header ()->setSortIndicatorShown (true); - - find_text->setText (QString ()); + mp_database.reset (database); + clear_markers (); + highlight_nets (std::vector ()); + if (! database) { + delete directory_tree->model (); + directory_tree->setModel (0); + return; } + + // NOTE: with the tree as the parent, the tree will take over ownership of the model + NetlistBrowserModel *new_model = new NetlistBrowserModel (directory_tree, database, &m_colorizer); + + directory_tree->setModel (new_model); + connect (directory_tree->selectionModel (), SIGNAL (currentChanged (const QModelIndex &, const QModelIndex &)), this, SLOT (current_index_changed (const QModelIndex &))); + connect (directory_tree->selectionModel (), SIGNAL (selectionChanged (const QItemSelection &, const QItemSelection &)), this, SLOT (net_selection_changed ())); + + directory_tree->header ()->setSortIndicatorShown (true); + + find_text->setText (QString ()); } void @@ -2203,11 +2215,22 @@ NetlistBrowserPage::update_highlights () return; } + const db::Layout &original_layout = mp_view->cellview (m_cv_index)->layout (); + const db::Layout *layout = mp_database->internal_layout (); if (! layout) { return; } + // a map of display properties vs. layer properties + + std::map display_by_lp; + for (lay::LayerPropertiesConstIterator lp = mp_view->begin_layers (); ! lp.at_end (); ++lp) { + if (! lp->has_children () && lp->cellview_index () == int (m_cv_index) && lp->layer_index () >= 0 && (unsigned int) lp->layer_index () < original_layout.layers ()) { + display_by_lp.insert (std::make_pair (original_layout.get_properties (lp->layer_index ()), lp)); + } + } + // @@@std::map > tv_by_layer = mp_view->cv_transform_variants_by_layer (m_cv_index); std::vector tv = mp_view->cv_transform_variants (m_cv_index); @@ -2228,7 +2251,8 @@ NetlistBrowserPage::update_highlights () const db::Connectivity &conn = mp_database->connectivity (); for (db::Connectivity::layer_iterator layer = conn.begin_layers (); layer != conn.end_layers (); ++layer) { - // @@@ TODO: how to get the original layer? + db::LayerProperties lp = layout->get_properties (*layer); + std::map::const_iterator display = display_by_lp.find (lp); db::recursive_cluster_shape_iterator shapes (mp_database->net_clusters (), *layer, cell_index, cluster_id); while (! shapes.at_end ()) { @@ -2241,25 +2265,32 @@ NetlistBrowserPage::update_highlights () mp_markers.push_back (new lay::Marker (mp_view, m_cv_index)); mp_markers.back ()->set (*shapes, shapes.trans (), tv); - #if 0 - // @@@ - if (! original.at_end ()) { - mp_markers.back ()->set_line_width (original->width (true)); + if (net_color.isValid ()) { + + mp_markers.back ()->set_color (net_color); + mp_markers.back ()->set_frame_color (net_color); + + } else if (display != display_by_lp.end ()) { + + mp_markers.back ()->set_line_width (display->second->width (true)); mp_markers.back ()->set_vertex_size (1); - mp_markers.back ()->set_dither_pattern (original->dither_pattern (true)); - if (view ()->background_color ().green () < 128) { - mp_markers.back ()->set_color (original->eff_fill_color_brighter (true, (m_marker_intensity * 255) / 100)); - mp_markers.back ()->set_frame_color (original->eff_frame_color_brighter (true, (m_marker_intensity * 255) / 100)); + mp_markers.back ()->set_dither_pattern (display->second->dither_pattern (true)); + if (mp_view->background_color ().green () < 128) { + mp_markers.back ()->set_color (display->second->eff_fill_color_brighter (true, (m_marker_intensity * 255) / 100)); + mp_markers.back ()->set_frame_color (display->second->eff_frame_color_brighter (true, (m_marker_intensity * 255) / 100)); } else { - mp_markers.back ()->set_color (original->eff_fill_color_brighter (true, (-m_marker_intensity * 255) / 100)); - mp_markers.back ()->set_frame_color (original->eff_frame_color_brighter (true, (-m_marker_intensity * 255) / 100)); + mp_markers.back ()->set_color (display->second->eff_fill_color_brighter (true, (-m_marker_intensity * 255) / 100)); + mp_markers.back ()->set_frame_color (display->second->eff_frame_color_brighter (true, (-m_marker_intensity * 255) / 100)); } + + } else { + + // fallback color + QColor net_color = mp_view->background_color ().green () < 128 ? QColor (Qt::white) : QColor (Qt::black); + mp_markers.back ()->set_color (net_color); + mp_markers.back ()->set_frame_color (net_color); + } - #endif - // @@@ - mp_markers.back ()->set_color (net_color); - mp_markers.back ()->set_frame_color (net_color); - // @@@ if (m_marker_line_width >= 0) { mp_markers.back ()->set_line_width (m_marker_line_width); diff --git a/src/laybasic/laybasic/layNetlistBrowserPage.h b/src/laybasic/laybasic/layNetlistBrowserPage.h index ca2553a3d..c10b3772b 100644 --- a/src/laybasic/laybasic/layNetlistBrowserPage.h +++ b/src/laybasic/laybasic/layNetlistBrowserPage.h @@ -214,7 +214,8 @@ private: */ class NetlistBrowserPage : public QFrame, - public Ui::NetlistBrowserPage + public Ui::NetlistBrowserPage, + public tl::Object { Q_OBJECT @@ -340,6 +341,7 @@ private: void highlight_nets (const std::vector &nets); std::vector selected_nets (); void set_color_for_selected_nets (const QColor &color); + void layer_list_changed (int); }; } // namespace lay diff --git a/testdata/algo/l2n_writer_au.txt b/testdata/algo/l2n_writer_au.txt index 79a4682be..c840d7397 100644 --- a/testdata/algo/l2n_writer_au.txt +++ b/testdata/algo/l2n_writer_au.txt @@ -9,15 +9,15 @@ unit(0.001) # This section lists the mask layers (drawing or derived) and their connections. # Mask layers -layer(poly) -layer(poly_lbl) -layer(diff_cont) -layer(poly_cont) -layer(metal1) -layer(metal1_lbl) -layer(via1) -layer(metal2) -layer(metal2_lbl) +layer(poly '3/0') +layer(poly_lbl '3/1') +layer(diff_cont '4/0') +layer(poly_cont '5/0') +layer(metal1 '6/0') +layer(metal1_lbl '6/1') +layer(via1 '7/0') +layer(metal2 '8/0') +layer(metal2_lbl '8/1') layer(psd) layer(nsd) diff --git a/testdata/algo/l2n_writer_au_2.txt b/testdata/algo/l2n_writer_au_2.txt index 3062b5887..67e4e8155 100644 --- a/testdata/algo/l2n_writer_au_2.txt +++ b/testdata/algo/l2n_writer_au_2.txt @@ -10,16 +10,16 @@ unit(0.001) # Mask layers layer(rbulk) -layer(nwell) -layer(poly) -layer(poly_lbl) -layer(diff_cont) -layer(poly_cont) -layer(metal1) -layer(metal1_lbl) -layer(via1) -layer(metal2) -layer(metal2_lbl) +layer(nwell '1/0') +layer(poly '3/0') +layer(poly_lbl '3/1') +layer(diff_cont '4/0') +layer(poly_cont '5/0') +layer(metal1 '6/0') +layer(metal1_lbl '6/1') +layer(via1 '7/0') +layer(metal2 '8/0') +layer(metal2_lbl '8/1') layer(ntie) layer(psd) layer(ptie) diff --git a/testdata/algo/l2n_writer_au_2s.txt b/testdata/algo/l2n_writer_au_2s.txt index f89b7692e..859310b4a 100644 --- a/testdata/algo/l2n_writer_au_2s.txt +++ b/testdata/algo/l2n_writer_au_2s.txt @@ -2,16 +2,16 @@ W(RINGO) U(0.001) L(rbulk) -L(nwell) -L(poly) -L(poly_lbl) -L(diff_cont) -L(poly_cont) -L(metal1) -L(metal1_lbl) -L(via1) -L(metal2) -L(metal2_lbl) +L(nwell '1/0') +L(poly '3/0') +L(poly_lbl '3/1') +L(diff_cont '4/0') +L(poly_cont '5/0') +L(metal1 '6/0') +L(metal1_lbl '6/1') +L(via1 '7/0') +L(metal2 '8/0') +L(metal2_lbl '8/1') L(ntie) L(psd) L(ptie) diff --git a/testdata/algo/l2n_writer_au_s.txt b/testdata/algo/l2n_writer_au_s.txt index e60473552..e994d927b 100644 --- a/testdata/algo/l2n_writer_au_s.txt +++ b/testdata/algo/l2n_writer_au_s.txt @@ -1,15 +1,15 @@ #%l2n-klayout W(RINGO) U(0.001) -L(poly) -L(poly_lbl) -L(diff_cont) -L(poly_cont) -L(metal1) -L(metal1_lbl) -L(via1) -L(metal2) -L(metal2_lbl) +L(poly '3/0') +L(poly_lbl '3/1') +L(diff_cont '4/0') +L(poly_cont '5/0') +L(metal1 '6/0') +L(metal1_lbl '6/1') +L(via1 '7/0') +L(metal2 '8/0') +L(metal2_lbl '8/1') L(psd) L(nsd) C(poly poly poly_lbl poly_cont)