diff --git a/src/laybasic/laybasic/gsiDeclLayLayoutView.cc b/src/laybasic/laybasic/gsiDeclLayLayoutView.cc index fb82f6878..a01db5183 100644 --- a/src/laybasic/laybasic/gsiDeclLayLayoutView.cc +++ b/src/laybasic/laybasic/gsiDeclLayLayoutView.cc @@ -2188,6 +2188,22 @@ Class decl_CellView ("lay", "CellView", "fashion, i.e. describing each instance in detail, not just by cell indexes. If " "the context and target cell are identical, the context path is empty." ) + + method ("context_trans", &lay::CellViewRef::context_trans, + "@brief Gets the accumulated transformation of the context path\n" + "This is the transformation applied to the target cell before it is shown in the context cell\n" + "Technically this is the product of all transformations over the context path.\n" + "See \\context_dtrans for a version delivering a micron-unit space transformation.\n" + "\n" + "This method has been introduced in version 0.27.3.\n" + ) + + method ("context_dtrans", &lay::CellViewRef::context_dtrans, + "@brief Gets the accumulated transformation of the context path in micron unit space\n" + "This is the transformation applied to the target cell before it is shown in the context cell\n" + "Technically this is the product of all transformations over the context path.\n" + "See \\context_trans for a version delivering an integer-unit space transformation.\n" + "\n" + "This method has been introduced in version 0.27.3.\n" + ) + event_ext ("on_technology_changed", &get_technology_changed_event, "@brief An event indicating that the technology has changed\n" "This event is triggered when the CellView is attached to a different technology.\n" diff --git a/src/laybasic/laybasic/layCellView.cc b/src/laybasic/laybasic/layCellView.cc index 941ca71fa..dafded284 100644 --- a/src/laybasic/laybasic/layCellView.cc +++ b/src/laybasic/laybasic/layCellView.cc @@ -656,6 +656,16 @@ CellView::context_trans () const return trans; } +db::DCplxTrans +CellView::context_dtrans () const +{ + tl_assert (m_layout_href.get () != 0); + + db::CplxTrans dbu_trans (m_layout_href->layout ().dbu ()); + return dbu_trans * context_trans () * dbu_trans.inverted (); +} + + // ------------------------------------------------------------- // CellView implementation @@ -824,5 +834,15 @@ CellViewRef::context_trans () const } } +db::DCplxTrans +CellViewRef::context_dtrans () const +{ + if (is_valid ()) { + return mp_cv->context_dtrans (); + } else { + return db::DCplxTrans (); + } +} + } diff --git a/src/laybasic/laybasic/layCellView.h b/src/laybasic/laybasic/layCellView.h index 081e36260..e2239e999 100644 --- a/src/laybasic/laybasic/layCellView.h +++ b/src/laybasic/laybasic/layCellView.h @@ -522,6 +522,11 @@ public: */ db::ICplxTrans context_trans () const; + /** + * @brief Retrive the accumulated transformation induced by the context part of the path as a micron-unit transformation + */ + db::DCplxTrans context_dtrans () const; + /** * @brief Deep copy of the cellview * @@ -730,6 +735,11 @@ public: */ db::ICplxTrans context_trans () const; + /** + * @brief Retrive the accumulated transformation induced by the context part of the path in micron units + */ + db::DCplxTrans context_dtrans() const; + private: tl::weak_ptr mp_cv; tl::weak_ptr mp_view; diff --git a/src/laybasic/laybasic/layNetlistBrowserPage.cc b/src/laybasic/laybasic/layNetlistBrowserPage.cc index e628cfcb8..61b905767 100644 --- a/src/laybasic/laybasic/layNetlistBrowserPage.cc +++ b/src/laybasic/laybasic/layNetlistBrowserPage.cc @@ -69,10 +69,11 @@ inline const db::Circuit *deref_circuit (const db::Circuit *obj) } template -static db::DCplxTrans +static std::pair trans_for (const Obj *objs, const db::Layout &ly, const db::Cell &cell, db::ContextCache &cc, const db::DCplxTrans &initial = db::DCplxTrans ()) { db::DCplxTrans t = initial; + bool good = true; const db::Circuit *circuit = deref_circuit (objs); while (circuit) { @@ -98,10 +99,12 @@ trans_for (const Obj *objs, const db::Layout &ly, const db::Cell &cell, db::Cont std::pair tc = cc.find_layout_context (circuit->cell_index (), cell.cell_index ()); if (tc.first) { t = dbu_trans * tc.second * dbu_trans.inverted () * t; + } else { + good = false; } } - return t; + return std::make_pair (good, t); } NetlistBrowserPage::NetlistBrowserPage (QWidget * /*parent*/) @@ -978,11 +981,14 @@ NetlistBrowserPage::adjust_view () return; } - const db::Layout &original_layout = mp_view->cellview (m_cv_index)->layout (); - const db::Circuit *top_circuit = mp_database->netlist ()->circuit_by_name (original_layout.cell_name (mp_view->cellview (m_cv_index).cell_index ())); + const db::Layout &original_layout = cv->layout (); + const db::Circuit *top_circuit = mp_database->netlist ()->circuit_by_name (original_layout.cell_name (cv.cell_index ())); + if (! top_circuit) { + return; + } const db::Layout *layout = mp_database->internal_layout (); - const db::Cell *cell = (top_circuit && layout->is_valid_cell_index (top_circuit->cell_index ()) ? &layout->cell (top_circuit->cell_index ()) : mp_database->internal_top_cell ()); + const db::Cell *cell = layout->is_valid_cell_index (top_circuit->cell_index ()) ? &layout->cell (top_circuit->cell_index ()) : mp_database->internal_top_cell (); if (! layout || ! cell) { return; } @@ -996,9 +1002,12 @@ NetlistBrowserPage::adjust_view () continue; } - db::DCplxTrans trans; + std::pair tr = trans_for (circuit, *layout, *cell, m_cell_context_cache, cv.context_dtrans ()); + if (! tr.first) { + continue; + } - trans = trans_for (circuit, *layout, *cell, m_cell_context_cache, db::DCplxTrans ()); + db::DCplxTrans trans = tr.second; for (std::list >::const_iterator p = path->path.begin (); p != path->path.end () && circuit; ++p) { if (p->first) { @@ -1273,11 +1282,19 @@ NetlistBrowserPage::update_highlights () return; } - const db::Layout &original_layout = mp_view->cellview (m_cv_index)->layout (); - const db::Circuit *top_circuit = mp_database->netlist ()->circuit_by_name (original_layout.cell_name (mp_view->cellview (m_cv_index).cell_index ())); + const lay::CellView &cv = mp_view->cellview (m_cv_index); + if (! cv.is_valid ()) { + return; + } + + const db::Layout &original_layout = cv->layout (); + const db::Circuit *top_circuit = mp_database->netlist ()->circuit_by_name (original_layout.cell_name (cv.cell_index ())); + if (! top_circuit) { + return; + } const db::Layout *layout = mp_database->internal_layout (); - const db::Cell *cell = (top_circuit && layout->is_valid_cell_index (top_circuit->cell_index ()) ? &layout->cell (top_circuit->cell_index ()) : mp_database->internal_top_cell ()); + const db::Cell *cell = layout->is_valid_cell_index (top_circuit->cell_index ()) ? &layout->cell (top_circuit->cell_index ()) : mp_database->internal_top_cell (); if (! layout || ! cell) { return; } @@ -1301,7 +1318,12 @@ NetlistBrowserPage::update_highlights () // computes the transformation supplied by the path - db::DCplxTrans trans = trans_for (circuit, *layout, *cell, m_cell_context_cache, db::DCplxTrans ()); + std::pair tr = trans_for (circuit, *layout, *cell, m_cell_context_cache, cv.context_dtrans ()); + if (! tr.first) { + continue; + } + + db::DCplxTrans trans = tr.second; for (std::list >::const_iterator p = path->path.begin (); p != path->path.end () && circuit; ++p) { if (p->first) { diff --git a/src/plugins/tools/net_tracer/lay_plugin/layNetTracerDialog.cc b/src/plugins/tools/net_tracer/lay_plugin/layNetTracerDialog.cc index 3c7da9d8b..7f4006ee4 100644 --- a/src/plugins/tools/net_tracer/lay_plugin/layNetTracerDialog.cc +++ b/src/plugins/tools/net_tracer/lay_plugin/layNetTracerDialog.cc @@ -1707,8 +1707,7 @@ NetTracerDialog::trace_all_nets (db::LayoutToNetlist *l2ndb, const lay::CellView l2ndb->clear_join_nets (); l2ndb->clear_join_net_names (); - // include floating subcircuits for netlist to flatten - l2ndb->set_include_floating_subcircuits (flat); + l2ndb->set_include_floating_subcircuits (true); l2ndb->extract_netlist (); if (flat) { diff --git a/testdata/ruby/layLayoutView.rb b/testdata/ruby/layLayoutView.rb index 8ed0b6817..4608365e1 100644 --- a/testdata/ruby/layLayoutView.rb +++ b/testdata/ruby/layLayoutView.rb @@ -242,6 +242,8 @@ class LAYLayoutView_TestClass < TestBase assert_equal(view.cellview(1).cell.name, "INV2") assert_equal(cv2.path.collect { |p| cv2.layout.cell(p).name }.join(","), "RINGO,INV2") assert_equal(cv2.context_path.collect { |p| p.to_s }.join(","), "") + assert_equal(cv2.context_trans.to_s, "r0 *1 0,0") + assert_equal(cv2.context_dtrans.to_s, "r0 *1 0,0") assert_equal(active_cellview_changed, 0) assert_equal(cellviews_changed, 0) @@ -294,6 +296,8 @@ class LAYLayoutView_TestClass < TestBase cv2.context_path = sp assert_equal(cv2.context_path.collect { |p| p.inst.cell.name + ":" + p.specific_cplx_trans.to_s }.join(","), "TRANS:r0 *1 -400,0") + assert_equal(cv2.context_trans.to_s, "r0 *1 -400,0") + assert_equal(cv2.context_dtrans.to_s, "r0 *1 -0.4,0") assert_equal(cv2.cell_name, "TRANS") assert_equal(cv2.ctx_cell.name, "INV2")