WIP: new macro category: LVS

This commit is contained in:
Matthias Koefferlein 2019-06-23 16:57:41 +02:00
parent 04f0edc814
commit 0f9c50c405
8 changed files with 231 additions and 24 deletions

View File

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

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<klayout-macro>
<description/>
<version/>
<category/>
<prolog/>
<epilog/>
<doc/>
<autorun>true</autorun>
<autorun-early>false</autorun-early>
<shortcut/>
<show-in-menu>false</show-in-menu>
<group-name/>
<menu-path/>
<interpreter>ruby</interpreter>
<dsl-interpreter-name/>
<text>
# Installs the home menu entries (needs to be done on autorun, not autorun-early)
if RBA::Application::instance &amp;&amp; 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
</text>
</klayout-macro>

View File

@ -0,0 +1,130 @@
<?xml version="1.0" encoding="utf-8"?>
<klayout-macro>
<description/>
<version/>
<category/>
<prolog/>
<epilog/>
<doc/>
<autorun>false</autorun>
<autorun-early>true</autorun-early>
<shortcut/>
<show-in-menu>false</show-in-menu>
<group-name/>
<menu-path/>
<interpreter>ruby</interpreter>
<dsl-interpreter-name/>
<text>
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 &gt;= 10 &amp;&amp; RBA::Logger::info("Running #{_macro.path}")
_lvs.instance_eval(_macro.text, _macro.path)
# Remove the debugger scope
RBA::MacroExecutionContext::remove_debugger_scope
rescue =&gt; 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 &lt; 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 = &lt;&lt;"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 &amp;&amp; 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 &lt; 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
</text>
</klayout-macro>

View File

@ -7,5 +7,8 @@
<file alias="_drc_source.rb">built-in-macros/_drc_source.rb</file>
<file alias="_drc_tags.rb">built-in-macros/_drc_tags.rb</file>
<file alias="drc_interpreters.lym">built-in-macros/drc_interpreters.lym</file>
<file alias="_lvs_engine.rb">built-in-macros/_lvs_engine.rb</file>
<file alias="lvs_interpreters.lym">built-in-macros/lvs_interpreters.lym</file>
<file alias="install.lym">built-in-macros/install.lym</file>
</qresource>
</RCC>

View File

@ -371,6 +371,13 @@ Class<lay::MainWindow> 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"

View File

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

View File

@ -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 ()
{

View File

@ -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 ();