diff --git a/src/drc/drc/built-in-macros/_drc_engine.rb b/src/drc/drc/built-in-macros/_drc_engine.rb index 5cd9fec55..f513aef6d 100644 --- a/src/drc/drc/built-in-macros/_drc_engine.rb +++ b/src/drc/drc/built-in-macros/_drc_engine.rb @@ -763,10 +763,17 @@ module DRC name = filename && File::basename(filename) name ||= "DRC" - lv = RBA::LayoutView::current - if lv - @output_rdb_index = lv.create_rdb(name) - @output_rdb = lv.rdb(@output_rdb_index) + @output_rdb_index = nil + + view = RBA::LayoutView::current + if view + if self._rdb_index + @output_rdb = RBA::ReportDatabase::new("") # reuse existing name + @output_rdb_index = view.replace_rdb(self._rdb_index, @output_rdb) + else + @output_rdb = RBA::ReportDatabase::new(name) + @output_rdb_index = view.add_rdb(@output_rdb) + end else @output_rdb = RBA::ReportDatabase::new(name) end diff --git a/src/drc/drc/built-in-macros/_drc_netter.rb b/src/drc/drc/built-in-macros/_drc_netter.rb index a449ba5b1..1a7f70ef6 100644 --- a/src/drc/drc/built-in-macros/_drc_netter.rb +++ b/src/drc/drc/built-in-macros/_drc_netter.rb @@ -407,6 +407,7 @@ module DRC @l2n = RBA::LayoutToNetlist::new(layout.top_cell.name, layout.dbu) end + @l2n.name = "DRC" @l2n.generator = @engine._generator end diff --git a/src/drc/drc/built-in-macros/drc_interpreters.lym b/src/drc/drc/built-in-macros/drc_interpreters.lym index 5818c23d7..6ada00b60 100644 --- a/src/drc/drc/built-in-macros/drc_interpreters.lym +++ b/src/drc/drc/built-in-macros/drc_interpreters.lym @@ -17,37 +17,39 @@ module DRC - def DRC.execute_drc(_macro) + def DRC.execute_drc(macro, generator, rdb_index = nil) - _timer = RBA::Timer::new - _timer.start - _drc = DRCEngine::new + timer = RBA::Timer::new + timer.start + drc = DRCEngine::new + drc._rdb_index = rdb_index + drc._generator = generator begin # Set a debugger scope so that our errors end up with the debugger set to the DRC's line - RBA::MacroExecutionContext::set_debugger_scope(_macro.path) + RBA::MacroExecutionContext::set_debugger_scope(macro.path) # No verbosity set in drc engine - we cannot use the engine's logger - RBA::Logger::verbosity >= 10 && RBA::Logger::info("Running #{_macro.path}") - _drc.instance_eval(_macro.text, _macro.path) + RBA::Logger::verbosity >= 10 && RBA::Logger::info("Running #{macro.path}") + drc.instance_eval(macro.text, macro.path) # Remove the debugger scope RBA::MacroExecutionContext::remove_debugger_scope rescue => ex - _drc.error("In #{_macro.path}: #{ex.to_s}") + drc.error("In #{macro.path}: #{ex.to_s}") RBA::MacroExecutionContext::ignore_next_exception raise ex ensure # cleans up and creates layout and report views - _drc._finish + drc._finish end - _timer.stop - _drc.info("Total run time: #{'%.3f'%(_timer.sys+_timer.user)}s") + timer.stop + drc.info("Total run time: #{'%.3f'%(timer.sys+timer.user)}s") end @@ -55,7 +57,9 @@ module DRC class DRCInterpreter < RBA::MacroInterpreter # Constructor - def initialize + def initialize(recipe) + + @recipe = recipe # Make the DSL use ruby syntax highlighting self.syntax_scheme = "ruby" @@ -74,8 +78,7 @@ module DRC # Implements the execute method def execute(macro) - $0 = macro.path - DRC::execute_drc(macro) + DRC::execute_drc(macro, @recipe.generator("script" => macro.path)) end end @@ -84,7 +87,9 @@ module DRC class DRCPlainTextInterpreter < RBA::MacroInterpreter # Constructor - def initialize + def initialize(recipe) + + @recipe = recipe # Make the DSL use ruby syntax highlighting self.syntax_scheme = "ruby" @@ -100,14 +105,40 @@ module DRC # Implements the execute method def execute(macro) - DRC::execute_drc(macro) + DRC::execute_drc(macro, @recipe.generator("script" => macro.path)) end end + # A recipe implementation allowing the LVS run to be redone + class DRCRecipe < RBA::Recipe + + def initialize + super("drc", "DRC recipe") + end + + def execute(params) + + script = params["script"] + if ! script + return + end + + macro = RBA::Macro::macro_by_path(script) + macro || raise("Can't find DRC script #{script} - unable to re-run") + + DRC::execute_drc(macro, self.generator("script" => script), params["rdb_index"]) + + end + + end + + # Register the recipe + drc_recipe = DRCRecipe::new + # Register the new interpreters - DRCInterpreter::new - DRCPlainTextInterpreter::new + DRCInterpreter::new(drc_recipe) + DRCPlainTextInterpreter::new(drc_recipe) end diff --git a/src/laybasic/laybasic/MarkerBrowserDialog.ui b/src/laybasic/laybasic/MarkerBrowserDialog.ui index d7c11abb5..1a7dc53d0 100644 --- a/src/laybasic/laybasic/MarkerBrowserDialog.ui +++ b/src/laybasic/laybasic/MarkerBrowserDialog.ui @@ -1,7 +1,8 @@ - + + MarkerBrowserDialog - - + + 0 0 @@ -9,40 +10,75 @@ 553 - + Marker Database Browser - - - 9 - - + + 6 + + 9 + + + 9 + + + 9 + + + 9 + - - + + QFrame::NoFrame - + QFrame::Raised - - + + 0 - + + 0 + + + 0 + + + 0 + + 6 - + + + + File ... + + + QToolButton::InstantPopup + + + + + + + ... on layout + + + + - + Qt::Horizontal - + QSizePolicy::Fixed - + 20 20 @@ -50,152 +86,133 @@ - - - - - 7 - 0 + + + + 1 0 - + QComboBox::AdjustToContentsOnFirstShow - - - + + + Database - - - - ... on layout - - - - - - - - 7 - 0 + + + + 1 0 - + QComboBox::AdjustToContentsOnFirstShow - - - - File ... - - - QToolButton::InstantPopup - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 10 - - - - - - - Qt::Horizontal - - - - - - + + QFrame::NoFrame - + QFrame::Raised - - - 0 - - + + 6 + + 0 + + + 0 + + + 0 + + + 0 + - - + + 1 - - - - 0 - - + + + 6 + + 0 + + + 0 + + + 0 + + + 0 + - - - - 13 - 13 + + + 0 0 - + QFrame::NoFrame - + QFrame::Raised - - - - 0 - - + + + 6 + + 0 + + + 0 + + + 0 + + + 0 + - - - Choose "Open" from the "File ..." menu + + + Choose "Open" from the "File ..." menu to load a marker database - + Qt::AlignCenter - + true @@ -208,40 +225,49 @@ to load a marker database - - + + Qt::Horizontal - - + + QFrame::NoFrame - + QFrame::Raised - - - 0 - - + + 6 + + 0 + + + 0 + + + 0 + + + 0 + - - + + Configure - + Qt::Horizontal - + 40 20 @@ -250,8 +276,8 @@ to load a marker database - - + + Close @@ -266,6 +292,7 @@ to load a marker database rdb::MarkerBrowserPage QFrame
rdbMarkerBrowserPage.h
+ 1 @@ -282,11 +309,11 @@ to load a marker database MarkerBrowserDialog accept() - + 837 441 - + 881 387 diff --git a/src/laybasic/laybasic/MarkerBrowserPage.ui b/src/laybasic/laybasic/MarkerBrowserPage.ui index 682d9ae9c..d352c1916 100644 --- a/src/laybasic/laybasic/MarkerBrowserPage.ui +++ b/src/laybasic/laybasic/MarkerBrowserPage.ui @@ -13,7 +13,7 @@ Form - + 6 @@ -29,6 +29,73 @@ 0 + + + + + 0 + 0 + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + ... + + + + :/run.png:/run.png + + + F5 + + + true + + + + + + + Qt::Vertical + + + + 20 + 11 + + + + + + + + Qt::Horizontal + + + + + + @@ -63,69 +130,6 @@ 6 - - - - ... - - - - :/down.png:/down.png - - - - - - - ... - - - - :/up.png:/up.png - - - - - - - - 0 - 0 - - - - - 0 - 4 - - - - Qt::ActionsContextMenu - - - QAbstractItemView::ExtendedSelection - - - QAbstractItemView::SelectRows - - - true - - - true - - - true - - - - - - - Directory - - - @@ -237,6 +241,69 @@
+ + + + ... + + + + :/down.png:/down.png + + + + + + + ... + + + + :/up.png:/up.png + + + + + + + + 0 + 0 + + + + + 0 + 4 + + + + Qt::ActionsContextMenu + + + QAbstractItemView::ExtendedSelection + + + QAbstractItemView::SelectRows + + + true + + + true + + + true + + + + + + + Directory + + +
diff --git a/src/laybasic/laybasic/gsiDeclLayLayoutView.cc b/src/laybasic/laybasic/gsiDeclLayLayoutView.cc index 9dc052808..2e0b3d44c 100644 --- a/src/laybasic/laybasic/gsiDeclLayLayoutView.cc +++ b/src/laybasic/laybasic/gsiDeclLayLayoutView.cc @@ -1448,7 +1448,7 @@ Class decl_LayoutView (QT_EXTERNAL_BASE (QWidget) "lay", "Layou "@return The \\ReportDatabase object or nil if the index is not valid" ) + gsi::method ("add_rdb", &lay::LayoutView::add_rdb, gsi::arg ("db"), - "@brief Adds the given database to the view\n" + "@brief Adds the given report database to the view\n" "\n" "This method will add an existing database to the view. It will then appear in the marker database browser.\n" "A similar method is \\create_rdb which will create a new database within the view.\n" @@ -1457,6 +1457,15 @@ Class decl_LayoutView (QT_EXTERNAL_BASE (QWidget) "lay", "Layou "\n" "This method has been added in version 0.26." ) + + gsi::method ("replace_rdb", &lay::LayoutView::replace_rdb, gsi::arg ("db_index"), gsi::arg ("db"), + "@brief Replaces the report database with the given index\n" + "\n" + "If the index is not valid, the database will be added to the view (see \\add_rdb).\n" + "\n" + "@return The index of the database within the view (see \\rdb)\n" + "\n" + "This method has been added in version 0.26." + ) + gsi::method_ext ("create_rdb", &create_rdb, gsi::arg ("name"), "@brief Creates a new report database and returns the index of the new database\n" "@param name The name of the new report database\n" @@ -1496,7 +1505,7 @@ Class decl_LayoutView (QT_EXTERNAL_BASE (QWidget) "lay", "Layou "This method has been added in version 0.26." ) + gsi::method ("add_l2ndb", &lay::LayoutView::add_l2ndb, gsi::arg ("db"), - "@brief Adds the given database to the view\n" + "@brief Adds the given netlist database to the view\n" "\n" "This method will add an existing database to the view. It will then appear in the netlist database browser.\n" "A similar method is \\create_l2ndb which will create a new database within the view.\n" @@ -1506,7 +1515,7 @@ Class decl_LayoutView (QT_EXTERNAL_BASE (QWidget) "lay", "Layou "This method has been added in version 0.26." ) + gsi::method ("replace_l2ndb", &lay::LayoutView::replace_l2ndb, gsi::arg ("db_index"), gsi::arg ("db"), - "@brief Replaces the database with the given index\n" + "@brief Replaces the netlist database with the given index\n" "\n" "If the index is not valid, the database will be added to the view (see \\add_lvsdb).\n" "\n" diff --git a/src/laybasic/laybasic/layLayoutView.cc b/src/laybasic/laybasic/layLayoutView.cc index 3a2b0dbf2..b6d2f791a 100644 --- a/src/laybasic/laybasic/layLayoutView.cc +++ b/src/laybasic/laybasic/layLayoutView.cc @@ -7210,21 +7210,16 @@ LayoutView::add_l2ndb (db::LayoutToNetlist *l2ndb) unsigned int LayoutView::replace_l2ndb (unsigned int db_index, db::LayoutToNetlist *l2ndb) { + tl_assert (l2ndb != 0); + if (db_index < m_l2ndbs.size ()) { + // keep the name as it is used for reference in the browser for example std::string n = m_l2ndbs [db_index]->name (); + l2ndb->set_name (n); delete m_l2ndbs [db_index]; - m_l2ndbs.erase (m_l2ndbs.begin () + db_index); - - // keep old name if possible - if (l2ndb->name ().empty ()) { - l2ndb->set_name (n); - } else { - make_unique_name (l2ndb, m_l2ndbs.begin (), m_l2ndbs.end ()); - } - - m_l2ndbs.insert (m_l2ndbs.begin () + db_index, l2ndb); + m_l2ndbs [db_index] = l2ndb; // Mark this object as owned by us (for GSI) l2ndb->keep (); @@ -7280,7 +7275,7 @@ LayoutView::remove_l2ndb (unsigned int index) unsigned int LayoutView::add_rdb (rdb::Database *rdb) { - make_unique_name (rdb, m_l2ndbs.begin (), m_l2ndbs.end ()); + make_unique_name (rdb, m_rdbs.begin (), m_rdbs.end ()); m_rdbs.push_back (rdb); // Mark this object as owned by us (for GSI) @@ -7291,6 +7286,32 @@ LayoutView::add_rdb (rdb::Database *rdb) return (unsigned int)(m_rdbs.size () - 1); } +unsigned int +LayoutView::replace_rdb (unsigned int db_index, rdb::Database *rdb) +{ + tl_assert (rdb != 0); + + if (db_index < m_rdbs.size ()) { + + // keep name because it's used for reference in the browser for example + std::string n = m_rdbs [db_index]->name (); + rdb->set_name (n); + + delete m_rdbs [db_index]; + m_rdbs [db_index] = rdb; + + // Mark this object as owned by us (for GSI) + rdb->keep (); + + rdb_list_changed_event (); + + return db_index; + + } else { + return add_rdb (rdb); + } +} + rdb::Database * LayoutView::get_rdb (int index) { diff --git a/src/laybasic/laybasic/layLayoutView.h b/src/laybasic/laybasic/layLayoutView.h index 548dd499d..d562d74ca 100644 --- a/src/laybasic/laybasic/layLayoutView.h +++ b/src/laybasic/laybasic/layLayoutView.h @@ -2285,6 +2285,17 @@ public: */ unsigned int add_rdb (rdb::Database *rdb); + /** + * @brief Replaces a marker database + * + * The layout view will become owner of the database. + * If the index is not valid, the database will be added and the new index will be returned. + * + * @param db_index The index of the database to replace + * @param rdb The database to add + */ + unsigned int replace_rdb (unsigned int db_index, rdb::Database *rdb); + /** * @brief Get the marker database by index * diff --git a/src/laybasic/laybasic/layNetlistBrowserPage.cc b/src/laybasic/laybasic/layNetlistBrowserPage.cc index 22d8e06db..b47b7fd09 100644 --- a/src/laybasic/laybasic/layNetlistBrowserPage.cc +++ b/src/laybasic/laybasic/layNetlistBrowserPage.cc @@ -613,6 +613,7 @@ NetlistBrowserPage::rerun_macro () } } + void NetlistBrowserPage::info_button_pressed () { diff --git a/src/laybasic/laybasic/rdbMarkerBrowserDialog.cc b/src/laybasic/laybasic/rdbMarkerBrowserDialog.cc index 680540389..b599eeb58 100644 --- a/src/laybasic/laybasic/rdbMarkerBrowserDialog.cc +++ b/src/laybasic/laybasic/rdbMarkerBrowserDialog.cc @@ -671,6 +671,7 @@ MarkerBrowserDialog::update_content () m_reload_action->setEnabled (rdb != 0); browser_frame->enable_updates (false); // Avoid building the internal lists several times ... + browser_frame->set_rdb (0); // force update browser_frame->set_rdb (rdb); browser_frame->set_max_marker_count (m_max_marker_count); browser_frame->set_marker_style (m_marker_color, m_marker_line_width, m_marker_vertex_size, m_marker_halo, m_marker_dither_pattern); diff --git a/src/laybasic/laybasic/rdbMarkerBrowserPage.cc b/src/laybasic/laybasic/rdbMarkerBrowserPage.cc index 1948b6f95..ef268bb1b 100644 --- a/src/laybasic/laybasic/rdbMarkerBrowserPage.cc +++ b/src/laybasic/laybasic/rdbMarkerBrowserPage.cc @@ -26,6 +26,7 @@ #include "dbLayoutUtils.h" +#include "tlRecipe.h" #include "layLayoutView.h" #include "layMarker.h" @@ -1463,7 +1464,8 @@ MarkerBrowserPage::MarkerBrowserPage (QWidget * /*parent*/) m_marker_list_sort_order (Qt::DescendingOrder), m_directory_tree_sorted_section (-1), m_directory_tree_sort_order (Qt::DescendingOrder), - mp_plugin_root (0) + mp_plugin_root (0), + dm_rerun_macro (this, &MarkerBrowserPage::rerun_macro) { Ui::MarkerBrowserPage::setupUi (this); @@ -1514,6 +1516,7 @@ MarkerBrowserPage::MarkerBrowserPage (QWidget * /*parent*/) connect (info_text, SIGNAL (anchorClicked (const QUrl &)), this, SLOT (info_anchor_clicked (const QUrl &))); connect (cat_filter, SIGNAL (textEdited (const QString &)), this, SLOT (filter_changed ())); connect (cell_filter, SIGNAL (textEdited (const QString &)), this, SLOT (filter_changed ())); + connect (rerun_button, SIGNAL (pressed ()), this, SLOT (rerun_button_pressed ())); m_show_all_action = new QAction (QObject::tr ("Show All"), this); m_show_all_action->setCheckable (true); @@ -1678,6 +1681,17 @@ MarkerBrowserPage::set_rdb (rdb::Database *database) mp_database = database; + rerun_button->setEnabled (mp_database && ! mp_database->generator ().empty ()); + if (rerun_button->isEnabled ()) { + QString shortcut; + if (! rerun_button->shortcut ().isEmpty ()) { + shortcut = QString::fromUtf8 (" (%1)").arg (rerun_button->shortcut ().toString ()); + } + rerun_button->setToolTip (tl::to_qstring (tl::to_string (tr ("Run ")) + mp_database->generator ()) + shortcut); + } else { + rerun_button->setToolTip (QString ()); + } + QAbstractItemModel *tree_model = directory_tree->model (); MarkerBrowserTreeViewModel *new_model = new MarkerBrowserTreeViewModel (); @@ -2643,6 +2657,32 @@ MarkerBrowserPage::flag_button_clicked () list_model->mark_data_changed (); } +void +MarkerBrowserPage::rerun_button_pressed () +{ + // NOTE: we use deferred execution, because otherwise the button won't get repainted properly + dm_rerun_macro (); +} + +void +MarkerBrowserPage::rerun_macro () +{ + if (! mp_database->generator ().empty ()) { + + std::map add_pars; + + for (unsigned int i = 0; i < mp_view->num_rdbs (); ++i) { + if (mp_view->get_rdb (i) == mp_database) { + add_pars["rdb_index"] = tl::Variant (int (i)); + break; + } + } + + tl::Recipe::make (mp_database->generator (), add_pars); + + } +} + void MarkerBrowserPage::flag_menu_selected () { diff --git a/src/laybasic/laybasic/rdbMarkerBrowserPage.h b/src/laybasic/laybasic/rdbMarkerBrowserPage.h index 66cd279a9..508bbf050 100644 --- a/src/laybasic/laybasic/rdbMarkerBrowserPage.h +++ b/src/laybasic/laybasic/rdbMarkerBrowserPage.h @@ -26,6 +26,7 @@ #include "ui_MarkerBrowserPage.h" #include "rdbMarkerBrowser.h" +#include "tlDeferredExecution.h" #include "dbBox.h" #include @@ -155,6 +156,7 @@ public slots: void dir_down_clicked (); void list_up_clicked (); void list_down_clicked (); + void rerun_button_pressed (); void flag_button_clicked (); void flag_menu_selected (); void important_button_clicked (); @@ -205,6 +207,7 @@ private: int m_directory_tree_sorted_section; Qt::SortOrder m_directory_tree_sort_order; lay::PluginRoot *mp_plugin_root; + tl::DeferredMethod dm_rerun_macro; void release_markers (); void update_marker_list (int selection_mode); @@ -214,6 +217,7 @@ private: void mark_visited (bool visited); void do_update_markers (); void update_info_text (); + void rerun_macro (); }; } // namespace rdb diff --git a/src/lvs/lvs/built-in-macros/_lvs_netter.rb b/src/lvs/lvs/built-in-macros/_lvs_netter.rb index 9649cb49e..26f45bb00 100644 --- a/src/lvs/lvs/built-in-macros/_lvs_netter.rb +++ b/src/lvs/lvs/built-in-macros/_lvs_netter.rb @@ -61,6 +61,7 @@ module LVS @lvs = RBA::LayoutVsSchematic::new(cell.name, layout.dbu) end + @lvs.name = "LVS" @lvs.generator = @engine._generator @l2n = @lvs