diff --git a/src/drc/drc/built-in-macros/_lvs_engine.rb b/src/drc/drc/built-in-macros/_lvs_engine.rb
new file mode 100644
index 000000000..7a7a65e06
--- /dev/null
+++ b/src/drc/drc/built-in-macros/_lvs_engine.rb
@@ -0,0 +1,30 @@
+# $autorun-early
+
+module LVS
+
+ include DRC
+
+ # The LVS engine
+
+ # %LVS%
+ # @scope
+ # @name global
+ # @brief LVS Reference: Global Functions
+ # Some functions are available on global level and can be used without any object.
+ # Most of them are convenience functions that basically act on some default object
+ # or provide function-like alternatives for the methods.
+ #
+ # LVS is built upon DRC. So all functions available in DRC are also available
+ # in LVS. In LVS, DRC functions are used to derive functional layers from original
+ # layers or specification of the layout source.
+
+ class LVSEngine < DRCEngine
+
+ def initialize
+ super
+ end
+
+ end
+
+end
+
diff --git a/src/drc/drc/built-in-macros/install.lym b/src/drc/drc/built-in-macros/install.lym
new file mode 100644
index 000000000..a4fcb9fcf
--- /dev/null
+++ b/src/drc/drc/built-in-macros/install.lym
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+ true
+ false
+
+ false
+
+
+ ruby
+
+
+# Installs the home menu entries (needs to be done on autorun, not autorun-early)
+
+if RBA::Application::instance && RBA::Application::instance.main_window
+
+ [ "drc", "lvs" ].each do |cat|
+
+ name = cat.upcase
+
+ mw = RBA::Application::instance.main_window
+ mw.menu.insert_menu("tools_menu.verification_group+", cat, name)
+
+ new_action = RBA::Action::new
+ new_action.title = "New #{name} Script"
+ new_action.on_triggered do
+ mw.show_macro_editor(cat, true)
+ end
+
+ mw.menu.insert_item("tools_menu.#{cat}.end", "new_script", new_action)
+
+ edit_action = RBA::Action::new
+ edit_action.title = "Edit #{name} Script"
+ edit_action.on_triggered do
+ mw.show_macro_editor(cat, false)
+ end
+
+ mw.menu.insert_item("tools_menu.#{cat}.end", "edit_script", edit_action)
+
+ end
+
+end
+
+
+
diff --git a/src/drc/drc/built-in-macros/lvs_interpreters.lym b/src/drc/drc/built-in-macros/lvs_interpreters.lym
new file mode 100644
index 000000000..882e8de5d
--- /dev/null
+++ b/src/drc/drc/built-in-macros/lvs_interpreters.lym
@@ -0,0 +1,130 @@
+
+
+
+
+
+
+
+
+ false
+ true
+
+ false
+
+
+ ruby
+
+
+module LVS
+
+ def LVS.execute_lvs(_macro)
+
+ _timer = RBA::Timer::new
+ _timer.start
+ _lvs = LVSEngine::new
+
+ begin
+
+ # Set a debugger scope so that our errors end up with the debugger set to the LVS's line
+ RBA::MacroExecutionContext::set_debugger_scope(_macro.path)
+ # No verbosity set in lvs engine - we cannot use the engine's logger
+ RBA::Logger::verbosity >= 10 && RBA::Logger::info("Running #{_macro.path}")
+ _lvs.instance_eval(_macro.text, _macro.path)
+ # Remove the debugger scope
+ RBA::MacroExecutionContext::remove_debugger_scope
+
+ rescue => ex
+
+ _lvs.error("In #{_macro.path}: #{ex.to_s}")
+ RBA::MacroExecutionContext::ignore_next_exception
+ raise ex
+
+ ensure
+
+ # cleans up and creates layout views
+ _lvs._finish
+
+ end
+
+ _timer.stop
+ _lvs.info("Total run time: #{'%.3f'%(_timer.sys+_timer.user)}s")
+
+ end
+
+ # A DSL implementation for a LVS language (XML format)
+ class LVSInterpreter < RBA::MacroInterpreter
+
+ # Constructor
+ def initialize
+
+ # Make the DSL use ruby syntax highlighting
+ self.syntax_scheme = "ruby"
+ self.suffix = "lylvs"
+ self.debugger_scheme = RBA::MacroInterpreter::RubyDebugger
+ self.storage_scheme = RBA::MacroInterpreter::MacroFormat
+ self.description = "LVS"
+
+ # Registers the new interpreter
+ register("lvs-dsl-xml")
+
+ # create a template for the macro editor:
+ mt = create_template("lvs")
+ mt.text = <<"END"
+# Read about LVS scripts in the User Manual under "Layout vs. Schematic (LVS)"
+# This is a sample:
+... (yet to do)
+END
+ mt.show_in_menu = true
+ mt.menu_path = "tools_menu.lvs.end"
+ mt.group_name = "lvs_scripts"
+ mt.description = "General;;LVS script (*.lylvs)\nA LVS script using KLayout's LVS language"
+ mt.category = "lvs"
+
+ # if available, create a menu branch
+ if RBA::Application::instance && RBA::Application::instance.main_window
+ mw = RBA::Application::instance.main_window
+ mw.menu.insert_menu("tools_menu.verification_group+", "lvs", "LVS")
+ end
+
+ end
+
+ # Implements the execute method
+ def execute(macro)
+ LVS::execute_lvs(macro)
+ end
+
+ end
+
+ # A DSL implementation for a LVS language (Plain text format)
+ class LVSPlainTextInterpreter < RBA::MacroInterpreter
+
+ # Constructor
+ def initialize
+
+ # Make the DSL use ruby syntax highlighting
+ self.syntax_scheme = "ruby"
+ self.suffix = "lvs"
+ self.debugger_scheme = RBA::MacroInterpreter::RubyDebugger
+ self.storage_scheme = RBA::MacroInterpreter::PlainTextWithHashAnnotationsFormat
+ self.description = "LVS (Text)"
+
+ # Registers the new interpreter
+ register("lvs-dsl")
+
+ end
+
+ # Implements the execute method
+ def execute(macro)
+ LVS::execute_lvs(macro)
+ end
+
+ end
+
+ # Register the new interpreters
+ LVSInterpreter::new
+ LVSPlainTextInterpreter::new
+
+end
+
+
+
diff --git a/src/drc/drc/drcResources.qrc b/src/drc/drc/drcResources.qrc
index 6af97f61d..8ab94011a 100644
--- a/src/drc/drc/drcResources.qrc
+++ b/src/drc/drc/drcResources.qrc
@@ -7,5 +7,8 @@
built-in-macros/_drc_source.rb
built-in-macros/_drc_tags.rb
built-in-macros/drc_interpreters.lym
+ built-in-macros/_lvs_engine.rb
+ built-in-macros/lvs_interpreters.lym
+ built-in-macros/install.lym
diff --git a/src/lay/lay/gsiDeclLayMainWindow.cc b/src/lay/lay/gsiDeclLayMainWindow.cc
index b04f54f37..332bef1ba 100644
--- a/src/lay/lay/gsiDeclLayMainWindow.cc
+++ b/src/lay/lay/gsiDeclLayMainWindow.cc
@@ -371,6 +371,13 @@ Class decl_MainWindow (QT_EXTERNAL_BASE (QMainWindow) "lay", "M
"\n"
"This event has been added in version 0.25.\n"
) +
+ gsi::method ("show_macro_editor", &lay::MainWindow::show_macro_editor, gsi::arg ("cat", std::string ()), gsi::arg ("add", false),
+ "@brief Shows the macro editor\n"
+ "If 'cat' is given, this category will be selected in the category tab. "
+ "If 'add' is true, the 'new macro' dialog will be opened.\n"
+ "\n"
+ "This method has been introduced in version 0.26.\n"
+ ) +
gsi::method ("cm_reset_window_state", &lay::MainWindow::cm_reset_window_state,
"@brief 'cm_reset_window_state' action (bound to a menu)"
"\n"
diff --git a/src/lay/lay/layMacroController.cc b/src/lay/lay/layMacroController.cc
index 28dde80c9..e14dcfcf8 100644
--- a/src/lay/lay/layMacroController.cc
+++ b/src/lay/lay/layMacroController.cc
@@ -78,6 +78,15 @@ static lay::MacroController::MacroCategory drc_cat ()
return cat;
}
+static lay::MacroController::MacroCategory lvs_cat ()
+{
+ lay::MacroController::MacroCategory cat;
+ cat.name = "lvs";
+ cat.description = tl::to_string (QObject::tr ("LVS"));
+ cat.folders.push_back ("lvs");
+ return cat;
+}
+
void
MacroController::finish ()
{
@@ -87,13 +96,14 @@ MacroController::finish ()
lym::MacroCollection::root ().add_folder (tl::to_string (QObject::tr ("Built-In")), ":/built-in-macros", "macros", true);
lym::MacroCollection::root ().add_folder (tl::to_string (QObject::tr ("Built-In")), ":/built-in-pymacros", "pymacros", true);
- // TODO: consider adding "drc" dynamically and allow more dynamic categories
+ // TODO: consider adding "drc" and "lvs" dynamically and allow more dynamic categories
// We can do so if we first load the macros with the initial interpreters, then do autorun (which creates DSL interpreters) and then
// register the remaining categories.
m_macro_categories.push_back (ruby_cat ());
m_macro_categories.push_back (python_cat ());
m_macro_categories.push_back (drc_cat ());
+ m_macro_categories.push_back (lvs_cat ());
// scans the macros from techs and packages (this will allow autorun-early on them)
// and updates m_external_paths
diff --git a/src/lay/lay/layMainWindow.cc b/src/lay/lay/layMainWindow.cc
index d30277913..349ad61ec 100644
--- a/src/lay/lay/layMainWindow.cc
+++ b/src/lay/lay/layMainWindow.cc
@@ -955,17 +955,10 @@ MainWindow::init_menu ()
MenuLayoutEntry::last ()
};
- MenuLayoutEntry drc_menu [] = {
- MenuLayoutEntry ("new_script", tl::to_string (QObject::tr ("New DRC Script")), SLOT (cm_new_drc_script ())),
- MenuLayoutEntry ("edit_script", tl::to_string (QObject::tr ("Edit DRC Script")), SLOT (cm_edit_drc_scripts ())),
- MenuLayoutEntry::last ()
- };
-
MenuLayoutEntry tools_menu [] = {
MenuLayoutEntry ("packages", tl::to_string (QObject::tr ("Manage Packages")), SLOT (cm_packages ())),
MenuLayoutEntry ("technologies", tl::to_string (QObject::tr ("Manage Technologies")), SLOT (cm_technologies ())),
MenuLayoutEntry::separator ("verification_group"),
- MenuLayoutEntry ("drc", tl::to_string (QObject::tr ("DRC")), drc_menu),
MenuLayoutEntry::separator ("post_verification_group"),
MenuLayoutEntry::last ()
};
@@ -4744,20 +4737,6 @@ MainWindow::show_macro_editor (const std::string &cat, bool add)
}
}
-void
-MainWindow::cm_edit_drc_scripts ()
-{
- // TODO: implement this as generic menu provided by the Interpreter
- show_macro_editor ("drc", false);
-}
-
-void
-MainWindow::cm_new_drc_script ()
-{
- // TODO: implement this as generic menu provided by the Interpreter
- show_macro_editor ("drc", true);
-}
-
void
MainWindow::cm_macro_editor ()
{
diff --git a/src/lay/lay/layMainWindow.h b/src/lay/lay/layMainWindow.h
index 6cc2017cd..782dc512e 100644
--- a/src/lay/lay/layMainWindow.h
+++ b/src/lay/lay/layMainWindow.h
@@ -739,8 +739,6 @@ public slots:
void cm_help_about ();
void cm_help_about_qt ();
void cm_macro_editor ();
- void cm_new_drc_script ();
- void cm_edit_drc_scripts ();
void cm_packages ();
void cm_technologies ();
void cm_open_too ();