diff --git a/src/lay/lay/doc/manual/net_tracing.xml b/src/lay/lay/doc/manual/net_tracing.xml index cdb8a1271..b903ae388 100644 --- a/src/lay/lay/doc/manual/net_tracing.xml +++ b/src/lay/lay/doc/manual/net_tracing.xml @@ -53,6 +53,20 @@ the "Trace Net" button again.

+

+ Sometimes you encounter large nets (e.g. power nets). When you click on such a net, the tracer will start running and + the extraction will take a long time. If you're not interested in the details of such nets, you can limit the depth + of the net tracing. This means, after a specified number of shapes is encountered, the tracer will stop and report + the shapes collected so far as an incomplete net. +

+ +

+ To configure the depth, enter the desired number of shapes in the + "Trace depth" box at the bottom of the trace dialog. NOTE: the actual number of shapes in the net may be a litte + less than the specified depth due to internal marker shapes which are taken into account, but are not delivered + as parts of the net. +

+

The "Trace Path" function works similar but allows specification of two points and let the algorithm find the shortest connection (in terms of shape count, not geometrical length) between those points. If the points are not connected, a message is given diff --git a/src/plugins/tools/net_tracer/db_plugin/dbNetTracer.cc b/src/plugins/tools/net_tracer/db_plugin/dbNetTracer.cc index 3c2977979..7b7bede12 100644 --- a/src/plugins/tools/net_tracer/db_plugin/dbNetTracer.cc +++ b/src/plugins/tools/net_tracer/db_plugin/dbNetTracer.cc @@ -840,7 +840,7 @@ NetTracerLayerExpression::make_l2n_region (db::LayoutToNetlist &l2n, std::map 0 && m_shapes_found.size () >= m_trace_depth) { + throw tl::BreakException (); + } + std::pair::iterator, bool> f = m_shapes_found.insert (net_shape); if (f.second) { if (mp_progress) { @@ -1326,6 +1341,10 @@ NetTracer::deliver_shape (const NetTracerShape &net_shape, const NetTracerShape std::map >::iterator n = m_shapes_graph.find (net_shape); if (n == m_shapes_graph.end ()) { + if (m_trace_depth > 0 && m_shapes_graph.size () >= m_trace_depth) { + throw tl::BreakException (); + } + n = m_shapes_graph.insert (std::make_pair (net_shape, std::vector ())).first; if (mp_progress) { diff --git a/src/plugins/tools/net_tracer/db_plugin/dbNetTracer.h b/src/plugins/tools/net_tracer/db_plugin/dbNetTracer.h index 4deabf29d..251131905 100644 --- a/src/plugins/tools/net_tracer/db_plugin/dbNetTracer.h +++ b/src/plugins/tools/net_tracer/db_plugin/dbNetTracer.h @@ -695,6 +695,24 @@ public: return m_shapes_found.end (); } + /** + * @brief Sets the maximum number of shapes to trace + * + * Setting the trace depth to 0 is equivalent to "unlimited". + */ + void set_trace_depth (size_t n) + { + m_trace_depth = n; + } + + /** + * @brief Gets the maximum number of shapes to trace + */ + size_t trace_depth () const + { + return m_trace_depth; + } + /** * @brief Returns the number of shapes found */ @@ -707,7 +725,7 @@ public: * @brief Returns true, if the net is incomplete * * This flag is true if the extractor was aborted - * for example by the user. + * for example by the user or the trace depth was exhausted. * The shapes do not fully cover the net. */ bool incomplete () const @@ -759,6 +777,7 @@ private: std::string m_name; int m_name_hier_depth; bool m_incomplete; + size_t m_trace_depth; NetTracerShape m_stop_shape; NetTracerShape m_start_shape; db::EdgeProcessor m_ep; diff --git a/src/plugins/tools/net_tracer/db_plugin/gsiDeclDbNetTracer.cc b/src/plugins/tools/net_tracer/db_plugin/gsiDeclDbNetTracer.cc index bca7e6d99..c5606cd27 100644 --- a/src/plugins/tools/net_tracer/db_plugin/gsiDeclDbNetTracer.cc +++ b/src/plugins/tools/net_tracer/db_plugin/gsiDeclDbNetTracer.cc @@ -227,6 +227,22 @@ gsi::Class decl_NetTracer ("db", "NetTracer", "The net name is extracted from labels found during the extraction. " "This attribute is useful only after the extraction has been performed." ) + + gsi::method ("trace_depth=", &db::NetTracer::set_trace_depth, gsi::arg ("n"), + "@brief Sets the trace depth (shape limit)\n" + "Set this value to limit the maximum number of shapes delivered. Upon reaching this count, " + "the tracer will stop and report the net as 'incomplete' (see \\incomplete?).\n" + "Setting a trace depth if 0 is equivalent to 'unlimited'.\n" + "The actual number of shapes delivered may be a little less than the depth because of " + "internal marker shapes which are taken into account, but are not delivered.\n" + "\n" + "This method has been introduced in version 0.26.4.\n" + ) + + gsi::method ("trace_depth", &db::NetTracer::trace_depth, + "@brief gets the trace depth\n" + "See \\trace_depth= for a description of this property.\n" + "\n" + "This method has been introduced in version 0.26.4.\n" + ) + gsi::method ("incomplete?", &db::NetTracer::incomplete, "@brief Returns a value indicating whether the net is incomplete\n" "A net may be incomplete if the extraction has been stopped by the user for example. " diff --git a/src/plugins/tools/net_tracer/lay_plugin/NetTracerDialog.ui b/src/plugins/tools/net_tracer/lay_plugin/NetTracerDialog.ui index aa6d47d46..823a74505 100644 --- a/src/plugins/tools/net_tracer/lay_plugin/NetTracerDialog.ui +++ b/src/plugins/tools/net_tracer/lay_plugin/NetTracerDialog.ui @@ -29,7 +29,24 @@ 6 - + + + + Qt::Horizontal + + + + + + + Configure + + + false + + + + @@ -50,41 +67,175 @@ Select one or multiple nets and choose "Export" to export the selected - - - - - 0 - 0 - + + + + + 0 + 0 + - - - 12 - 75 - false - true - + + QFrame::NoFrame - - Net Tracer + + QFrame::Raised + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Trace Net + + + true + + + false + + + true + + + + + + + Lock + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 10 + + + + + + + + Trace Path + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 10 + + + + + + + + Delete + + + + + + + Clear All + + + + + + + Qt::Vertical + + + + 11 + 261 + + + + + + + + Redo + + + + - - + + Qt::Horizontal + + QSizePolicy::Fixed + + + + 5 + 20 + + + + + + + + Trace depth: + - - + + - Configure + Close - - false + + + + + + + 1 + 0 + + + + @@ -98,7 +249,7 @@ Select one or multiple nets and choose "Export" to export the selected - + @@ -326,152 +477,47 @@ p, li { white-space: pre-wrap; } - - - - - 0 - 0 - - - - QFrame::NoFrame - - - QFrame::Raised - - - - 6 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Trace Net - - - true - - - false - - - true - - - - - - - Lock - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 10 - - - - - - - - Trace Path - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 10 - - - - - - - - Delete - - - - - - - Clear All - - - - - - - Qt::Vertical - - - - 11 - 261 - - - - - - - - Redo - - - - - - - - + + - - 1 + + 0 0 + + + 12 + 75 + false + true + + - + Net Tracer - - + + - Close + shapes + + + + + + + + 0 + 0 + + + + + 80 + 16777215 + diff --git a/src/plugins/tools/net_tracer/lay_plugin/layNetTracerConfig.cc b/src/plugins/tools/net_tracer/lay_plugin/layNetTracerConfig.cc index 64618b7cf..a8cfdcf73 100644 --- a/src/plugins/tools/net_tracer/lay_plugin/layNetTracerConfig.cc +++ b/src/plugins/tools/net_tracer/lay_plugin/layNetTracerConfig.cc @@ -41,6 +41,7 @@ extern const std::string cfg_nt_marker_intensity ("nt-marker-intensity"); extern const std::string cfg_nt_window_mode ("nt-window-mode"); extern const std::string cfg_nt_window_dim ("nt-window-dim"); extern const std::string cfg_nt_max_shapes_highlighted ("nt-max-shapes-highlighted"); +extern const std::string cfg_nt_trace_depth ("nt-trace_depth"); // ------------------------------------------------------------ diff --git a/src/plugins/tools/net_tracer/lay_plugin/layNetTracerConfig.h b/src/plugins/tools/net_tracer/lay_plugin/layNetTracerConfig.h index 6990c4141..7a3a7710e 100644 --- a/src/plugins/tools/net_tracer/lay_plugin/layNetTracerConfig.h +++ b/src/plugins/tools/net_tracer/lay_plugin/layNetTracerConfig.h @@ -44,6 +44,7 @@ extern const std::string cfg_nt_marker_intensity; extern const std::string cfg_nt_window_mode; extern const std::string cfg_nt_window_dim; extern const std::string cfg_nt_max_shapes_highlighted; +extern const std::string cfg_nt_trace_depth; enum nt_window_type { NTDontChange = 0, NTFitNet, NTCenter, NTCenterSize }; diff --git a/src/plugins/tools/net_tracer/lay_plugin/layNetTracerDialog.cc b/src/plugins/tools/net_tracer/lay_plugin/layNetTracerDialog.cc index f82b4150f..7a94781c6 100644 --- a/src/plugins/tools/net_tracer/lay_plugin/layNetTracerDialog.cc +++ b/src/plugins/tools/net_tracer/lay_plugin/layNetTracerDialog.cc @@ -394,16 +394,13 @@ NetTracerDialog::do_trace (const db::DBox &start_search_box, const db::DBox &sto } db::NetTracer net_tracer; + net_tracer.set_trace_depth (get_trace_depth ()); // and trace - try { - if (trace_path) { - net_tracer.trace (cv->layout (), *cv.cell (), start_point, start_layer, stop_point, stop_layer, tracer_data); - } else { - net_tracer.trace (cv->layout (), *cv.cell (), start_point, start_layer, tracer_data); - } - } catch (tl::BreakException &) { - // just keep the found shapes on break (user abort) + if (trace_path) { + net_tracer.trace (cv->layout (), *cv.cell (), start_point, start_layer, stop_point, stop_layer, tracer_data); + } else { + net_tracer.trace (cv->layout (), *cv.cell (), start_point, start_layer, tracer_data); } if (net_tracer.begin () == net_tracer.end ()) { @@ -433,8 +430,18 @@ NetTracerDialog::configure (const std::string &name, const std::string &value) need_update = true; - } else if (name == cfg_nt_marker_cycle_colors) { + } else if (name == cfg_nt_trace_depth) { + unsigned int n = 0; + tl::from_string (value, n); + if (n > 0) { + depth_le->setText (tl::to_qstring (tl::to_string (n))); + } else { + depth_le->setText (QString ()); + } + + } else if (name == cfg_nt_marker_cycle_colors) { + m_auto_colors.from_string (value, true); } else if (name == cfg_nt_marker_cycle_colors_enabled) { @@ -1113,6 +1120,7 @@ void NetTracerDialog::trace_path_button_clicked () { BEGIN_PROTECTED + commit (); net_list->setCurrentItem (0); m_mouse_state = 2; view ()->message (tl::to_string (QObject::tr ("Click on the first point in the net"))); @@ -1124,6 +1132,7 @@ void NetTracerDialog::trace_net_button_clicked () { BEGIN_PROTECTED + commit (); net_list->setCurrentItem (0); m_mouse_state = 1; view ()->message (tl::to_string (QObject::tr ("Click on a point in the net"))); @@ -1411,9 +1420,35 @@ BEGIN_PROTECTED END_PROTECTED } +size_t +NetTracerDialog::get_trace_depth() +{ + double n = 0.0; + try { + QString depth = depth_le->text ().trimmed (); + if (! depth.isEmpty ()) { + tl::from_string (tl::to_string (depth), n); + if (n < 0 || n > std::numeric_limits::max ()) { + n = 0.0; + } + } + } catch (...) { + // .. nothing yet .. + } + + return (size_t) n; +} + +void +NetTracerDialog::commit () +{ + root ()->config_set (cfg_nt_trace_depth, tl::to_string (get_trace_depth ())); +} + void NetTracerDialog::deactivated () { + commit (); clear_markers (); release_mouse (); } diff --git a/src/plugins/tools/net_tracer/lay_plugin/layNetTracerDialog.h b/src/plugins/tools/net_tracer/lay_plugin/layNetTracerDialog.h index 305741447..99ddd29b6 100644 --- a/src/plugins/tools/net_tracer/lay_plugin/layNetTracerDialog.h +++ b/src/plugins/tools/net_tracer/lay_plugin/layNetTracerDialog.h @@ -108,6 +108,8 @@ private: lay::FileDialog *mp_export_file_dialog; std::string m_export_file_name; + void commit (); + size_t get_trace_depth (); void update_highlights (); void adjust_view (); void clear_markers (); diff --git a/src/plugins/tools/net_tracer/unit_tests/dbNetTracer.cc b/src/plugins/tools/net_tracer/unit_tests/dbNetTracerTests.cc similarity index 95% rename from src/plugins/tools/net_tracer/unit_tests/dbNetTracer.cc rename to src/plugins/tools/net_tracer/unit_tests/dbNetTracerTests.cc index dfb204650..374ce61f4 100644 --- a/src/plugins/tools/net_tracer/unit_tests/dbNetTracer.cc +++ b/src/plugins/tools/net_tracer/unit_tests/dbNetTracerTests.cc @@ -90,7 +90,7 @@ static db::NetTracerNet trace (db::NetTracer &tracer, const db::Layout &layout, return db::NetTracerNet (tracer, db::ICplxTrans (), layout, cell.cell_index (), std::string (), std::string (), tracer_data); } -void run_test (tl::TestBase *_this, const std::string &file, const db::NetTracerTechnologyComponent &tc, const db::LayerProperties &lp_start, const db::Point &p_start, const std::string &file_au, const char *net_name = 0) +void run_test (tl::TestBase *_this, const std::string &file, const db::NetTracerTechnologyComponent &tc, const db::LayerProperties &lp_start, const db::Point &p_start, const std::string &file_au, const char *net_name = 0, size_t depth = 0) { db::Manager m; @@ -107,12 +107,18 @@ void run_test (tl::TestBase *_this, const std::string &file, const db::NetTracer const db::Cell &cell = layout_org.cell (*layout_org.begin_top_down ()); db::NetTracer tracer; + tracer.set_trace_depth (depth); db::NetTracerNet net = trace (tracer, layout_org, cell, tc, layer_for (layout_org, lp_start), p_start); if (net_name) { EXPECT_EQ (net.name (), std::string (net_name)); } + EXPECT_EQ (net.incomplete (), depth != 0); + if (depth > 0) { + EXPECT_EQ (net.size () <= depth, true); + } + db::Layout layout_net; net.export_net (layout_net, layout_net.cell (layout_net.add_cell ("NET"))); @@ -337,7 +343,19 @@ TEST(6) run_test (_this, file, tc, db::LayerProperties (1, 0), db::Point (-2250, -900), file_au, "IN_B"); } -TEST(7) +TEST(6b) +{ + std::string file = "t6.oas.gz"; + std::string file_au = "t6b_net.oas.gz"; + + db::NetTracerTechnologyComponent tc; + tc.add (connection ("1-10", "2", "3")); + tc.add (connection ("3", "4", "5")); + + run_test (_this, file, tc, db::LayerProperties (1, 0), db::Point (-2250, -900), file_au, "IN_B", 10); +} + +TEST(7) { std::string file = "t7.oas.gz"; std::string file_au = "t7_net.oas.gz"; diff --git a/src/plugins/tools/net_tracer/unit_tests/unit_tests.pro b/src/plugins/tools/net_tracer/unit_tests/unit_tests.pro index 5ce84dbf5..5a32713ef 100644 --- a/src/plugins/tools/net_tracer/unit_tests/unit_tests.pro +++ b/src/plugins/tools/net_tracer/unit_tests/unit_tests.pro @@ -6,8 +6,8 @@ TARGET = net_tracer_tests include($$PWD/../../../../lib_ut.pri) SOURCES = \ - dbNetTracer.cc \ - dbTraceAllNets.cc + dbTraceAllNets.cc \ + dbNetTracerTests.cc INCLUDEPATH += $$LAY_INC $$TL_INC $$DB_INC $$GSI_INC $$PWD/../db_plugin $$PWD/../../../common DEPENDPATH += $$LAY_INC $$TL_INC $$DB_INC $$GSI_INC $$PWD/../db_plugin $$PWD/../../../common diff --git a/testdata/net_tracer/t6b_net.oas.gz b/testdata/net_tracer/t6b_net.oas.gz new file mode 100644 index 000000000..4c232c3a5 Binary files /dev/null and b/testdata/net_tracer/t6b_net.oas.gz differ