WIP: refactoring, added first tests for LVS

This commit is contained in:
Matthias Koefferlein
2019-07-06 08:52:40 +02:00
parent 15022709b4
commit 2f6aae7204
19 changed files with 1316 additions and 56 deletions
@@ -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 &amp;&amp; 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>
-50
View File
@@ -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 &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>
+1 -4
View File
@@ -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
View File
@@ -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") {
+6
View File
@@ -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 &amp;&amp; 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>
+22
View File
@@ -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
+51
View File
@@ -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
+34
View File
@@ -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;
}
}
+40
View File
@@ -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
+8
View File
@@ -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>
+162
View File
@@ -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
+623
View File
@@ -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
+16
View File
@@ -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