mirror of https://github.com/KLayout/klayout.git
WIP: new macro category: LVS
This commit is contained in:
parent
04f0edc814
commit
0f9c50c405
|
|
@ -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
|
||||||
|
|
||||||
|
|
@ -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 && 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>
|
||||||
|
|
||||||
|
|
@ -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 >= 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
|
||||||
|
</text>
|
||||||
|
</klayout-macro>
|
||||||
|
|
||||||
|
|
@ -7,5 +7,8 @@
|
||||||
<file alias="_drc_source.rb">built-in-macros/_drc_source.rb</file>
|
<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_tags.rb">built-in-macros/_drc_tags.rb</file>
|
||||||
<file alias="drc_interpreters.lym">built-in-macros/drc_interpreters.lym</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>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
||||||
|
|
@ -371,6 +371,13 @@ Class<lay::MainWindow> decl_MainWindow (QT_EXTERNAL_BASE (QMainWindow) "lay", "M
|
||||||
"\n"
|
"\n"
|
||||||
"This event has been added in version 0.25.\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,
|
gsi::method ("cm_reset_window_state", &lay::MainWindow::cm_reset_window_state,
|
||||||
"@brief 'cm_reset_window_state' action (bound to a menu)"
|
"@brief 'cm_reset_window_state' action (bound to a menu)"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,15 @@ static lay::MacroController::MacroCategory drc_cat ()
|
||||||
return 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
|
void
|
||||||
MacroController::finish ()
|
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-macros", "macros", true);
|
||||||
lym::MacroCollection::root ().add_folder (tl::to_string (QObject::tr ("Built-In")), ":/built-in-pymacros", "pymacros", 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
|
// 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.
|
// register the remaining categories.
|
||||||
|
|
||||||
m_macro_categories.push_back (ruby_cat ());
|
m_macro_categories.push_back (ruby_cat ());
|
||||||
m_macro_categories.push_back (python_cat ());
|
m_macro_categories.push_back (python_cat ());
|
||||||
m_macro_categories.push_back (drc_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)
|
// scans the macros from techs and packages (this will allow autorun-early on them)
|
||||||
// and updates m_external_paths
|
// and updates m_external_paths
|
||||||
|
|
|
||||||
|
|
@ -955,17 +955,10 @@ MainWindow::init_menu ()
|
||||||
MenuLayoutEntry::last ()
|
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 tools_menu [] = {
|
||||||
MenuLayoutEntry ("packages", tl::to_string (QObject::tr ("Manage Packages")), SLOT (cm_packages ())),
|
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 ("technologies", tl::to_string (QObject::tr ("Manage Technologies")), SLOT (cm_technologies ())),
|
||||||
MenuLayoutEntry::separator ("verification_group"),
|
MenuLayoutEntry::separator ("verification_group"),
|
||||||
MenuLayoutEntry ("drc", tl::to_string (QObject::tr ("DRC")), drc_menu),
|
|
||||||
MenuLayoutEntry::separator ("post_verification_group"),
|
MenuLayoutEntry::separator ("post_verification_group"),
|
||||||
MenuLayoutEntry::last ()
|
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
|
void
|
||||||
MainWindow::cm_macro_editor ()
|
MainWindow::cm_macro_editor ()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -739,8 +739,6 @@ public slots:
|
||||||
void cm_help_about ();
|
void cm_help_about ();
|
||||||
void cm_help_about_qt ();
|
void cm_help_about_qt ();
|
||||||
void cm_macro_editor ();
|
void cm_macro_editor ();
|
||||||
void cm_new_drc_script ();
|
|
||||||
void cm_edit_drc_scripts ();
|
|
||||||
void cm_packages ();
|
void cm_packages ();
|
||||||
void cm_technologies ();
|
void cm_technologies ();
|
||||||
void cm_open_too ();
|
void cm_open_too ();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue