mirror of https://github.com/KLayout/klayout.git
Netlist browser: fixed a segfault on 'unload all'
This commit is contained in:
parent
0983ebc854
commit
e661bac0a7
|
|
@ -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;
|
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)
|
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) {
|
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::Layout &layout = m_layouts[layout_index]->layout;
|
||||||
db::HierarchyBuilder &builder = m_layouts[layout_index]->builder;
|
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);
|
builder.set_target_layer (layer_index);
|
||||||
|
|
||||||
// The chain of operators for producing clipped and reduced polygon references
|
// 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::Layout &layout = m_layouts[layout_index]->layout;
|
||||||
db::HierarchyBuilder &builder = m_layouts[layout_index]->builder;
|
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);
|
builder.set_target_layer (layer_index);
|
||||||
|
|
||||||
// Build the working hierarchy from the recursive shape iterator
|
// 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::Layout &layout = m_layouts[layout_index]->layout;
|
||||||
db::HierarchyBuilder &builder = m_layouts[layout_index]->builder;
|
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);
|
builder.set_target_layer (layer_index);
|
||||||
|
|
||||||
// The chain of operators for producing edges
|
// 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::Layout &layout = m_layouts[layout_index]->layout;
|
||||||
db::HierarchyBuilder &builder = m_layouts[layout_index]->builder;
|
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);
|
builder.set_target_layer (layer_index);
|
||||||
|
|
||||||
// The chain of operators for producing the edge pairs
|
// The chain of operators for producing the edge pairs
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ namespace db
|
||||||
* description(<text>) - an arbitrary description text [short key: B]
|
* description(<text>) - an arbitrary description text [short key: B]
|
||||||
* unit(<unit>) - specifies the database unit [short key: U]
|
* unit(<unit>) - specifies the database unit [short key: U]
|
||||||
* top(<circuit>) - specifies the name of the top circuit [short key: W]
|
* top(<circuit>) - specifies the name of the top circuit [short key: W]
|
||||||
* layer(<name>) - define a layer [short key: L]
|
* layer(<name> <source-spec>?) - define a layer [short key: L]
|
||||||
* connect(<layer1> <name> ...) - connects layer1 with the following layers [short key: C]
|
* connect(<layer1> <name> ...) - connects layer1 with the following layers [short key: C]
|
||||||
* global(<layer> <net-name> ...)
|
* global(<layer> <net-name> ...)
|
||||||
* - connects the shapes of the layer with the given global
|
* - connects the shapes of the layer with the given global
|
||||||
|
|
|
||||||
|
|
@ -201,9 +201,21 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n)
|
||||||
} else if (test (skeys::layer_key) || test (lkeys::layer_key)) {
|
} else if (test (skeys::layer_key) || test (lkeys::layer_key)) {
|
||||||
|
|
||||||
Brace br (this);
|
Brace br (this);
|
||||||
std::string layer;
|
std::string layer, lspec;
|
||||||
read_word_or_quoted (layer);
|
read_word_or_quoted (layer);
|
||||||
delete l2n->make_layer (layer);
|
if (br) {
|
||||||
|
read_word_or_quoted (lspec);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::auto_ptr<db::Region> 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 ();
|
br.done ();
|
||||||
|
|
||||||
} else if (test (skeys::class_key) || test (lkeys::class_key)) {
|
} else if (test (skeys::class_key) || test (lkeys::class_key)) {
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,12 @@ void std_writer_impl<Keys>::write (const db::LayoutToNetlist *l2n)
|
||||||
*mp_stream << endl << "# Mask layers" << endl;
|
*mp_stream << endl << "# Mask layers" << endl;
|
||||||
}
|
}
|
||||||
for (db::Connectivity::layer_iterator l = l2n->connectivity ().begin_layers (); l != l2n->connectivity ().end_layers (); ++l) {
|
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 ()) {
|
if (! Keys::is_short ()) {
|
||||||
|
|
|
||||||
|
|
@ -1754,8 +1754,17 @@ NetlistBrowserPage::set_highlight_style (QColor color, int line_width, int verte
|
||||||
void
|
void
|
||||||
NetlistBrowserPage::set_view (lay::LayoutView *view, unsigned int cv_index)
|
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;
|
mp_view = view;
|
||||||
m_cv_index = cv_index;
|
m_cv_index = cv_index;
|
||||||
|
|
||||||
|
if (mp_view) {
|
||||||
|
mp_view->layer_list_changed_event.add (this, &NetlistBrowserPage::layer_list_changed);
|
||||||
|
}
|
||||||
|
|
||||||
update_highlights ();
|
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
|
void
|
||||||
NetlistBrowserPage::anchor_clicked (const QString &a)
|
NetlistBrowserPage::anchor_clicked (const QString &a)
|
||||||
{
|
{
|
||||||
|
|
@ -2052,29 +2067,26 @@ NetlistBrowserPage::show_all (bool f)
|
||||||
void
|
void
|
||||||
NetlistBrowserPage::set_l2ndb (db::LayoutToNetlist *database)
|
NetlistBrowserPage::set_l2ndb (db::LayoutToNetlist *database)
|
||||||
{
|
{
|
||||||
if (database != mp_database.get ()) {
|
mp_database.reset (database);
|
||||||
|
clear_markers ();
|
||||||
mp_database.reset (database);
|
highlight_nets (std::vector<const db::Net *> ());
|
||||||
clear_markers ();
|
|
||||||
highlight_nets (std::vector<const db::Net *> ());
|
|
||||||
|
|
||||||
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 ());
|
|
||||||
|
|
||||||
|
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
|
void
|
||||||
|
|
@ -2203,11 +2215,22 @@ NetlistBrowserPage::update_highlights ()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const db::Layout &original_layout = mp_view->cellview (m_cv_index)->layout ();
|
||||||
|
|
||||||
const db::Layout *layout = mp_database->internal_layout ();
|
const db::Layout *layout = mp_database->internal_layout ();
|
||||||
if (! layout) {
|
if (! layout) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// a map of display properties vs. layer properties
|
||||||
|
|
||||||
|
std::map<db::LayerProperties, lay::LayerPropertiesConstIterator> 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<unsigned int, std::vector<db::DCplxTrans> > tv_by_layer = mp_view->cv_transform_variants_by_layer (m_cv_index);
|
// @@@std::map<unsigned int, std::vector<db::DCplxTrans> > tv_by_layer = mp_view->cv_transform_variants_by_layer (m_cv_index);
|
||||||
std::vector<db::DCplxTrans> tv = mp_view->cv_transform_variants (m_cv_index);
|
std::vector<db::DCplxTrans> tv = mp_view->cv_transform_variants (m_cv_index);
|
||||||
|
|
||||||
|
|
@ -2228,7 +2251,8 @@ NetlistBrowserPage::update_highlights ()
|
||||||
const db::Connectivity &conn = mp_database->connectivity ();
|
const db::Connectivity &conn = mp_database->connectivity ();
|
||||||
for (db::Connectivity::layer_iterator layer = conn.begin_layers (); layer != conn.end_layers (); ++layer) {
|
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<db::LayerProperties, lay::LayerPropertiesConstIterator>::const_iterator display = display_by_lp.find (lp);
|
||||||
|
|
||||||
db::recursive_cluster_shape_iterator<db::PolygonRef> shapes (mp_database->net_clusters (), *layer, cell_index, cluster_id);
|
db::recursive_cluster_shape_iterator<db::PolygonRef> shapes (mp_database->net_clusters (), *layer, cell_index, cluster_id);
|
||||||
while (! shapes.at_end ()) {
|
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.push_back (new lay::Marker (mp_view, m_cv_index));
|
||||||
mp_markers.back ()->set (*shapes, shapes.trans (), tv);
|
mp_markers.back ()->set (*shapes, shapes.trans (), tv);
|
||||||
|
|
||||||
#if 0
|
if (net_color.isValid ()) {
|
||||||
// @@@
|
|
||||||
if (! original.at_end ()) {
|
mp_markers.back ()->set_color (net_color);
|
||||||
mp_markers.back ()->set_line_width (original->width (true));
|
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_vertex_size (1);
|
||||||
mp_markers.back ()->set_dither_pattern (original->dither_pattern (true));
|
mp_markers.back ()->set_dither_pattern (display->second->dither_pattern (true));
|
||||||
if (view ()->background_color ().green () < 128) {
|
if (mp_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_color (display->second->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_frame_color (display->second->eff_frame_color_brighter (true, (m_marker_intensity * 255) / 100));
|
||||||
} else {
|
} else {
|
||||||
mp_markers.back ()->set_color (original->eff_fill_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 (original->eff_frame_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) {
|
if (m_marker_line_width >= 0) {
|
||||||
mp_markers.back ()->set_line_width (m_marker_line_width);
|
mp_markers.back ()->set_line_width (m_marker_line_width);
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,8 @@ private:
|
||||||
*/
|
*/
|
||||||
class NetlistBrowserPage
|
class NetlistBrowserPage
|
||||||
: public QFrame,
|
: public QFrame,
|
||||||
public Ui::NetlistBrowserPage
|
public Ui::NetlistBrowserPage,
|
||||||
|
public tl::Object
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
|
@ -340,6 +341,7 @@ private:
|
||||||
void highlight_nets (const std::vector<const db::Net *> &nets);
|
void highlight_nets (const std::vector<const db::Net *> &nets);
|
||||||
std::vector<const db::Net *> selected_nets ();
|
std::vector<const db::Net *> selected_nets ();
|
||||||
void set_color_for_selected_nets (const QColor &color);
|
void set_color_for_selected_nets (const QColor &color);
|
||||||
|
void layer_list_changed (int);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace lay
|
} // namespace lay
|
||||||
|
|
|
||||||
|
|
@ -9,15 +9,15 @@ unit(0.001)
|
||||||
# This section lists the mask layers (drawing or derived) and their connections.
|
# This section lists the mask layers (drawing or derived) and their connections.
|
||||||
|
|
||||||
# Mask layers
|
# Mask layers
|
||||||
layer(poly)
|
layer(poly '3/0')
|
||||||
layer(poly_lbl)
|
layer(poly_lbl '3/1')
|
||||||
layer(diff_cont)
|
layer(diff_cont '4/0')
|
||||||
layer(poly_cont)
|
layer(poly_cont '5/0')
|
||||||
layer(metal1)
|
layer(metal1 '6/0')
|
||||||
layer(metal1_lbl)
|
layer(metal1_lbl '6/1')
|
||||||
layer(via1)
|
layer(via1 '7/0')
|
||||||
layer(metal2)
|
layer(metal2 '8/0')
|
||||||
layer(metal2_lbl)
|
layer(metal2_lbl '8/1')
|
||||||
layer(psd)
|
layer(psd)
|
||||||
layer(nsd)
|
layer(nsd)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,16 +10,16 @@ unit(0.001)
|
||||||
|
|
||||||
# Mask layers
|
# Mask layers
|
||||||
layer(rbulk)
|
layer(rbulk)
|
||||||
layer(nwell)
|
layer(nwell '1/0')
|
||||||
layer(poly)
|
layer(poly '3/0')
|
||||||
layer(poly_lbl)
|
layer(poly_lbl '3/1')
|
||||||
layer(diff_cont)
|
layer(diff_cont '4/0')
|
||||||
layer(poly_cont)
|
layer(poly_cont '5/0')
|
||||||
layer(metal1)
|
layer(metal1 '6/0')
|
||||||
layer(metal1_lbl)
|
layer(metal1_lbl '6/1')
|
||||||
layer(via1)
|
layer(via1 '7/0')
|
||||||
layer(metal2)
|
layer(metal2 '8/0')
|
||||||
layer(metal2_lbl)
|
layer(metal2_lbl '8/1')
|
||||||
layer(ntie)
|
layer(ntie)
|
||||||
layer(psd)
|
layer(psd)
|
||||||
layer(ptie)
|
layer(ptie)
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,16 @@
|
||||||
W(RINGO)
|
W(RINGO)
|
||||||
U(0.001)
|
U(0.001)
|
||||||
L(rbulk)
|
L(rbulk)
|
||||||
L(nwell)
|
L(nwell '1/0')
|
||||||
L(poly)
|
L(poly '3/0')
|
||||||
L(poly_lbl)
|
L(poly_lbl '3/1')
|
||||||
L(diff_cont)
|
L(diff_cont '4/0')
|
||||||
L(poly_cont)
|
L(poly_cont '5/0')
|
||||||
L(metal1)
|
L(metal1 '6/0')
|
||||||
L(metal1_lbl)
|
L(metal1_lbl '6/1')
|
||||||
L(via1)
|
L(via1 '7/0')
|
||||||
L(metal2)
|
L(metal2 '8/0')
|
||||||
L(metal2_lbl)
|
L(metal2_lbl '8/1')
|
||||||
L(ntie)
|
L(ntie)
|
||||||
L(psd)
|
L(psd)
|
||||||
L(ptie)
|
L(ptie)
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
#%l2n-klayout
|
#%l2n-klayout
|
||||||
W(RINGO)
|
W(RINGO)
|
||||||
U(0.001)
|
U(0.001)
|
||||||
L(poly)
|
L(poly '3/0')
|
||||||
L(poly_lbl)
|
L(poly_lbl '3/1')
|
||||||
L(diff_cont)
|
L(diff_cont '4/0')
|
||||||
L(poly_cont)
|
L(poly_cont '5/0')
|
||||||
L(metal1)
|
L(metal1 '6/0')
|
||||||
L(metal1_lbl)
|
L(metal1_lbl '6/1')
|
||||||
L(via1)
|
L(via1 '7/0')
|
||||||
L(metal2)
|
L(metal2 '8/0')
|
||||||
L(metal2_lbl)
|
L(metal2_lbl '8/1')
|
||||||
L(psd)
|
L(psd)
|
||||||
L(nsd)
|
L(nsd)
|
||||||
C(poly poly poly_lbl poly_cont)
|
C(poly poly poly_lbl poly_cont)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue