mirror of
https://github.com/KLayout/klayout.git
synced 2026-09-02 10:57:51 +02:00
WIP: refactoring, added first tests for LVS
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
<?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
|
||||
|
||||
cat = "drc"
|
||||
|
||||
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
|
||||
</text>
|
||||
</klayout-macro>
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
<?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>
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
<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_netter.rb">built-in-macros/_lvs_netter.rb</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>
|
||||
<file alias="drc_install.lym">built-in-macros/drc_install.lym</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
+3
-2
@@ -69,9 +69,10 @@ plugins.depends += lib rdb db
|
||||
}
|
||||
|
||||
equals(HAVE_RUBY, "1") {
|
||||
SUBDIRS += drc
|
||||
MAIN_DEPENDS += drc
|
||||
SUBDIRS += drc lvs
|
||||
MAIN_DEPENDS += drc lvs
|
||||
drc.depends += rdb lym
|
||||
lvs.depends += drc
|
||||
}
|
||||
|
||||
equals(HAVE_QTBINDINGS, "1") {
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
TEMPLATE = subdirs
|
||||
SUBDIRS = lvs unit_tests
|
||||
|
||||
unit_tests.depends += lvs
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
<?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
|
||||
|
||||
cat = "lvs"
|
||||
|
||||
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
|
||||
</text>
|
||||
</klayout-macro>
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
DESTDIR = $$OUT_PWD/../..
|
||||
TARGET = klayout_lvs
|
||||
|
||||
include($$PWD/../../lib.pri)
|
||||
|
||||
DEFINES += MAKE_LVS_LIBRARY
|
||||
|
||||
SOURCES = \
|
||||
lvsForceLink.cc \
|
||||
|
||||
HEADERS = \
|
||||
lvsCommon.h \
|
||||
lvsForceLink.h \
|
||||
|
||||
RESOURCES = \
|
||||
lvsResources.qrc
|
||||
|
||||
INCLUDEPATH += $$TL_INC $$DB_INC $$GSI_INC $$LYM_INC $$RDB_INC
|
||||
DEPENDPATH += $$TL_INC $$DB_INC $$GSI_INC $$LYM_INC $$RDB_INC
|
||||
LIBS += -L$$DESTDIR -lklayout_tl -lklayout_db -lklayout_gsi -lklayout_lym -lklayout_rdb -lklayout_drc
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2019 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#if !defined(HDR_lvsCommon_h)
|
||||
# define HDR_lvsCommon_h
|
||||
|
||||
# if defined _WIN32 || defined __CYGWIN__
|
||||
|
||||
# ifdef MAKE_LVS_LIBRARY
|
||||
# define LVS_PUBLIC __declspec(dllexport)
|
||||
# else
|
||||
# define LVS_PUBLIC __declspec(dllimport)
|
||||
# endif
|
||||
# define LVS_LOCAL
|
||||
# define LVS_PUBLIC_TEMPLATE
|
||||
|
||||
# else
|
||||
|
||||
# if __GNUC__ >= 4 || defined(__clang__)
|
||||
# define LVS_PUBLIC __attribute__ ((visibility ("default")))
|
||||
# define LVS_PUBLIC_TEMPLATE __attribute__ ((visibility ("default")))
|
||||
# define LVS_LOCAL __attribute__ ((visibility ("hidden")))
|
||||
# else
|
||||
# define LVS_PUBLIC
|
||||
# define LVS_PUBLIC_TEMPLATE
|
||||
# define LVS_LOCAL
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2019 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "lvsForceLink.h"
|
||||
#include "rdbForceLink.h"
|
||||
|
||||
namespace lvs
|
||||
{
|
||||
int _force_link_f ()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2019 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HDR_lvsForceLink
|
||||
#define HDR_lvsForceLink
|
||||
|
||||
#include "lvsCommon.h"
|
||||
|
||||
/**
|
||||
* @file Include this function to force linking of the lvs module
|
||||
*/
|
||||
|
||||
namespace lvs
|
||||
{
|
||||
LVS_PUBLIC int _force_link_f ();
|
||||
int _force_link_target = _force_link_f ();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<RCC>
|
||||
<qresource prefix="/built-in-macros">
|
||||
<file alias="_lvs_netter.rb">built-in-macros/_lvs_netter.rb</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="lvs_install.lym">built-in-macros/lvs_install.lym</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -0,0 +1,162 @@
|
||||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2019 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include "tlUnitTest.h"
|
||||
#include "dbReader.h"
|
||||
#include "dbTestSupport.h"
|
||||
#include "lymMacro.h"
|
||||
|
||||
TEST(1)
|
||||
{
|
||||
std::string input = tl::testsrc ();
|
||||
input += "/testdata/lvs/inv.oas";
|
||||
std::string schematic = "inv.cir"; // relative to inv.oas
|
||||
std::string au_cir = tl::testsrc ();
|
||||
au_cir += "/testdata/lvs/inv_layout.cir";
|
||||
std::string au_lvsdb = tl::testsrc ();
|
||||
au_lvsdb += "/testdata/lvs/inv.lvsdb";
|
||||
|
||||
std::string output_cir = this->tmp_file ("tmp.cir");
|
||||
std::string output_lvsdb = this->tmp_file ("tmp.lvsdb");
|
||||
|
||||
lym::Macro lvs;
|
||||
lvs.set_text (tl::sprintf (
|
||||
"source('%s', 'INVERTER')\n"
|
||||
"\n"
|
||||
"deep\n"
|
||||
"\n"
|
||||
"# Reports generated\n"
|
||||
"\n"
|
||||
"# LVS report to inv.lvsdb\n"
|
||||
"report_lvs('%s')\n"
|
||||
"\n"
|
||||
"# Write extracted netlist to inv_extracted.cir\n"
|
||||
"target_netlist('%s', write_spice, 'Extracted by KLayout')\n"
|
||||
"\n"
|
||||
"# Drawing layers\n"
|
||||
"\n"
|
||||
"nwell = input(1, 0)\n"
|
||||
"active = input(2, 0)\n"
|
||||
"pplus = input(3, 0)\n"
|
||||
"nplus = input(4, 0)\n"
|
||||
"poly = input(5, 0)\n"
|
||||
"contact = input(6, 0)\n"
|
||||
"metal1 = input(7, 0)\n"
|
||||
"metal1_lbl = labels(7, 1)\n"
|
||||
"via1 = input(8, 0)\n"
|
||||
"metal2 = input(9, 0)\n"
|
||||
"metal2_lbl = labels(9, 1)\n"
|
||||
"\n"
|
||||
"# Bulk layer for terminal provisioning\n"
|
||||
"\n"
|
||||
"bulk = polygon_layer\n"
|
||||
"\n"
|
||||
"# Computed layers\n"
|
||||
"\n"
|
||||
"active_in_nwell = active & nwell\n"
|
||||
"pactive = active_in_nwell & pplus\n"
|
||||
"pgate = pactive & poly\n"
|
||||
"psd = pactive - pgate\n"
|
||||
"\n"
|
||||
"active_outside_nwell = active - nwell\n"
|
||||
"nactive = active_outside_nwell & nplus\n"
|
||||
"ngate = nactive & poly\n"
|
||||
"nsd = nactive - ngate\n"
|
||||
"\n"
|
||||
"# Device extraction\n"
|
||||
"\n"
|
||||
"# PMOS transistor device extraction\n"
|
||||
"extract_devices(mos4('PMOS'), { 'SD' => psd, 'G' => pgate, 'W' => nwell, \n"
|
||||
" 'tS' => psd, 'tD' => psd, 'tG' => poly, 'tW' => nwell })\n"
|
||||
"\n"
|
||||
"# NMOS transistor device extraction\n"
|
||||
"extract_devices(mos4('NMOS'), { 'SD' => nsd, 'G' => ngate, 'W' => bulk, \n"
|
||||
" 'tS' => nsd, 'tD' => nsd, 'tG' => poly, 'tW' => bulk })\n"
|
||||
"\n"
|
||||
"# Define connectivity for netlist extraction\n"
|
||||
"\n"
|
||||
"# Inter-layer\n"
|
||||
"connect(psd, contact)\n"
|
||||
"connect(nsd, contact)\n"
|
||||
"connect(poly, contact)\n"
|
||||
"connect(contact, metal1)\n"
|
||||
"connect(metal1, metal1_lbl) # attaches labels\n"
|
||||
"connect(metal1, via1)\n"
|
||||
"connect(via1, metal2)\n"
|
||||
"connect(metal2, metal2_lbl) # attaches labels\n"
|
||||
"\n"
|
||||
"# Global\n"
|
||||
"connect_global(bulk, 'SUBSTRATE')\n"
|
||||
"connect_global(nwell, 'NWELL')\n"
|
||||
"\n"
|
||||
"# Compare section\n"
|
||||
"\n"
|
||||
"schematic('%s')\n"
|
||||
"\n"
|
||||
"compare\n"
|
||||
, input, output_lvsdb, output_cir, schematic)
|
||||
);
|
||||
lvs.set_interpreter (lym::Macro::DSLInterpreter);
|
||||
lvs.set_dsl_interpreter ("lvs-dsl");
|
||||
|
||||
EXPECT_EQ (lvs.run (), 0);
|
||||
|
||||
compare_text_files (output_cir, au_cir);
|
||||
compare_text_files (output_lvsdb, au_lvsdb);
|
||||
}
|
||||
|
||||
#if 0
|
||||
TEST(2)
|
||||
{
|
||||
lym::Macro lvs;
|
||||
lvs.set_text (
|
||||
"dbu 0.001\n"
|
||||
"def compare(a, b, ex)\n"
|
||||
" a = a.to_s\n"
|
||||
" b = b.to_s\n"
|
||||
" if a != b\n"
|
||||
" raise(ex + \" (actual=#{a}, ref=#{b})\")\n"
|
||||
" end\n"
|
||||
"end\n"
|
||||
"compare(0.1.um, 0.1, \"unexpected value when converting um\")\n"
|
||||
"compare(0.1.micron, 0.1, \"unexpected value when converting micron\")\n"
|
||||
"compare(0.1.um2, 0.1, \"unexpected value when converting um2\")\n"
|
||||
"compare(0.1.mm2, 100000.0, \"unexpected value when converting mm2\")\n"
|
||||
"compare(120.dbu, 0.12, \"unexpected value when converting dbu\")\n"
|
||||
"compare((0.1.um + 120.dbu), 0.22, \"unexpected value when adding values\")\n"
|
||||
"compare(0.1.mm, 100.0, \"unexpected value when converting mm\")\n"
|
||||
"compare(1e-6.m, 1.0, \"unexpected value when converting m\")\n"
|
||||
"compare(1.um, 1.0, \"unexpected value when converting integer um\")\n"
|
||||
"compare(1.micron, 1.0, \"unexpected value when convering integer micron\")\n"
|
||||
"compare(1.um2, 1.0, \"unexpected value when converting integer um2\")\n"
|
||||
"compare(1.mm2, 1000000.0, \"unexpected value when converting integer mm2\")\n"
|
||||
"compare((1.um + 120.dbu), 1.12, \"unexpected value when adding integer values\")\n"
|
||||
"compare(1.mm, 1000.0, \"unexpected value when converting integer mm\")\n"
|
||||
"compare(1.m, 1000000.0, \"unexpected value when converting integer m\")\n"
|
||||
);
|
||||
lvs.set_interpreter (lym::Macro::DSLInterpreter);
|
||||
lvs.set_dsl_interpreter ("lvs-dsl");
|
||||
|
||||
EXPECT_EQ (lvs.run (), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,623 @@
|
||||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2019 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include "tlUnitTest.h"
|
||||
#include "dbReader.h"
|
||||
#include "dbTestSupport.h"
|
||||
#include "dbNetlist.h"
|
||||
#include "dbNetlistSpiceReader.h"
|
||||
#include "lymMacro.h"
|
||||
#include "tlFileUtils.h"
|
||||
|
||||
#if 0 // @@@
|
||||
TEST(1)
|
||||
{
|
||||
std::string rs = tl::testsrc ();
|
||||
rs += "/testdata/lvs/lvsSimpleTests_1.lvs";
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au += "/testdata/lvs/lvsSimpleTests_au1.gds";
|
||||
|
||||
std::string output = this->tmp_file ("tmp.gds");
|
||||
|
||||
{
|
||||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$lvs_test_source = nil\n"
|
||||
"$lvs_test_target = '%s'\n"
|
||||
, output)
|
||||
);
|
||||
config.set_interpreter (lym::Macro::Ruby);
|
||||
EXPECT_EQ (config.run (), 0);
|
||||
}
|
||||
|
||||
lym::Macro lvs;
|
||||
lvs.load_from (rs);
|
||||
EXPECT_EQ (lvs.run (), 0);
|
||||
|
||||
db::Layout layout;
|
||||
|
||||
{
|
||||
tl::InputStream stream (output);
|
||||
db::Reader reader (stream);
|
||||
reader.read (layout);
|
||||
}
|
||||
|
||||
db::compare_layouts (_this, layout, au, db::NoNormalization);
|
||||
}
|
||||
|
||||
TEST(2)
|
||||
{
|
||||
std::string rs = tl::testsrc ();
|
||||
rs += "/testdata/lvs/lvsSimpleTests_2.lvs";
|
||||
|
||||
std::string input = tl::testsrc ();
|
||||
input += "/testdata/lvs/lvstest.gds";
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au += "/testdata/lvs/lvsSimpleTests_au2.gds";
|
||||
|
||||
std::string output = this->tmp_file ("tmp.gds");
|
||||
|
||||
{
|
||||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$lvs_test_source = '%s'\n"
|
||||
"$lvs_test_target = '%s'\n"
|
||||
, input, output)
|
||||
);
|
||||
config.set_interpreter (lym::Macro::Ruby);
|
||||
EXPECT_EQ (config.run (), 0);
|
||||
}
|
||||
|
||||
lym::Macro lvs;
|
||||
lvs.load_from (rs);
|
||||
EXPECT_EQ (lvs.run (), 0);
|
||||
|
||||
db::Layout layout;
|
||||
|
||||
{
|
||||
tl::InputStream stream (output);
|
||||
db::Reader reader (stream);
|
||||
reader.read (layout);
|
||||
}
|
||||
|
||||
db::compare_layouts (_this, layout, au, db::NoNormalization);
|
||||
}
|
||||
|
||||
TEST(3_Flat)
|
||||
{
|
||||
std::string rs = tl::testsrc ();
|
||||
rs += "/testdata/lvs/lvsSimpleTests_3.lvs";
|
||||
|
||||
std::string input = tl::testsrc ();
|
||||
input += "/testdata/lvs/lvstest.gds";
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au += "/testdata/lvs/lvsSimpleTests_au3.gds";
|
||||
|
||||
std::string output = this->tmp_file ("tmp.gds");
|
||||
|
||||
{
|
||||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$lvs_test_source = '%s'\n"
|
||||
"$lvs_test_target = '%s'\n"
|
||||
, input, output)
|
||||
);
|
||||
config.set_interpreter (lym::Macro::Ruby);
|
||||
EXPECT_EQ (config.run (), 0);
|
||||
}
|
||||
|
||||
lym::Macro lvs;
|
||||
lvs.load_from (rs);
|
||||
EXPECT_EQ (lvs.run (), 0);
|
||||
|
||||
db::Layout layout;
|
||||
|
||||
{
|
||||
tl::InputStream stream (output);
|
||||
db::Reader reader (stream);
|
||||
reader.read (layout);
|
||||
}
|
||||
|
||||
db::compare_layouts (_this, layout, au, db::NoNormalization);
|
||||
}
|
||||
|
||||
TEST(4_Hierarchical)
|
||||
{
|
||||
std::string rs = tl::testsrc ();
|
||||
rs += "/testdata/lvs/lvsSimpleTests_4.lvs";
|
||||
|
||||
std::string input = tl::testsrc ();
|
||||
input += "/testdata/lvs/lvstest.gds";
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au += "/testdata/lvs/lvsSimpleTests_au4.gds";
|
||||
|
||||
std::string output = this->tmp_file ("tmp.gds");
|
||||
|
||||
{
|
||||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$lvs_test_source = '%s'\n"
|
||||
"$lvs_test_target = '%s'\n"
|
||||
, input, output)
|
||||
);
|
||||
config.set_interpreter (lym::Macro::Ruby);
|
||||
EXPECT_EQ (config.run (), 0);
|
||||
}
|
||||
|
||||
lym::Macro lvs;
|
||||
lvs.load_from (rs);
|
||||
EXPECT_EQ (lvs.run (), 0);
|
||||
|
||||
db::Layout layout;
|
||||
|
||||
{
|
||||
tl::InputStream stream (output);
|
||||
db::Reader reader (stream);
|
||||
reader.read (layout);
|
||||
}
|
||||
|
||||
db::compare_layouts (_this, layout, au, db::NoNormalization);
|
||||
}
|
||||
|
||||
TEST(5_FlatAntenna)
|
||||
{
|
||||
std::string rs = tl::testsrc ();
|
||||
rs += "/testdata/lvs/lvsSimpleTests_5.lvs";
|
||||
|
||||
std::string input = tl::testsrc ();
|
||||
input += "/testdata/lvs/antenna_l1.gds";
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au += "/testdata/lvs/lvsSimpleTests_au5.gds";
|
||||
|
||||
std::string output = this->tmp_file ("tmp.gds");
|
||||
|
||||
{
|
||||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$lvs_test_source = '%s'\n"
|
||||
"$lvs_test_target = '%s'\n"
|
||||
, input, output)
|
||||
);
|
||||
config.set_interpreter (lym::Macro::Ruby);
|
||||
EXPECT_EQ (config.run (), 0);
|
||||
}
|
||||
|
||||
lym::Macro lvs;
|
||||
lvs.load_from (rs);
|
||||
EXPECT_EQ (lvs.run (), 0);
|
||||
|
||||
db::Layout layout;
|
||||
|
||||
{
|
||||
tl::InputStream stream (output);
|
||||
db::Reader reader (stream);
|
||||
reader.read (layout);
|
||||
}
|
||||
|
||||
db::compare_layouts (_this, layout, au, db::NoNormalization);
|
||||
}
|
||||
|
||||
TEST(6_HierarchicalAntenna)
|
||||
{
|
||||
std::string rs = tl::testsrc ();
|
||||
rs += "/testdata/lvs/lvsSimpleTests_6.lvs";
|
||||
|
||||
std::string input = tl::testsrc ();
|
||||
input += "/testdata/lvs/antenna_l1.gds";
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au += "/testdata/lvs/lvsSimpleTests_au6.gds";
|
||||
|
||||
std::string output = this->tmp_file ("tmp.gds");
|
||||
|
||||
{
|
||||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$lvs_test_source = '%s'\n"
|
||||
"$lvs_test_target = '%s'\n"
|
||||
, input, output)
|
||||
);
|
||||
config.set_interpreter (lym::Macro::Ruby);
|
||||
EXPECT_EQ (config.run (), 0);
|
||||
}
|
||||
|
||||
lym::Macro lvs;
|
||||
lvs.load_from (rs);
|
||||
EXPECT_EQ (lvs.run (), 0);
|
||||
|
||||
db::Layout layout;
|
||||
|
||||
{
|
||||
tl::InputStream stream (output);
|
||||
db::Reader reader (stream);
|
||||
reader.read (layout);
|
||||
}
|
||||
|
||||
db::compare_layouts (_this, layout, au, db::NoNormalization);
|
||||
}
|
||||
|
||||
TEST(7_AntennaWithDiodes)
|
||||
{
|
||||
std::string rs = tl::testsrc ();
|
||||
rs += "/testdata/lvs/lvsSimpleTests_7.lvs";
|
||||
|
||||
std::string input = tl::testsrc ();
|
||||
input += "/testdata/lvs/antenna_l1.gds";
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au += "/testdata/lvs/lvsSimpleTests_au7.gds";
|
||||
|
||||
std::string output = this->tmp_file ("tmp.gds");
|
||||
|
||||
{
|
||||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$lvs_test_source = '%s'\n"
|
||||
"$lvs_test_target = '%s'\n"
|
||||
, input, output)
|
||||
);
|
||||
config.set_interpreter (lym::Macro::Ruby);
|
||||
EXPECT_EQ (config.run (), 0);
|
||||
}
|
||||
|
||||
lym::Macro lvs;
|
||||
lvs.load_from (rs);
|
||||
EXPECT_EQ (lvs.run (), 0);
|
||||
|
||||
db::Layout layout;
|
||||
|
||||
{
|
||||
tl::InputStream stream (output);
|
||||
db::Reader reader (stream);
|
||||
reader.read (layout);
|
||||
}
|
||||
|
||||
db::compare_layouts (_this, layout, au, db::NoNormalization);
|
||||
}
|
||||
|
||||
TEST(8_TextsAndPolygons)
|
||||
{
|
||||
std::string rs = tl::testsrc ();
|
||||
rs += "/testdata/lvs/lvsSimpleTests_8.lvs";
|
||||
|
||||
std::string input = tl::testsrc ();
|
||||
input += "/testdata/lvs/texts.gds";
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au += "/testdata/lvs/lvsSimpleTests_au8.gds";
|
||||
|
||||
std::string output = this->tmp_file ("tmp.gds");
|
||||
|
||||
{
|
||||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$lvs_test_source = '%s'\n"
|
||||
"$lvs_test_target = '%s'\n"
|
||||
, input, output)
|
||||
);
|
||||
config.set_interpreter (lym::Macro::Ruby);
|
||||
EXPECT_EQ (config.run (), 0);
|
||||
}
|
||||
|
||||
lym::Macro lvs;
|
||||
lvs.load_from (rs);
|
||||
EXPECT_EQ (lvs.run (), 0);
|
||||
|
||||
db::Layout layout;
|
||||
|
||||
{
|
||||
tl::InputStream stream (output);
|
||||
db::Reader reader (stream);
|
||||
reader.read (layout);
|
||||
}
|
||||
|
||||
db::compare_layouts (_this, layout, au, db::NoNormalization);
|
||||
}
|
||||
|
||||
static void compare_netlists (tl::TestBase *_this, const std::string &cir, const std::string &cir_au)
|
||||
{
|
||||
db::Netlist nl, nl_au;
|
||||
|
||||
db::NetlistSpiceReader reader;
|
||||
|
||||
{
|
||||
tl::info << "Output: " << cir;
|
||||
tl::InputStream is (cir);
|
||||
reader.read (is, nl);
|
||||
}
|
||||
|
||||
{
|
||||
tl::info << "Golden: " << cir_au;
|
||||
tl::InputStream is (cir_au);
|
||||
reader.read (is, nl_au);
|
||||
}
|
||||
|
||||
db::compare_netlist (_this, nl, nl_au);
|
||||
}
|
||||
|
||||
TEST(9_NetlistExtraction)
|
||||
{
|
||||
std::string rs = tl::testsrc ();
|
||||
rs += "/testdata/lvs/lvsSimpleTests_9.lvs";
|
||||
|
||||
std::string input = tl::testsrc ();
|
||||
input += "/testdata/lvs/ringo.gds";
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au += "/testdata/lvs/lvsSimpleTests_au9a.cir";
|
||||
|
||||
std::string au_simplified = tl::testsrc ();
|
||||
au_simplified += "/testdata/lvs/lvsSimpleTests_au9b.cir";
|
||||
|
||||
std::string output = this->tmp_file ("tmp.cir");
|
||||
std::string output_simplified = this->tmp_file ("tmp_simplified.cir");
|
||||
|
||||
{
|
||||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$lvs_test_source = '%s'\n"
|
||||
"$lvs_test_target = '%s'\n"
|
||||
"$lvs_test_target_simplified = '%s'\n"
|
||||
, input, output, output_simplified)
|
||||
);
|
||||
config.set_interpreter (lym::Macro::Ruby);
|
||||
EXPECT_EQ (config.run (), 0);
|
||||
}
|
||||
|
||||
lym::Macro lvs;
|
||||
lvs.load_from (rs);
|
||||
EXPECT_EQ (lvs.run (), 0);
|
||||
|
||||
|
||||
// verify
|
||||
|
||||
CHECKPOINT ();
|
||||
compare_netlists (_this, output, au);
|
||||
|
||||
CHECKPOINT ();
|
||||
compare_netlists (_this, output_simplified, au_simplified);
|
||||
}
|
||||
|
||||
TEST(10_NetlistExtractionFlat)
|
||||
{
|
||||
std::string rs = tl::testsrc ();
|
||||
rs += "/testdata/lvs/lvsSimpleTests_10.lvs";
|
||||
|
||||
std::string input = tl::testsrc ();
|
||||
input += "/testdata/lvs/ringo.gds";
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au += "/testdata/lvs/lvsSimpleTests_au10a.cir";
|
||||
|
||||
std::string au_simplified = tl::testsrc ();
|
||||
au_simplified += "/testdata/lvs/lvsSimpleTests_au10b.cir";
|
||||
|
||||
std::string output = this->tmp_file ("tmp.cir");
|
||||
std::string output_simplified = this->tmp_file ("tmp_simplified.cir");
|
||||
|
||||
{
|
||||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$lvs_test_source = '%s'\n"
|
||||
"$lvs_test_target = '%s'\n"
|
||||
"$lvs_test_target_simplified = '%s'\n"
|
||||
, input, output, output_simplified)
|
||||
);
|
||||
config.set_interpreter (lym::Macro::Ruby);
|
||||
EXPECT_EQ (config.run (), 0);
|
||||
}
|
||||
|
||||
lym::Macro lvs;
|
||||
lvs.load_from (rs);
|
||||
EXPECT_EQ (lvs.run (), 0);
|
||||
|
||||
|
||||
// verify
|
||||
|
||||
CHECKPOINT ();
|
||||
compare_netlists (_this, output, au);
|
||||
|
||||
CHECKPOINT ();
|
||||
compare_netlists (_this, output_simplified, au_simplified);
|
||||
}
|
||||
|
||||
TEST(11_CustomDevices)
|
||||
{
|
||||
std::string rs = tl::testsrc ();
|
||||
rs += "/testdata/lvs/lvsSimpleTests_11.lvs";
|
||||
|
||||
std::string input = tl::testsrc ();
|
||||
input += "/testdata/lvs/vdiv.gds";
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au += "/testdata/lvs/lvsSimpleTests_au11a.cir";
|
||||
|
||||
std::string au_simplified = tl::testsrc ();
|
||||
au_simplified += "/testdata/lvs/lvsSimpleTests_au11b.cir";
|
||||
|
||||
std::string output = this->tmp_file ("tmp.cir");
|
||||
std::string output_simplified = this->tmp_file ("tmp_simplified.cir");
|
||||
|
||||
{
|
||||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$lvs_test_source = '%s'\n"
|
||||
"$lvs_test_target = '%s'\n"
|
||||
"$lvs_test_target_simplified = '%s'\n"
|
||||
, input, output, output_simplified)
|
||||
);
|
||||
config.set_interpreter (lym::Macro::Ruby);
|
||||
EXPECT_EQ (config.run (), 0);
|
||||
}
|
||||
|
||||
lym::Macro lvs;
|
||||
lvs.load_from (rs);
|
||||
EXPECT_EQ (lvs.run (), 0);
|
||||
|
||||
|
||||
// verify
|
||||
|
||||
CHECKPOINT ();
|
||||
compare_netlists (_this, output, au);
|
||||
|
||||
CHECKPOINT ();
|
||||
compare_netlists (_this, output_simplified, au_simplified);
|
||||
}
|
||||
|
||||
TEST(12_NetlistJoinLabels)
|
||||
{
|
||||
std::string rs = tl::testsrc ();
|
||||
rs += "/testdata/lvs/lvsSimpleTests_12.lvs";
|
||||
|
||||
std::string input = tl::testsrc ();
|
||||
input += "/testdata/lvs/implicit_nets.gds";
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au += "/testdata/lvs/lvsSimpleTests_au12a.cir";
|
||||
|
||||
std::string output = this->tmp_file ("tmp.cir");
|
||||
|
||||
{
|
||||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$lvs_test_source = '%s'\n"
|
||||
"$lvs_test_target = '%s'\n"
|
||||
"$lvs_test_target_simplified = nil\n"
|
||||
, input, output)
|
||||
);
|
||||
config.set_interpreter (lym::Macro::Ruby);
|
||||
EXPECT_EQ (config.run (), 0);
|
||||
}
|
||||
|
||||
lym::Macro lvs;
|
||||
lvs.load_from (rs);
|
||||
EXPECT_EQ (lvs.run (), 0);
|
||||
|
||||
// verify
|
||||
|
||||
CHECKPOINT ();
|
||||
compare_netlists (_this, output, au);
|
||||
}
|
||||
|
||||
TEST(13a_KissingCorners)
|
||||
{
|
||||
std::string rs = tl::testsrc ();
|
||||
rs += "/testdata/lvs/lvsSimpleTests_13a.lvs";
|
||||
|
||||
std::string input = tl::testsrc ();
|
||||
input += "/testdata/lvs/kissing_corners.gds";
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au += "/testdata/lvs/lvsSimpleTests_au13a.gds";
|
||||
|
||||
std::string output = this->tmp_file ("tmp.gds");
|
||||
|
||||
{
|
||||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$lvs_test_source = '%s'\n"
|
||||
"$lvs_test_target = '%s'\n"
|
||||
, input, output)
|
||||
);
|
||||
config.set_interpreter (lym::Macro::Ruby);
|
||||
EXPECT_EQ (config.run (), 0);
|
||||
}
|
||||
|
||||
lym::Macro lvs;
|
||||
lvs.load_from (rs);
|
||||
EXPECT_EQ (lvs.run (), 0);
|
||||
|
||||
// verify
|
||||
|
||||
db::Layout layout;
|
||||
|
||||
{
|
||||
tl::InputStream stream (output);
|
||||
db::Reader reader (stream);
|
||||
reader.read (layout);
|
||||
}
|
||||
|
||||
CHECKPOINT ();
|
||||
db::compare_layouts (_this, layout, au, db::NoNormalization);
|
||||
}
|
||||
|
||||
TEST(13b_KissingCornersDeep)
|
||||
{
|
||||
std::string rs = tl::testsrc ();
|
||||
rs += "/testdata/lvs/lvsSimpleTests_13b.lvs";
|
||||
|
||||
std::string input = tl::testsrc ();
|
||||
input += "/testdata/lvs/kissing_corners.gds";
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au += "/testdata/lvs/lvsSimpleTests_au13b.gds";
|
||||
|
||||
std::string output = this->tmp_file ("tmp.gds");
|
||||
|
||||
{
|
||||
// Set some variables
|
||||
lym::Macro config;
|
||||
config.set_text (tl::sprintf (
|
||||
"$lvs_test_source = '%s'\n"
|
||||
"$lvs_test_target = '%s'\n"
|
||||
, input, output)
|
||||
);
|
||||
config.set_interpreter (lym::Macro::Ruby);
|
||||
EXPECT_EQ (config.run (), 0);
|
||||
}
|
||||
|
||||
lym::Macro lvs;
|
||||
lvs.load_from (rs);
|
||||
EXPECT_EQ (lvs.run (), 0);
|
||||
|
||||
// verify
|
||||
|
||||
db::Layout layout;
|
||||
|
||||
{
|
||||
tl::InputStream stream (output);
|
||||
db::Reader reader (stream);
|
||||
reader.read (layout);
|
||||
}
|
||||
|
||||
CHECKPOINT ();
|
||||
db::compare_layouts (_this, layout, au, db::NoNormalization);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,16 @@
|
||||
|
||||
DESTDIR_UT = $$OUT_PWD/../..
|
||||
DESTDIR = $$OUT_PWD/..
|
||||
|
||||
TARGET = lvs_tests
|
||||
|
||||
include($$PWD/../../lib_ut.pri)
|
||||
|
||||
SOURCES = \
|
||||
lvsBasicTests.cc \
|
||||
lvsSimpleTests.cc \
|
||||
|
||||
INCLUDEPATH += $$DRC_INC $$TL_INC $$RDB_INC $$DB_INC $$GSI_INC $$LYM_INC
|
||||
DEPENDPATH += $$DRC_INC $$TL_INC $$RDB_INC $$DB_INC $$GSI_INC $$LYM_INC
|
||||
|
||||
LIBS += -L$$DESTDIR_UT -lklayout_lvs -lklayout_drc -lklayout_rdb -lklayout_db -lklayout_tl -lklayout_gsi -lklayout_lym
|
||||
Reference in New Issue
Block a user