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
+ 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