2017-02-12 13:21:08 +01:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
|
|
KLayout Layout Viewer
|
2017-02-12 15:28:14 +01:00
|
|
|
Copyright (C) 2006-2017 Matthias Koefferlein
|
2017-02-12 13:21:08 +01:00
|
|
|
|
|
|
|
|
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 "dbOASISWriter.h"
|
|
|
|
|
#include "dbGDS2Writer.h"
|
|
|
|
|
#include "dbOASISReader.h"
|
|
|
|
|
#include "dbGDS2Reader.h"
|
|
|
|
|
#include "dbLayoutDiff.h"
|
|
|
|
|
#include "dbWriter.h"
|
|
|
|
|
#include "dbTextWriter.h"
|
|
|
|
|
|
|
|
|
|
#include "utHead.h"
|
|
|
|
|
|
|
|
|
|
#include <cstdlib>
|
|
|
|
|
#include <QDir>
|
|
|
|
|
|
|
|
|
|
void run_test (ut::TestBase *_this, const char *file, bool scaling_test, int compr, bool recompress)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
db::Manager m;
|
|
|
|
|
db::Layout layout_org (&m);
|
|
|
|
|
std::string fn (ut::testsrc ());
|
|
|
|
|
fn += "/testdata/oasis/";
|
|
|
|
|
fn += file;
|
|
|
|
|
tl::InputStream stream (fn);
|
|
|
|
|
db::Reader reader (stream);
|
|
|
|
|
reader.set_warnings_as_errors (true);
|
|
|
|
|
reader.read (layout_org);
|
|
|
|
|
|
|
|
|
|
// in between test the capabilities of a layout to copy itself
|
|
|
|
|
db::Layout layout;
|
|
|
|
|
layout = layout_org;
|
|
|
|
|
layout_org.clear ();
|
|
|
|
|
|
|
|
|
|
std::string tmp_file = _this->tmp_file ("tmp_1.oas");
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::OutputStream stream (tmp_file);
|
|
|
|
|
db::OASISWriter writer;
|
|
|
|
|
db::SaveLayoutOptions options;
|
|
|
|
|
writer.write (layout, stream, options);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
db::Layout layout2 (&m);
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::InputStream stream2 (tmp_file);
|
|
|
|
|
db::Reader reader2 (stream2);
|
|
|
|
|
db::LoadLayoutOptions options;
|
|
|
|
|
db::OASISReaderOptions oasis_options;
|
|
|
|
|
options.set_options (oasis_options);
|
|
|
|
|
reader2.set_warnings_as_errors (true);
|
|
|
|
|
reader2.read (layout2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CHECKPOINT ();
|
|
|
|
|
bool equal = db::compare_layouts (layout, layout2, db::layout_diff::f_verbose | db::layout_diff::f_flatten_array_insts, 0);
|
|
|
|
|
if (! equal) {
|
|
|
|
|
_this->raise (tl::sprintf ("Compare failed - see %s vs %s\n", fn, tmp_file));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
db::Manager m;
|
|
|
|
|
db::Layout layout_org (&m);
|
|
|
|
|
std::string fn (ut::testsrc ());
|
|
|
|
|
fn += "/testdata/oasis/";
|
|
|
|
|
fn += file;
|
|
|
|
|
tl::InputStream stream (fn);
|
|
|
|
|
db::Reader reader (stream);
|
|
|
|
|
reader.set_warnings_as_errors (true);
|
|
|
|
|
reader.read (layout_org);
|
|
|
|
|
|
|
|
|
|
// in between test the capabilities of a layout to copy itself
|
|
|
|
|
db::Layout layout;
|
|
|
|
|
layout = layout_org;
|
|
|
|
|
layout_org.clear ();
|
|
|
|
|
|
|
|
|
|
// generate a "unique" name ...
|
|
|
|
|
unsigned int hash = 0;
|
|
|
|
|
for (const char *cp = file; *cp; ++cp) {
|
|
|
|
|
hash = (hash << 4) ^ (hash >> 4) ^ ((unsigned int) *cp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string tmp_file = _this->tmp_file ("tmp_2.oas");
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::OutputStream stream (tmp_file);
|
|
|
|
|
db::OASISWriter writer;
|
|
|
|
|
db::SaveLayoutOptions options;
|
|
|
|
|
db::OASISWriterOptions oasis_options;
|
|
|
|
|
oasis_options.write_cblocks = true;
|
|
|
|
|
oasis_options.strict_mode = true;
|
|
|
|
|
options.set_options (oasis_options);
|
|
|
|
|
writer.write (layout, stream, options);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
db::Layout layout2 (&m);
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::InputStream stream2 (tmp_file);
|
|
|
|
|
db::Reader reader2 (stream2);
|
|
|
|
|
db::LoadLayoutOptions options;
|
|
|
|
|
db::OASISReaderOptions oasis_options;
|
|
|
|
|
oasis_options.expect_strict_mode = 1;
|
|
|
|
|
options.set_options (oasis_options);
|
|
|
|
|
reader2.set_warnings_as_errors (true);
|
|
|
|
|
reader2.read (layout2, options);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CHECKPOINT ();
|
|
|
|
|
bool equal = db::compare_layouts (layout, layout2, db::layout_diff::f_verbose | db::layout_diff::f_flatten_array_insts, 0);
|
|
|
|
|
if (! equal) {
|
|
|
|
|
_this->raise (tl::sprintf ("Compare failed - see %s vs %s\n", fn, tmp_file));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
db::Manager m;
|
|
|
|
|
db::Layout layout_org (&m);
|
|
|
|
|
std::string fn (ut::testsrc ());
|
|
|
|
|
fn += "/testdata/oasis/";
|
|
|
|
|
fn += file;
|
|
|
|
|
tl::InputStream stream (fn);
|
|
|
|
|
db::Reader reader (stream);
|
|
|
|
|
reader.read (layout_org);
|
|
|
|
|
|
|
|
|
|
// in between test the capabilities of a layout to copy itself
|
|
|
|
|
db::Layout layout;
|
|
|
|
|
layout = layout_org;
|
|
|
|
|
layout_org.clear ();
|
|
|
|
|
|
|
|
|
|
std::string tmp_file = _this->tmp_file ("tmp_3.oas");
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::OutputStream stream (tmp_file);
|
|
|
|
|
db::OASISWriter writer;
|
|
|
|
|
db::SaveLayoutOptions options;
|
|
|
|
|
db::OASISWriterOptions oasis_options;
|
|
|
|
|
oasis_options.strict_mode = false;
|
|
|
|
|
oasis_options.write_std_properties = 2;
|
|
|
|
|
options.set_options (oasis_options);
|
|
|
|
|
writer.write (layout, stream, options);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
db::Layout layout2 (&m);
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::InputStream stream2 (tmp_file);
|
|
|
|
|
db::Reader reader2 (stream2);
|
|
|
|
|
db::LoadLayoutOptions options;
|
|
|
|
|
db::OASISReaderOptions oasis_options;
|
|
|
|
|
oasis_options.expect_strict_mode = 0;
|
|
|
|
|
options.set_options (oasis_options);
|
|
|
|
|
reader2.set_warnings_as_errors (true);
|
|
|
|
|
reader2.read (layout2, options);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CHECKPOINT ();
|
|
|
|
|
bool equal = db::compare_layouts (layout, layout2, db::layout_diff::f_verbose | db::layout_diff::f_flatten_array_insts, 0);
|
|
|
|
|
if (! equal) {
|
|
|
|
|
_this->raise (tl::sprintf ("Compare failed - see %s vs %s\n", fn, tmp_file));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
db::Manager m;
|
|
|
|
|
db::Layout layout_org (&m);
|
|
|
|
|
std::string fn (ut::testsrc ());
|
|
|
|
|
fn += "/testdata/oasis/";
|
|
|
|
|
fn += file;
|
|
|
|
|
tl::InputStream stream (fn);
|
|
|
|
|
db::Reader reader (stream);
|
|
|
|
|
reader.read (layout_org);
|
|
|
|
|
|
|
|
|
|
// in between test the capabilities of a layout to copy itself
|
|
|
|
|
db::Layout layout;
|
|
|
|
|
layout = layout_org;
|
|
|
|
|
layout_org.clear ();
|
|
|
|
|
|
|
|
|
|
std::string tmp_file = _this->tmp_file ("tmp_4.oas");
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::OutputStream stream (tmp_file);
|
|
|
|
|
db::OASISWriter writer;
|
|
|
|
|
db::SaveLayoutOptions options;
|
|
|
|
|
db::OASISWriterOptions oasis_options;
|
|
|
|
|
oasis_options.write_cblocks = true;
|
|
|
|
|
oasis_options.strict_mode = true;
|
|
|
|
|
oasis_options.write_std_properties = 2;
|
|
|
|
|
options.set_options (oasis_options);
|
|
|
|
|
writer.write (layout, stream, options);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
db::Layout layout2 (&m);
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::InputStream stream2 (tmp_file);
|
|
|
|
|
db::Reader reader2 (stream2);
|
|
|
|
|
db::LoadLayoutOptions options;
|
|
|
|
|
db::OASISReaderOptions oasis_options;
|
|
|
|
|
oasis_options.expect_strict_mode = 1;
|
|
|
|
|
options.set_options (oasis_options);
|
|
|
|
|
reader2.set_warnings_as_errors (true);
|
|
|
|
|
reader2.read (layout2, options);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CHECKPOINT ();
|
|
|
|
|
bool equal = db::compare_layouts (layout, layout2, db::layout_diff::f_verbose | db::layout_diff::f_flatten_array_insts, 0);
|
|
|
|
|
if (! equal) {
|
|
|
|
|
_this->raise (tl::sprintf ("Compare failed - see %s vs %s\n", fn, tmp_file));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (scaling_test) {
|
|
|
|
|
|
|
|
|
|
db::Manager m;
|
|
|
|
|
db::Layout layout (&m);
|
|
|
|
|
std::string fn (ut::testsrc ());
|
|
|
|
|
fn += "/testdata/oasis/";
|
|
|
|
|
fn += file;
|
|
|
|
|
tl::InputStream stream (fn);
|
|
|
|
|
db::Reader reader (stream);
|
|
|
|
|
reader.read (layout);
|
|
|
|
|
|
|
|
|
|
db::SaveLayoutOptions options;
|
|
|
|
|
db::OASISWriterOptions oasis_options;
|
|
|
|
|
oasis_options.compression_level = compr;
|
|
|
|
|
oasis_options.recompress = recompress;
|
|
|
|
|
options.set_options (oasis_options);
|
|
|
|
|
options.set_scale_factor (3.0);
|
|
|
|
|
options.set_dbu (0.0005);
|
|
|
|
|
|
|
|
|
|
// generate a "unique" name ...
|
|
|
|
|
unsigned int hash = 0;
|
|
|
|
|
for (const char *cp = file; *cp; ++cp) {
|
|
|
|
|
hash = (hash << 4) ^ (hash >> 4) ^ ((unsigned int) *cp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string tmp1_file = _this->tmp_file ("tmp_s1.gds");
|
|
|
|
|
std::string tmp2_file = _this->tmp_file ("tmp_s2.oas");
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::OutputStream stream (tmp1_file);
|
|
|
|
|
db::GDS2Writer writer;
|
|
|
|
|
writer.write (layout, stream, options);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::OutputStream stream (tmp2_file);
|
|
|
|
|
db::OASISWriter writer;
|
|
|
|
|
writer.write (layout, stream, options);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
db::Layout layout1 (&m);
|
|
|
|
|
{
|
|
|
|
|
tl::InputStream file (tmp1_file);
|
|
|
|
|
db::Reader reader (file);
|
|
|
|
|
reader.read (layout1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
db::Layout layout2 (&m);
|
|
|
|
|
{
|
|
|
|
|
tl::InputStream file (tmp2_file);
|
|
|
|
|
db::Reader reader (file);
|
|
|
|
|
reader.read (layout2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CHECKPOINT ();
|
|
|
|
|
bool equal = db::compare_layouts (layout1, layout2, db::layout_diff::f_verbose | db::layout_diff::f_flatten_array_insts | db::layout_diff::f_no_properties | db::layout_diff::f_no_layer_names | db::layout_diff::f_boxes_as_polygons, 0);
|
|
|
|
|
if (! equal) {
|
|
|
|
|
_this->raise (tl::sprintf ("Compare failed - see %s vs %s\n", tmp1_file, tmp2_file));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void run_test (ut::TestBase *_this, const char *file, bool scaling_test = true)
|
|
|
|
|
{
|
|
|
|
|
for (int recompress = 0; recompress < 2; ++recompress) {
|
|
|
|
|
run_test (_this, file, scaling_test, 0, recompress);
|
|
|
|
|
run_test (_this, file, scaling_test, 1, recompress);
|
|
|
|
|
run_test (_this, file, scaling_test, 2, recompress);
|
|
|
|
|
run_test (_this, file, scaling_test, 10, recompress);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(1)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t10.1.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(2)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t11.1.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(3)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t11.2.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(4)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t11.3.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(4A)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t11.4.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(5)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t1.1.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(6)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t12.1.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(7)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t1.2.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(8)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t13.1.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(9)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t13.2.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(10)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t13.3.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(11)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t1.3.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(12)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t14.1.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(13)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t1.4.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(14)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t1.5.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(15)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t2.1.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(16)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t2.2.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(17)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t2.4.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(19)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t3.10.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(20)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t3.1.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(21)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t3.2.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(22)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t3.5.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(23)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t3.9.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(24)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t4.1.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(25)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t4.2.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(26)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t5.1.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(27)
|
|
|
|
|
{
|
|
|
|
|
// no scaling test, since this test contains polygons with >8000 points that cannot be written to GDS
|
|
|
|
|
run_test (_this, "t5.2.oas", false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(28)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t5.3.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(29)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t6.1.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(30)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t7.1.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(31)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t8.1.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(32)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t8.2.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(33)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t8.3.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(34)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t8.4.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(35)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t8.5.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(36)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t8.6.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(37)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t8.7.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(38)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t8.8.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(39)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t9.1.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(40)
|
|
|
|
|
{
|
|
|
|
|
run_test (_this, "t9.2.oas");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(100)
|
|
|
|
|
{
|
|
|
|
|
db::Manager m;
|
|
|
|
|
db::Layout g (&m);
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp0;
|
|
|
|
|
lp0.layer = 0;
|
|
|
|
|
lp0.datatype = 0;
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp1;
|
|
|
|
|
lp1.layer = 1;
|
|
|
|
|
lp1.datatype = 0;
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp2;
|
|
|
|
|
lp2.layer = 2;
|
|
|
|
|
lp2.datatype = 0;
|
|
|
|
|
|
|
|
|
|
g.insert_layer (0, lp0);
|
|
|
|
|
g.insert_layer (1, lp1);
|
|
|
|
|
g.insert_layer (2, lp2);
|
|
|
|
|
|
|
|
|
|
db::Cell &c1 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c2 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c3 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c4 (g.cell (g.add_cell ()));
|
|
|
|
|
|
|
|
|
|
db::Box b (0, 100, 1000, 1200);
|
|
|
|
|
c1.shapes (1).insert (b);
|
|
|
|
|
|
|
|
|
|
db::Box bb (0, -100, 2000, 2200);
|
|
|
|
|
c2.shapes (2).insert (bb);
|
|
|
|
|
|
|
|
|
|
// inserting instances ..
|
|
|
|
|
db::FTrans f (1, true);
|
|
|
|
|
db::Vector p (-10, 20);
|
|
|
|
|
db::Trans t (f.rot (), p);
|
|
|
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
|
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
|
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c3.cell_index ()), t));
|
|
|
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
|
|
|
|
|
|
|
|
|
|
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter100.gds"));
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::OutputStream out (tmp_file);
|
|
|
|
|
db::SaveLayoutOptions options;
|
|
|
|
|
options.set_format ("OASIS");
|
|
|
|
|
db::Writer writer (options);
|
|
|
|
|
writer.write (g, out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tl::InputStream in (tmp_file);
|
|
|
|
|
db::Reader reader (in);
|
|
|
|
|
db::Layout gg;
|
|
|
|
|
reader.set_warnings_as_errors (true);
|
|
|
|
|
reader.read (gg);
|
|
|
|
|
|
|
|
|
|
const char *expected =
|
|
|
|
|
"begin_lib 0.001\n"
|
|
|
|
|
"begin_cell {$1}\n"
|
|
|
|
|
"box 1 0 {0 100} {1000 1200}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"begin_cell {$4}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"begin_cell {$3}\n"
|
|
|
|
|
"sref {$1} 90 1 1 {-10 20}\n"
|
2017-07-28 00:19:39 +02:00
|
|
|
"sref {$4} 90 1 1 {-10 20}\n"
|
2017-02-12 13:21:08 +01:00
|
|
|
"end_cell\n"
|
|
|
|
|
"begin_cell {$2}\n"
|
|
|
|
|
"sref {$1} 90 1 1 {-10 20}\n"
|
2017-07-28 00:19:39 +02:00
|
|
|
"sref {$3} 90 1 1 {-10 20}\n"
|
2017-02-12 13:21:08 +01:00
|
|
|
"box 2 0 {0 -100} {2000 2200}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"end_lib\n"
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
tl::OutputStringStream os;
|
|
|
|
|
tl::OutputStream stream (os);
|
|
|
|
|
db::TextWriter textwriter (stream);
|
|
|
|
|
textwriter.write (gg);
|
|
|
|
|
EXPECT_EQ (std::string (os.string ()), std::string (expected))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(101)
|
|
|
|
|
{
|
|
|
|
|
db::Manager m;
|
|
|
|
|
db::Layout g (&m);
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp0;
|
|
|
|
|
lp0.layer = 0;
|
|
|
|
|
lp0.datatype = 0;
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp1;
|
|
|
|
|
lp1.layer = 1;
|
|
|
|
|
lp1.datatype = 0;
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp2;
|
|
|
|
|
lp2.layer = 2;
|
|
|
|
|
lp2.datatype = 0;
|
|
|
|
|
|
|
|
|
|
g.insert_layer (0, lp0);
|
|
|
|
|
g.insert_layer (1, lp1);
|
|
|
|
|
g.insert_layer (2, lp2);
|
|
|
|
|
|
|
|
|
|
db::Cell &c1 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c2 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c3 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c4 (g.cell (g.add_cell ()));
|
|
|
|
|
|
|
|
|
|
db::Box b (0, 100, 1000, 1200);
|
|
|
|
|
c1.shapes (1).insert (b);
|
|
|
|
|
|
|
|
|
|
db::Box bb (0, -100, 2000, 2200);
|
|
|
|
|
c2.shapes (2).insert (bb);
|
|
|
|
|
|
|
|
|
|
// inserting instances ..
|
|
|
|
|
db::FTrans f (1, true);
|
|
|
|
|
db::Vector p (-10, 20);
|
|
|
|
|
db::Trans t (f.rot (), p);
|
|
|
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
|
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
|
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c3.cell_index ()), t));
|
|
|
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
|
|
|
|
|
|
|
|
|
|
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter101.gds"));
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::OutputStream out (tmp_file);
|
|
|
|
|
db::SaveLayoutOptions options;
|
|
|
|
|
options.set_format ("OASIS");
|
|
|
|
|
options.add_layer (0);
|
|
|
|
|
options.set_dont_write_empty_cells (true);
|
|
|
|
|
db::Writer writer (options);
|
|
|
|
|
writer.write (g, out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tl::InputStream in (tmp_file);
|
|
|
|
|
db::Reader reader (in);
|
|
|
|
|
db::Layout gg;
|
|
|
|
|
reader.set_warnings_as_errors (true);
|
|
|
|
|
reader.read (gg);
|
|
|
|
|
|
|
|
|
|
const char *expected =
|
|
|
|
|
"begin_lib 0.001\n"
|
|
|
|
|
"begin_cell {$2}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"end_lib\n"
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
tl::OutputStringStream os;
|
|
|
|
|
tl::OutputStream stream (os);
|
|
|
|
|
db::TextWriter textwriter (stream);
|
|
|
|
|
textwriter.write (gg);
|
|
|
|
|
EXPECT_EQ (std::string (os.string ()), std::string (expected))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(102)
|
|
|
|
|
{
|
|
|
|
|
db::Manager m;
|
|
|
|
|
db::Layout g (&m);
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp0;
|
|
|
|
|
lp0.layer = 0;
|
|
|
|
|
lp0.datatype = 0;
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp1;
|
|
|
|
|
lp1.layer = 1;
|
|
|
|
|
lp1.datatype = 0;
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp2;
|
|
|
|
|
lp2.layer = 2;
|
|
|
|
|
lp2.datatype = 0;
|
|
|
|
|
|
|
|
|
|
g.insert_layer (0, lp0);
|
|
|
|
|
g.insert_layer (1, lp1);
|
|
|
|
|
g.insert_layer (2, lp2);
|
|
|
|
|
|
|
|
|
|
db::Cell &c1 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c2 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c3 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c4 (g.cell (g.add_cell ()));
|
|
|
|
|
|
|
|
|
|
db::Box b (0, 100, 1000, 1200);
|
|
|
|
|
c1.shapes (1).insert (b);
|
|
|
|
|
|
|
|
|
|
db::Box bb (0, -100, 2000, 2200);
|
|
|
|
|
c2.shapes (2).insert (bb);
|
|
|
|
|
|
|
|
|
|
// inserting instances ..
|
|
|
|
|
db::FTrans f (1, true);
|
|
|
|
|
db::Vector p (-10, 20);
|
|
|
|
|
db::Trans t (f.rot (), p);
|
|
|
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
|
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
|
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c3.cell_index ()), t));
|
|
|
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
|
|
|
|
|
|
|
|
|
|
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter102.gds"));
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::OutputStream out (tmp_file);
|
|
|
|
|
db::SaveLayoutOptions options;
|
|
|
|
|
options.set_format ("OASIS");
|
|
|
|
|
options.add_layer (1);
|
|
|
|
|
options.set_dont_write_empty_cells (true);
|
|
|
|
|
db::Writer writer (options);
|
|
|
|
|
writer.write (g, out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tl::InputStream in (tmp_file);
|
|
|
|
|
db::Reader reader (in);
|
|
|
|
|
db::Layout gg;
|
|
|
|
|
reader.set_warnings_as_errors (true);
|
|
|
|
|
reader.read (gg);
|
|
|
|
|
|
|
|
|
|
const char *expected =
|
|
|
|
|
"begin_lib 0.001\n"
|
|
|
|
|
"begin_cell {$1}\n"
|
|
|
|
|
"box 1 0 {0 100} {1000 1200}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"begin_cell {$3}\n"
|
|
|
|
|
"sref {$1} 90 1 1 {-10 20}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"begin_cell {$2}\n"
|
|
|
|
|
"sref {$1} 90 1 1 {-10 20}\n"
|
2017-07-28 00:19:39 +02:00
|
|
|
"sref {$3} 90 1 1 {-10 20}\n"
|
2017-02-12 13:21:08 +01:00
|
|
|
"end_cell\n"
|
|
|
|
|
"end_lib\n"
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
tl::OutputStringStream os;
|
|
|
|
|
tl::OutputStream stream (os);
|
|
|
|
|
db::TextWriter textwriter (stream);
|
|
|
|
|
textwriter.write (gg);
|
|
|
|
|
EXPECT_EQ (std::string (os.string ()), std::string (expected))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(103)
|
|
|
|
|
{
|
|
|
|
|
db::Manager m;
|
|
|
|
|
db::Layout g (&m);
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp0;
|
|
|
|
|
lp0.layer = 0;
|
|
|
|
|
lp0.datatype = 0;
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp1;
|
|
|
|
|
lp1.layer = 1;
|
|
|
|
|
lp1.datatype = 0;
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp2;
|
|
|
|
|
lp2.layer = 2;
|
|
|
|
|
lp2.datatype = 0;
|
|
|
|
|
|
|
|
|
|
g.insert_layer (0, lp0);
|
|
|
|
|
g.insert_layer (1, lp1);
|
|
|
|
|
g.insert_layer (2, lp2);
|
|
|
|
|
|
|
|
|
|
db::Cell &c1 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c2 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c3 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c4 (g.cell (g.add_cell ()));
|
|
|
|
|
|
|
|
|
|
db::Box b (0, 100, 1000, 1200);
|
|
|
|
|
c1.shapes (1).insert (b);
|
|
|
|
|
|
|
|
|
|
db::Box bb (0, -100, 2000, 2200);
|
|
|
|
|
c2.shapes (2).insert (bb);
|
|
|
|
|
|
|
|
|
|
// inserting instances ..
|
|
|
|
|
db::FTrans f (1, true);
|
|
|
|
|
db::Vector p (-10, 20);
|
|
|
|
|
db::Trans t (f.rot (), p);
|
|
|
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
|
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
|
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c3.cell_index ()), t));
|
|
|
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
|
|
|
|
|
|
|
|
|
|
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter103.gds"));
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::OutputStream out (tmp_file);
|
|
|
|
|
db::SaveLayoutOptions options;
|
|
|
|
|
options.set_format ("OASIS");
|
|
|
|
|
options.add_layer (2);
|
|
|
|
|
options.set_dont_write_empty_cells (true);
|
|
|
|
|
db::Writer writer (options);
|
|
|
|
|
writer.write (g, out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tl::InputStream in (tmp_file);
|
|
|
|
|
db::Reader reader (in);
|
|
|
|
|
db::Layout gg;
|
|
|
|
|
reader.set_warnings_as_errors (true);
|
|
|
|
|
reader.read (gg);
|
|
|
|
|
|
|
|
|
|
const char *expected =
|
|
|
|
|
"begin_lib 0.001\n"
|
|
|
|
|
"begin_cell {$2}\n"
|
|
|
|
|
"box 2 0 {0 -100} {2000 2200}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"end_lib\n"
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
tl::OutputStringStream os;
|
|
|
|
|
tl::OutputStream stream (os);
|
|
|
|
|
db::TextWriter textwriter (stream);
|
|
|
|
|
textwriter.write (gg);
|
|
|
|
|
EXPECT_EQ (std::string (os.string ()), std::string (expected))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(110)
|
|
|
|
|
{
|
|
|
|
|
db::Manager m;
|
|
|
|
|
db::Layout g (&m);
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp0;
|
|
|
|
|
lp0.layer = 0;
|
|
|
|
|
lp0.datatype = 0;
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp1;
|
|
|
|
|
lp1.layer = 1;
|
|
|
|
|
lp1.datatype = 0;
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp2;
|
|
|
|
|
lp2.layer = 2;
|
|
|
|
|
lp2.datatype = 0;
|
|
|
|
|
|
|
|
|
|
g.insert_layer (0, lp0);
|
|
|
|
|
g.insert_layer (1, lp1);
|
|
|
|
|
g.insert_layer (2, lp2);
|
|
|
|
|
|
|
|
|
|
db::Cell &c1 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c2 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c3 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c4 (g.cell (g.add_cell ()));
|
|
|
|
|
|
|
|
|
|
db::Box b (0, 100, 1000, 1200);
|
|
|
|
|
c1.shapes (1).insert (b);
|
|
|
|
|
|
|
|
|
|
db::Box bb (0, -100, 2000, 2200);
|
|
|
|
|
c2.shapes (2).insert (bb);
|
|
|
|
|
|
|
|
|
|
// inserting instances ..
|
|
|
|
|
db::FTrans f (1, true);
|
|
|
|
|
db::Vector p (-10, 20);
|
|
|
|
|
db::Trans t (f.rot (), p);
|
|
|
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
|
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
|
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c3.cell_index ()), t));
|
|
|
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
|
|
|
|
|
|
|
|
|
|
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter110.gds"));
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::OutputStream out (tmp_file);
|
|
|
|
|
db::SaveLayoutOptions options;
|
|
|
|
|
options.set_format ("OASIS");
|
|
|
|
|
options.set_dont_write_empty_cells (true);
|
|
|
|
|
options.add_cell (c3.cell_index ());
|
|
|
|
|
db::Writer writer (options);
|
|
|
|
|
writer.write (g, out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tl::InputStream in (tmp_file);
|
|
|
|
|
db::Reader reader (in);
|
|
|
|
|
db::Layout gg;
|
|
|
|
|
reader.set_warnings_as_errors (true);
|
|
|
|
|
reader.read (gg);
|
|
|
|
|
|
|
|
|
|
const char *expected =
|
|
|
|
|
"begin_lib 0.001\n"
|
|
|
|
|
"begin_cell {$1}\n"
|
|
|
|
|
"box 1 0 {0 100} {1000 1200}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"begin_cell {$3}\n"
|
|
|
|
|
"sref {$1} 90 1 1 {-10 20}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"end_lib\n"
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
tl::OutputStringStream os;
|
|
|
|
|
tl::OutputStream stream (os);
|
|
|
|
|
db::TextWriter textwriter (stream);
|
|
|
|
|
textwriter.write (gg);
|
|
|
|
|
EXPECT_EQ (std::string (os.string ()), std::string (expected))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(111)
|
|
|
|
|
{
|
|
|
|
|
db::Manager m;
|
|
|
|
|
db::Layout g (&m);
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp0;
|
|
|
|
|
lp0.layer = 0;
|
|
|
|
|
lp0.datatype = 0;
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp1;
|
|
|
|
|
lp1.layer = 1;
|
|
|
|
|
lp1.datatype = 0;
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp2;
|
|
|
|
|
lp2.layer = 2;
|
|
|
|
|
lp2.datatype = 0;
|
|
|
|
|
|
|
|
|
|
g.insert_layer (0, lp0);
|
|
|
|
|
g.insert_layer (1, lp1);
|
|
|
|
|
g.insert_layer (2, lp2);
|
|
|
|
|
|
|
|
|
|
db::Cell &c1 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c2 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c3 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c4 (g.cell (g.add_cell ()));
|
|
|
|
|
|
|
|
|
|
db::Box b (0, 100, 1000, 1200);
|
|
|
|
|
c1.shapes (1).insert (b);
|
|
|
|
|
|
|
|
|
|
db::Box bb (0, -100, 2000, 2200);
|
|
|
|
|
c2.shapes (2).insert (bb);
|
|
|
|
|
|
|
|
|
|
// inserting instances ..
|
|
|
|
|
db::FTrans f (1, true);
|
|
|
|
|
db::Vector p (-10, 20);
|
|
|
|
|
db::Trans t (f.rot (), p);
|
|
|
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
|
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
|
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c3.cell_index ()), t));
|
|
|
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
|
|
|
|
|
|
|
|
|
|
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter111.gds"));
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::OutputStream out (tmp_file);
|
|
|
|
|
db::SaveLayoutOptions options;
|
|
|
|
|
options.set_format ("OASIS");
|
|
|
|
|
options.add_cell (c3.cell_index ());
|
|
|
|
|
options.add_layer (0);
|
|
|
|
|
options.set_dont_write_empty_cells (true);
|
|
|
|
|
db::Writer writer (options);
|
|
|
|
|
writer.write (g, out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tl::InputStream in (tmp_file);
|
|
|
|
|
db::Reader reader (in);
|
|
|
|
|
db::Layout gg;
|
|
|
|
|
reader.set_warnings_as_errors (true);
|
|
|
|
|
reader.read (gg);
|
|
|
|
|
|
|
|
|
|
const char *expected =
|
|
|
|
|
"begin_lib 0.001\n"
|
|
|
|
|
"begin_cell {$3}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"end_lib\n"
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
tl::OutputStringStream os;
|
|
|
|
|
tl::OutputStream stream (os);
|
|
|
|
|
db::TextWriter textwriter (stream);
|
|
|
|
|
textwriter.write (gg);
|
|
|
|
|
EXPECT_EQ (std::string (os.string ()), std::string (expected))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(112)
|
|
|
|
|
{
|
|
|
|
|
db::Manager m;
|
|
|
|
|
db::Layout g (&m);
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp0;
|
|
|
|
|
lp0.layer = 0;
|
|
|
|
|
lp0.datatype = 0;
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp1;
|
|
|
|
|
lp1.layer = 1;
|
|
|
|
|
lp1.datatype = 0;
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp2;
|
|
|
|
|
lp2.layer = 2;
|
|
|
|
|
lp2.datatype = 0;
|
|
|
|
|
|
|
|
|
|
g.insert_layer (0, lp0);
|
|
|
|
|
g.insert_layer (1, lp1);
|
|
|
|
|
g.insert_layer (2, lp2);
|
|
|
|
|
|
|
|
|
|
db::Cell &c1 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c2 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c3 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c4 (g.cell (g.add_cell ()));
|
|
|
|
|
|
|
|
|
|
db::Box b (0, 100, 1000, 1200);
|
|
|
|
|
c1.shapes (1).insert (b);
|
|
|
|
|
|
|
|
|
|
db::Box bb (0, -100, 2000, 2200);
|
|
|
|
|
c2.shapes (2).insert (bb);
|
|
|
|
|
|
|
|
|
|
// inserting instances ..
|
|
|
|
|
db::FTrans f (1, true);
|
|
|
|
|
db::Vector p (-10, 20);
|
|
|
|
|
db::Trans t (f.rot (), p);
|
|
|
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
|
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
|
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c3.cell_index ()), t));
|
|
|
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
|
|
|
|
|
|
|
|
|
|
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter112.gds"));
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::OutputStream out (tmp_file);
|
|
|
|
|
db::SaveLayoutOptions options;
|
|
|
|
|
options.set_format ("OASIS");
|
|
|
|
|
options.add_cell (c3.cell_index ());
|
|
|
|
|
options.add_layer (1);
|
|
|
|
|
options.set_dont_write_empty_cells (true);
|
|
|
|
|
db::Writer writer (options);
|
|
|
|
|
writer.write (g, out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tl::InputStream in (tmp_file);
|
|
|
|
|
db::Reader reader (in);
|
|
|
|
|
db::Layout gg;
|
|
|
|
|
reader.set_warnings_as_errors (true);
|
|
|
|
|
reader.read (gg);
|
|
|
|
|
|
|
|
|
|
const char *expected =
|
|
|
|
|
"begin_lib 0.001\n"
|
|
|
|
|
"begin_cell {$1}\n"
|
|
|
|
|
"box 1 0 {0 100} {1000 1200}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"begin_cell {$3}\n"
|
|
|
|
|
"sref {$1} 90 1 1 {-10 20}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"end_lib\n"
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
tl::OutputStringStream os;
|
|
|
|
|
tl::OutputStream stream (os);
|
|
|
|
|
db::TextWriter textwriter (stream);
|
|
|
|
|
textwriter.write (gg);
|
|
|
|
|
EXPECT_EQ (std::string (os.string ()), std::string (expected))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(113)
|
|
|
|
|
{
|
|
|
|
|
db::Manager m;
|
|
|
|
|
db::Layout g (&m);
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp0;
|
|
|
|
|
lp0.layer = 0;
|
|
|
|
|
lp0.datatype = 0;
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp1;
|
|
|
|
|
lp1.layer = 1;
|
|
|
|
|
lp1.datatype = 0;
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp2;
|
|
|
|
|
lp2.layer = 2;
|
|
|
|
|
lp2.datatype = 0;
|
|
|
|
|
|
|
|
|
|
g.insert_layer (0, lp0);
|
|
|
|
|
g.insert_layer (1, lp1);
|
|
|
|
|
g.insert_layer (2, lp2);
|
|
|
|
|
|
|
|
|
|
db::Cell &c1 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c2 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c3 (g.cell (g.add_cell ()));
|
|
|
|
|
db::Cell &c4 (g.cell (g.add_cell ()));
|
|
|
|
|
|
|
|
|
|
db::Box b (0, 100, 1000, 1200);
|
|
|
|
|
c1.shapes (1).insert (b);
|
|
|
|
|
|
|
|
|
|
db::Box bb (0, -100, 2000, 2200);
|
|
|
|
|
c2.shapes (2).insert (bb);
|
|
|
|
|
|
|
|
|
|
// inserting instances ..
|
|
|
|
|
db::FTrans f (1, true);
|
|
|
|
|
db::Vector p (-10, 20);
|
|
|
|
|
db::Trans t (f.rot (), p);
|
|
|
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
|
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
|
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c3.cell_index ()), t));
|
|
|
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
|
|
|
|
|
|
|
|
|
|
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter113.gds"));
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::OutputStream out (tmp_file);
|
|
|
|
|
db::SaveLayoutOptions options;
|
|
|
|
|
options.set_format ("OASIS");
|
|
|
|
|
options.add_cell (c3.cell_index ());
|
|
|
|
|
options.add_layer (2);
|
|
|
|
|
options.set_dont_write_empty_cells (true);
|
|
|
|
|
db::Writer writer (options);
|
|
|
|
|
writer.write (g, out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tl::InputStream in (tmp_file);
|
|
|
|
|
db::Reader reader (in);
|
|
|
|
|
db::Layout gg;
|
|
|
|
|
reader.set_warnings_as_errors (true);
|
|
|
|
|
reader.read (gg);
|
|
|
|
|
|
|
|
|
|
const char *expected =
|
|
|
|
|
"begin_lib 0.001\n"
|
|
|
|
|
"begin_cell {$3}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"end_lib\n"
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
tl::OutputStringStream os;
|
|
|
|
|
tl::OutputStream stream (os);
|
|
|
|
|
db::TextWriter textwriter (stream);
|
|
|
|
|
textwriter.write (gg);
|
|
|
|
|
EXPECT_EQ (std::string (os.string ()), std::string (expected))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(114)
|
|
|
|
|
{
|
|
|
|
|
db::Manager m;
|
|
|
|
|
db::Layout g (&m);
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp1;
|
|
|
|
|
lp1.layer = 1;
|
|
|
|
|
lp1.datatype = 0;
|
|
|
|
|
|
|
|
|
|
g.insert_layer (1, lp1);
|
|
|
|
|
|
|
|
|
|
db::Cell &c1 (g.cell (g.add_cell ()));
|
|
|
|
|
|
|
|
|
|
db::Edge e1 (0, 100, 1000, 1200);
|
|
|
|
|
c1.shapes (1).insert (e1);
|
|
|
|
|
|
|
|
|
|
db::Edge e2 (0, 100, 0, 1200);
|
|
|
|
|
c1.shapes (1).insert (e2);
|
|
|
|
|
|
|
|
|
|
db::Edge e3 (0, 1200, 1000, 1200);
|
|
|
|
|
c1.shapes (1).insert (e3);
|
|
|
|
|
|
|
|
|
|
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter114.gds"));
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::OutputStream out (tmp_file);
|
|
|
|
|
db::SaveLayoutOptions options;
|
|
|
|
|
options.set_format ("OASIS");
|
|
|
|
|
db::Writer writer (options);
|
|
|
|
|
writer.write (g, out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tl::InputStream in (tmp_file);
|
|
|
|
|
db::Reader reader (in);
|
|
|
|
|
db::Layout gg;
|
|
|
|
|
reader.set_warnings_as_errors (true);
|
|
|
|
|
reader.read (gg);
|
|
|
|
|
|
|
|
|
|
const char *expected =
|
|
|
|
|
"begin_lib 0.001\n"
|
|
|
|
|
"begin_cell {$1}\n"
|
|
|
|
|
"path 1 0 0 0 0 {0 1200} {1000 1200}\n"
|
|
|
|
|
"path 1 0 0 0 0 {0 100} {1000 1200}\n"
|
2017-07-28 00:19:39 +02:00
|
|
|
"path 1 0 0 0 0 {0 100} {0 1200}\n"
|
2017-02-12 13:21:08 +01:00
|
|
|
"end_cell\n"
|
|
|
|
|
"end_lib\n"
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
tl::OutputStringStream os;
|
|
|
|
|
tl::OutputStream stream (os);
|
|
|
|
|
db::TextWriter textwriter (stream);
|
|
|
|
|
textwriter.write (gg);
|
|
|
|
|
EXPECT_EQ (std::string (os.string ()), std::string (expected))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(115)
|
|
|
|
|
{
|
|
|
|
|
db::Manager m;
|
|
|
|
|
db::Layout g (&m);
|
|
|
|
|
|
|
|
|
|
db::property_names_id_type n1, n2, n3;
|
|
|
|
|
n1 = g.properties_repository ().prop_name_id (tl::Variant (17));
|
|
|
|
|
n2 = g.properties_repository ().prop_name_id (tl::Variant ("name"));
|
|
|
|
|
n3 = g.properties_repository ().prop_name_id (tl::Variant ((unsigned int) 42));
|
|
|
|
|
|
|
|
|
|
db::PropertiesRepository::properties_set s1;
|
|
|
|
|
s1.insert (std::make_pair (n1, tl::Variant ("17value")));
|
|
|
|
|
s1.insert (std::make_pair (n2, tl::Variant (117)));
|
|
|
|
|
|
|
|
|
|
db::PropertiesRepository::properties_set s2;
|
|
|
|
|
s2.insert (std::make_pair (n3, tl::Variant (42)));
|
|
|
|
|
|
|
|
|
|
db::properties_id_type p1 = g.properties_repository ().properties_id (s1);
|
|
|
|
|
db::properties_id_type p2 = g.properties_repository ().properties_id (s2);
|
|
|
|
|
|
|
|
|
|
g.prop_id (p1);
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp1;
|
|
|
|
|
lp1.layer = 1;
|
|
|
|
|
lp1.datatype = 0;
|
|
|
|
|
|
|
|
|
|
g.insert_layer (1, lp1);
|
|
|
|
|
|
|
|
|
|
db::Cell &c1 (g.cell (g.add_cell ()));
|
|
|
|
|
c1.prop_id (p2);
|
|
|
|
|
|
|
|
|
|
db::Edge e1 (0, 100, 1000, 1200);
|
|
|
|
|
c1.shapes (1).insert (e1);
|
|
|
|
|
|
|
|
|
|
db::Edge e2 (0, 100, 0, 1200);
|
|
|
|
|
c1.shapes (1).insert (e2);
|
|
|
|
|
|
|
|
|
|
db::Edge e3 (0, 1200, 1000, 1200);
|
|
|
|
|
c1.shapes (1).insert (e3);
|
|
|
|
|
|
|
|
|
|
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter115.gds"));
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::OutputStream out (tmp_file);
|
|
|
|
|
db::SaveLayoutOptions options;
|
|
|
|
|
options.set_format ("OASIS");
|
|
|
|
|
db::Writer writer (options);
|
|
|
|
|
writer.write (g, out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tl::InputStream in (tmp_file);
|
|
|
|
|
db::Reader reader (in);
|
|
|
|
|
db::Layout gg;
|
|
|
|
|
reader.set_warnings_as_errors (true);
|
|
|
|
|
reader.read (gg);
|
|
|
|
|
|
|
|
|
|
const char *expected =
|
|
|
|
|
"set props {\n"
|
|
|
|
|
" {17 {17value}}\n"
|
|
|
|
|
" {{name} {117}}\n"
|
|
|
|
|
"}\n"
|
|
|
|
|
"begin_libp $props 0.001\n"
|
|
|
|
|
"set props {\n"
|
|
|
|
|
" {42 {42}}\n"
|
|
|
|
|
"}\n"
|
|
|
|
|
"begin_cellp $props {$1}\n"
|
|
|
|
|
"path 1 0 0 0 0 {0 1200} {1000 1200}\n"
|
|
|
|
|
"path 1 0 0 0 0 {0 100} {1000 1200}\n"
|
2017-07-28 00:19:39 +02:00
|
|
|
"path 1 0 0 0 0 {0 100} {0 1200}\n"
|
2017-02-12 13:21:08 +01:00
|
|
|
"end_cell\n"
|
|
|
|
|
"end_lib\n"
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
tl::OutputStringStream os;
|
|
|
|
|
tl::OutputStream stream (os);
|
|
|
|
|
db::TextWriter textwriter (stream);
|
|
|
|
|
textwriter.write (gg);
|
|
|
|
|
EXPECT_EQ (std::string (os.string ()), std::string (expected))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(118)
|
|
|
|
|
{
|
|
|
|
|
// 1x1 arrays (#902)
|
|
|
|
|
|
|
|
|
|
db::Manager m;
|
|
|
|
|
db::Layout g (&m);
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp1;
|
|
|
|
|
lp1.layer = 1;
|
|
|
|
|
lp1.datatype = 0;
|
|
|
|
|
|
|
|
|
|
g.insert_layer (0, lp1);
|
|
|
|
|
|
|
|
|
|
db::Cell &c1 (g.cell (g.add_cell ()));
|
|
|
|
|
c1.shapes (0).insert (db::Box (100, 0, 100, 200));
|
|
|
|
|
|
|
|
|
|
db::Cell &c2 (g.cell (g.add_cell ()));
|
|
|
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), db::Trans (), db::Vector (0, 1), db::Vector (1, 0), 1, 1));
|
|
|
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), db::Trans (db::Vector (17, -42)), db::Vector (0, 1), db::Vector (1, 0), 1, 1));
|
|
|
|
|
|
|
|
|
|
std::string tmp_file = ut::TestBase::tmp_file ("tmp.oas");
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::OutputStream out (tmp_file);
|
|
|
|
|
db::SaveLayoutOptions options;
|
|
|
|
|
options.set_format ("OASIS");
|
|
|
|
|
db::Writer writer (options);
|
|
|
|
|
writer.write (g, out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tl::InputStream in (tmp_file);
|
|
|
|
|
db::Reader reader (in);
|
|
|
|
|
db::Layout gg;
|
|
|
|
|
reader.set_warnings_as_errors (true);
|
|
|
|
|
reader.read (gg);
|
|
|
|
|
|
|
|
|
|
const char *expected =
|
|
|
|
|
"begin_lib 0.001\n"
|
|
|
|
|
"begin_cell {$1}\n"
|
|
|
|
|
"box 1 0 {100 0} {100 200}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"begin_cell {$2}\n"
|
|
|
|
|
"sref {$1} 0 0 1 {17 -42}\n"
|
|
|
|
|
"sref {$1} 0 0 1 {0 0}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"end_lib\n"
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
tl::OutputStringStream os;
|
|
|
|
|
tl::OutputStream stream (os);
|
|
|
|
|
db::TextWriter textwriter (stream);
|
|
|
|
|
textwriter.write (gg);
|
|
|
|
|
EXPECT_EQ (std::string (os.string ()), std::string (expected))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(116)
|
|
|
|
|
{
|
|
|
|
|
db::Manager m;
|
|
|
|
|
db::Layout g (&m);
|
|
|
|
|
|
|
|
|
|
db::property_names_id_type n1, n2, n3;
|
|
|
|
|
n1 = g.properties_repository ().prop_name_id (tl::Variant (17));
|
|
|
|
|
n2 = g.properties_repository ().prop_name_id (tl::Variant ("name"));
|
|
|
|
|
n3 = g.properties_repository ().prop_name_id (tl::Variant ((unsigned int) 42));
|
|
|
|
|
|
|
|
|
|
db::PropertiesRepository::properties_set s1;
|
|
|
|
|
s1.insert (std::make_pair (n1, tl::Variant ("17value")));
|
|
|
|
|
s1.insert (std::make_pair (n2, tl::Variant (117)));
|
|
|
|
|
|
|
|
|
|
db::PropertiesRepository::properties_set s2;
|
|
|
|
|
s2.insert (std::make_pair (n3, tl::Variant (42)));
|
|
|
|
|
|
|
|
|
|
db::properties_id_type p1 = g.properties_repository ().properties_id (s1);
|
|
|
|
|
db::properties_id_type p2 = g.properties_repository ().properties_id (s2);
|
|
|
|
|
|
|
|
|
|
g.prop_id (p1);
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp1;
|
|
|
|
|
lp1.layer = 1;
|
|
|
|
|
lp1.datatype = 0;
|
|
|
|
|
|
|
|
|
|
g.insert_layer (1, lp1);
|
|
|
|
|
|
|
|
|
|
db::Cell &c1 (g.cell (g.add_cell ()));
|
|
|
|
|
c1.prop_id (p2);
|
|
|
|
|
|
|
|
|
|
db::Edge e1 (0, 100, 1000, 1200);
|
|
|
|
|
c1.shapes (1).insert (e1);
|
|
|
|
|
|
|
|
|
|
db::Cell &c2 (g.cell (g.add_cell ()));
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter116a.gds"));
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::OutputStream out (tmp_file);
|
|
|
|
|
db::SaveLayoutOptions write_options;
|
|
|
|
|
write_options.set_format ("OASIS");
|
|
|
|
|
db::Writer writer (write_options);
|
|
|
|
|
writer.write (g, out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tl::InputStream in (tmp_file);
|
|
|
|
|
db::OASISReaderOptions oas_options;
|
|
|
|
|
oas_options.read_all_properties = true;
|
|
|
|
|
db::LoadLayoutOptions options;
|
|
|
|
|
options.set_options (oas_options);
|
|
|
|
|
db::Reader reader (in);
|
|
|
|
|
db::Layout gg;
|
|
|
|
|
reader.set_warnings_as_errors (true);
|
|
|
|
|
reader.read (gg, options);
|
|
|
|
|
|
|
|
|
|
const char *expected =
|
|
|
|
|
"set props {\n"
|
|
|
|
|
" {{S_MAX_SIGNED_INTEGER_WIDTH} {4}}\n"
|
|
|
|
|
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {4}}\n"
|
|
|
|
|
" {{S_TOP_CELL} {$2}}\n"
|
|
|
|
|
" {{S_TOP_CELL} {$1}}\n"
|
|
|
|
|
" {17 {17value}}\n"
|
|
|
|
|
" {{name} {117}}\n"
|
|
|
|
|
"}\n"
|
|
|
|
|
"begin_libp $props 0.001\n"
|
|
|
|
|
"set props {\n"
|
|
|
|
|
" {42 {42}}\n"
|
|
|
|
|
"}\n"
|
|
|
|
|
"begin_cellp $props {$1}\n"
|
|
|
|
|
"path 1 0 0 0 0 {0 100} {1000 1200}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"begin_cell {$2}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"end_lib\n"
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
tl::OutputStringStream os;
|
|
|
|
|
tl::OutputStream stream (os);
|
|
|
|
|
db::TextWriter textwriter (stream);
|
|
|
|
|
textwriter.write (gg);
|
|
|
|
|
EXPECT_EQ (std::string (os.string ()), std::string (expected))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter116b.gds"));
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::OutputStream out (tmp_file);
|
|
|
|
|
db::SaveLayoutOptions write_options;
|
|
|
|
|
write_options.set_format ("OASIS");
|
|
|
|
|
db::OASISWriterOptions oas_write_options;
|
|
|
|
|
oas_write_options.write_std_properties = 0;
|
|
|
|
|
write_options.set_options (oas_write_options);
|
|
|
|
|
db::Writer writer (write_options);
|
|
|
|
|
writer.write (g, out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tl::InputStream in (tmp_file);
|
|
|
|
|
db::OASISReaderOptions oas_options;
|
|
|
|
|
oas_options.read_all_properties = true;
|
|
|
|
|
oas_options.expect_strict_mode = 0;
|
|
|
|
|
db::LoadLayoutOptions options;
|
|
|
|
|
options.set_options (oas_options);
|
|
|
|
|
db::Reader reader (in);
|
|
|
|
|
db::Layout gg;
|
|
|
|
|
reader.set_warnings_as_errors (true);
|
|
|
|
|
reader.read (gg, options);
|
|
|
|
|
|
|
|
|
|
const char *expected =
|
|
|
|
|
"set props {\n"
|
|
|
|
|
" {17 {17value}}\n"
|
|
|
|
|
" {{name} {117}}\n"
|
|
|
|
|
"}\n"
|
|
|
|
|
"begin_libp $props 0.001\n"
|
|
|
|
|
"set props {\n"
|
|
|
|
|
" {42 {42}}\n"
|
|
|
|
|
"}\n"
|
|
|
|
|
"begin_cellp $props {$1}\n"
|
|
|
|
|
"path 1 0 0 0 0 {0 100} {1000 1200}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"begin_cell {$2}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"end_lib\n"
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
tl::OutputStringStream os;
|
|
|
|
|
tl::OutputStream stream (os);
|
|
|
|
|
db::TextWriter textwriter (stream);
|
|
|
|
|
textwriter.write (gg);
|
|
|
|
|
EXPECT_EQ (std::string (os.string ()), std::string (expected))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter116c.gds"));
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::OutputStream out (tmp_file);
|
|
|
|
|
db::SaveLayoutOptions write_options;
|
|
|
|
|
write_options.set_format ("OASIS");
|
|
|
|
|
db::OASISWriterOptions oas_write_options;
|
|
|
|
|
oas_write_options.write_std_properties = 2;
|
|
|
|
|
write_options.set_options (oas_write_options);
|
|
|
|
|
db::Writer writer (write_options);
|
|
|
|
|
writer.write (g, out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tl::InputStream in (tmp_file);
|
|
|
|
|
db::OASISReaderOptions oas_options;
|
|
|
|
|
oas_options.read_all_properties = true;
|
|
|
|
|
oas_options.expect_strict_mode = 0;
|
|
|
|
|
db::LoadLayoutOptions options;
|
|
|
|
|
options.set_options (oas_options);
|
|
|
|
|
db::Reader reader (in);
|
|
|
|
|
db::Layout gg;
|
|
|
|
|
reader.set_warnings_as_errors (true);
|
|
|
|
|
reader.read (gg, options);
|
|
|
|
|
|
|
|
|
|
const char *expected =
|
|
|
|
|
"set props {\n"
|
|
|
|
|
" {{S_MAX_SIGNED_INTEGER_WIDTH} {4}}\n"
|
|
|
|
|
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {4}}\n"
|
|
|
|
|
" {{S_TOP_CELL} {$2}}\n"
|
|
|
|
|
" {{S_TOP_CELL} {$1}}\n"
|
|
|
|
|
" {{S_BOUNDING_BOXES_AVAILABLE} {2}}\n"
|
|
|
|
|
" {17 {17value}}\n"
|
|
|
|
|
" {{name} {117}}\n"
|
|
|
|
|
"}\n"
|
|
|
|
|
"begin_libp $props 0.001\n"
|
|
|
|
|
"set props {\n"
|
|
|
|
|
" {{S_BOUNDING_BOX} {0,0,100,1000,1100}}\n"
|
|
|
|
|
" {42 {42}}\n"
|
|
|
|
|
"}\n"
|
|
|
|
|
"begin_cellp $props {$1}\n"
|
|
|
|
|
"path 1 0 0 0 0 {0 100} {1000 1200}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"set props {\n"
|
|
|
|
|
" {{S_BOUNDING_BOX} {2,0,0,0,0}}\n"
|
|
|
|
|
"}\n"
|
|
|
|
|
"begin_cellp $props {$2}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"end_lib\n"
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
tl::OutputStringStream os;
|
|
|
|
|
tl::OutputStream stream (os);
|
|
|
|
|
db::TextWriter textwriter (stream);
|
|
|
|
|
textwriter.write (gg);
|
|
|
|
|
EXPECT_EQ (std::string (os.string ()), std::string (expected))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
std::string tmp_file = ut::TestBase::tmp_file ("tmp_dbOASISWriter116d.gds");
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::OutputStream out (tmp_file);
|
|
|
|
|
db::SaveLayoutOptions write_options;
|
|
|
|
|
write_options.set_format ("OASIS");
|
|
|
|
|
db::OASISWriterOptions oas_write_options;
|
|
|
|
|
oas_write_options.write_std_properties = 2;
|
|
|
|
|
oas_write_options.strict_mode = true;
|
|
|
|
|
write_options.set_options (oas_write_options);
|
|
|
|
|
db::Writer writer (write_options);
|
|
|
|
|
writer.write (g, out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tl::InputStream in (tmp_file);
|
|
|
|
|
db::OASISReaderOptions oas_options;
|
|
|
|
|
oas_options.read_all_properties = true;
|
|
|
|
|
oas_options.expect_strict_mode = 1;
|
|
|
|
|
db::LoadLayoutOptions options;
|
|
|
|
|
options.set_options (oas_options);
|
|
|
|
|
db::Reader reader (in);
|
|
|
|
|
db::Layout gg;
|
|
|
|
|
reader.set_warnings_as_errors (true);
|
|
|
|
|
reader.read (gg, options);
|
|
|
|
|
|
|
|
|
|
const char *expected =
|
|
|
|
|
"set props {\n"
|
|
|
|
|
" {{S_MAX_SIGNED_INTEGER_WIDTH} {4}}\n"
|
|
|
|
|
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {4}}\n"
|
|
|
|
|
" {{S_TOP_CELL} {$2}}\n"
|
|
|
|
|
" {{S_TOP_CELL} {$1}}\n"
|
|
|
|
|
" {{S_BOUNDING_BOXES_AVAILABLE} {2}}\n"
|
|
|
|
|
" {{name} {117}}\n"
|
|
|
|
|
" {17 {17value}}\n"
|
|
|
|
|
"}\n"
|
|
|
|
|
"begin_libp $props 0.001\n"
|
|
|
|
|
"set props {\n"
|
|
|
|
|
" {42 {42}}\n"
|
|
|
|
|
" {{S_BOUNDING_BOX} {0,0,100,1000,1100}}\n"
|
|
|
|
|
" {{S_CELL_OFFSET} {231}}\n"
|
|
|
|
|
"}\n"
|
|
|
|
|
"begin_cellp $props {$1}\n"
|
|
|
|
|
"path 1 0 0 0 0 {0 100} {1000 1200}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"set props {\n"
|
|
|
|
|
" {{S_BOUNDING_BOX} {2,0,0,0,0}}\n"
|
|
|
|
|
" {{S_CELL_OFFSET} {229}}\n"
|
|
|
|
|
"}\n"
|
|
|
|
|
"begin_cellp $props {$2}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"end_lib\n"
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
tl::OutputStringStream os;
|
|
|
|
|
tl::OutputStream stream (os);
|
|
|
|
|
db::TextWriter textwriter (stream);
|
|
|
|
|
textwriter.write (gg);
|
|
|
|
|
EXPECT_EQ (std::string (os.string ()), std::string (expected))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c1.insert (db::CellInstArray (c2.cell_index (), db::Trans ()));
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
std::string tmp_file = ut::TestBase::tmp_file ("tmp_dbOASISWriter116e.gds");
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::OutputStream out (tmp_file);
|
|
|
|
|
db::SaveLayoutOptions write_options;
|
|
|
|
|
write_options.set_format ("OASIS");
|
|
|
|
|
db::Writer writer (write_options);
|
|
|
|
|
writer.write (g, out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tl::InputStream in (tmp_file);
|
|
|
|
|
db::OASISReaderOptions oas_options;
|
|
|
|
|
oas_options.read_all_properties = true;
|
|
|
|
|
db::LoadLayoutOptions options;
|
|
|
|
|
options.set_options (oas_options);
|
|
|
|
|
db::Reader reader (in);
|
|
|
|
|
db::Layout gg;
|
|
|
|
|
reader.set_warnings_as_errors (true);
|
|
|
|
|
reader.read (gg, options);
|
|
|
|
|
|
|
|
|
|
const char *expected =
|
|
|
|
|
"set props {\n"
|
|
|
|
|
" {{S_MAX_SIGNED_INTEGER_WIDTH} {4}}\n"
|
|
|
|
|
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {4}}\n"
|
|
|
|
|
" {{S_TOP_CELL} {$1}}\n"
|
|
|
|
|
" {17 {17value}}\n"
|
|
|
|
|
" {{name} {117}}\n"
|
|
|
|
|
"}\n"
|
|
|
|
|
"begin_libp $props 0.001\n"
|
|
|
|
|
"begin_cell {$2}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"set props {\n"
|
|
|
|
|
" {42 {42}}\n"
|
|
|
|
|
"}\n"
|
|
|
|
|
"begin_cellp $props {$1}\n"
|
|
|
|
|
"sref {$2} 0 0 1 {0 0}\n"
|
|
|
|
|
"path 1 0 0 0 0 {0 100} {1000 1200}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"end_lib\n"
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
tl::OutputStringStream os;
|
|
|
|
|
tl::OutputStream stream (os);
|
|
|
|
|
db::TextWriter textwriter (stream);
|
|
|
|
|
textwriter.write (gg);
|
|
|
|
|
EXPECT_EQ (std::string (os.string ()), std::string (expected))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
std::string tmp_file = ut::TestBase::tmp_file ("tmp_dbOASISWriter116f.gds");
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::OutputStream out (tmp_file);
|
|
|
|
|
db::SaveLayoutOptions write_options;
|
|
|
|
|
write_options.select_cell (c2.cell_index ());
|
|
|
|
|
write_options.set_format ("OASIS");
|
|
|
|
|
db::Writer writer (write_options);
|
|
|
|
|
writer.write (g, out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tl::InputStream in (tmp_file);
|
|
|
|
|
db::OASISReaderOptions oas_options;
|
|
|
|
|
oas_options.read_all_properties = true;
|
|
|
|
|
db::LoadLayoutOptions options;
|
|
|
|
|
options.set_options (oas_options);
|
|
|
|
|
db::Reader reader (in);
|
|
|
|
|
db::Layout gg;
|
|
|
|
|
reader.set_warnings_as_errors (true);
|
|
|
|
|
reader.read (gg, options);
|
|
|
|
|
|
|
|
|
|
const char *expected =
|
|
|
|
|
"set props {\n"
|
|
|
|
|
" {{S_MAX_SIGNED_INTEGER_WIDTH} {4}}\n"
|
|
|
|
|
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {4}}\n"
|
|
|
|
|
" {{S_TOP_CELL} {$2}}\n"
|
|
|
|
|
" {17 {17value}}\n"
|
|
|
|
|
" {{name} {117}}\n"
|
|
|
|
|
"}\n"
|
|
|
|
|
"begin_libp $props 0.001\n"
|
|
|
|
|
"begin_cell {$2}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"end_lib\n"
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
tl::OutputStringStream os;
|
|
|
|
|
tl::OutputStream stream (os);
|
|
|
|
|
db::TextWriter textwriter (stream);
|
|
|
|
|
textwriter.write (gg);
|
|
|
|
|
EXPECT_EQ (std::string (os.string ()), std::string (expected))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(117)
|
|
|
|
|
{
|
|
|
|
|
// polygons and boxes without area
|
|
|
|
|
|
|
|
|
|
db::Manager m;
|
|
|
|
|
db::Layout g (&m);
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp1;
|
|
|
|
|
lp1.layer = 1;
|
|
|
|
|
lp1.datatype = 0;
|
|
|
|
|
|
|
|
|
|
g.insert_layer (0, lp1);
|
|
|
|
|
|
|
|
|
|
db::Cell &c1 (g.cell (g.add_cell ()));
|
|
|
|
|
|
|
|
|
|
c1.shapes (0).insert (db::Box (100, 0, 100, 200));
|
|
|
|
|
c1.shapes (0).insert (db::Box (100, -20, 100, -20));
|
|
|
|
|
|
|
|
|
|
db::Point pts[] = {
|
|
|
|
|
db::Point (100, 15),
|
|
|
|
|
db::Point (150, 15),
|
|
|
|
|
db::Point (120, 15)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
db::Polygon p;
|
|
|
|
|
p.assign_hull (&pts[0], &pts[sizeof (pts) / sizeof(pts[0])], false);
|
|
|
|
|
c1.shapes (0).insert (p);
|
|
|
|
|
|
|
|
|
|
db::SimplePolygon ps;
|
|
|
|
|
ps.assign_hull (&pts[0], &pts[sizeof (pts) / sizeof(pts[0])], false);
|
|
|
|
|
ps.transform (db::FTrans (db::FTrans::r90), false);
|
|
|
|
|
c1.shapes (0).insert (ps);
|
|
|
|
|
|
|
|
|
|
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter117.gds"));
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
tl::OutputStream out (tmp_file);
|
|
|
|
|
db::SaveLayoutOptions options;
|
|
|
|
|
options.set_format ("OASIS");
|
|
|
|
|
db::Writer writer (options);
|
|
|
|
|
writer.write (g, out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tl::InputStream in (tmp_file);
|
|
|
|
|
db::Reader reader (in);
|
|
|
|
|
db::Layout gg;
|
|
|
|
|
reader.set_warnings_as_errors (true);
|
|
|
|
|
reader.read (gg);
|
|
|
|
|
|
|
|
|
|
const char *expected =
|
|
|
|
|
"begin_lib 0.001\n"
|
|
|
|
|
"begin_cell {$1}\n"
|
|
|
|
|
"boundary 1 0 {-15 100} {-15 120} {-15 150} {-15 100}\n"
|
|
|
|
|
"boundary 1 0 {100 15} {150 15} {120 15} {100 15}\n"
|
|
|
|
|
"box 1 0 {100 -20} {100 -20}\n"
|
|
|
|
|
"box 1 0 {100 0} {100 200}\n"
|
|
|
|
|
"end_cell\n"
|
|
|
|
|
"end_lib\n"
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
tl::OutputStringStream os;
|
|
|
|
|
tl::OutputStream stream (os);
|
|
|
|
|
db::TextWriter textwriter (stream);
|
|
|
|
|
textwriter.write (gg);
|
|
|
|
|
EXPECT_EQ (std::string (os.string ()), std::string (expected))
|
|
|
|
|
}
|
|
|
|
|
|