mirror of https://github.com/KLayout/klayout.git
2103 lines
53 KiB
C++
2103 lines
53 KiB
C++
|
|
/*
|
|
|
|
KLayout Layout Viewer
|
|
Copyright (C) 2006-2025 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 "dbOASISWriter.h"
|
|
#include "dbOASISReader.h"
|
|
#include "dbLayoutDiff.h"
|
|
#include "dbWriter.h"
|
|
#include "dbTextWriter.h"
|
|
#include "dbLibraryProxy.h"
|
|
#include "dbTestSupport.h"
|
|
|
|
#include "tlUnitTest.h"
|
|
|
|
#include <cstdlib>
|
|
|
|
void run_test (tl::TestBase *_this, const char *file, bool scaling_test, int compr, bool recompress, bool tables_at_end)
|
|
{
|
|
{
|
|
db::Manager m (false);
|
|
db::Layout layout_org (&m);
|
|
std::string fn (tl::testdata ());
|
|
fn += "/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;
|
|
db::OASISWriterOptions oasis_options;
|
|
oasis_options.write_cblocks = false;
|
|
oasis_options.strict_mode = false;
|
|
oasis_options.tables_at_end = tables_at_end;
|
|
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;
|
|
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 (false);
|
|
db::Layout layout_org (&m);
|
|
std::string fn (tl::testdata ());
|
|
fn += "/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;
|
|
oasis_options.tables_at_end = tables_at_end;
|
|
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 (false);
|
|
db::Layout layout_org (&m);
|
|
std::string fn (tl::testdata ());
|
|
fn += "/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.write_cblocks = false;
|
|
oasis_options.strict_mode = false;
|
|
oasis_options.tables_at_end = tables_at_end;
|
|
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 (false);
|
|
db::Layout layout_org (&m);
|
|
std::string fn (tl::testdata ());
|
|
fn += "/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.tables_at_end = tables_at_end;
|
|
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 (false);
|
|
db::Layout layout (&m);
|
|
std::string fn (tl::testdata ());
|
|
fn += "/oasis/";
|
|
fn += file;
|
|
tl::InputStream stream (fn);
|
|
db::Reader reader (stream);
|
|
reader.read (layout);
|
|
|
|
// named layers create a mismatch between GDS and OASIS, so we unname them here
|
|
for (auto l = layout.begin_layers (); l != layout.end_layers (); ++l) {
|
|
db::LayerProperties lp = layout.get_properties ((*l).first);
|
|
lp.name.clear ();
|
|
layout.set_properties ((*l).first, lp);
|
|
}
|
|
|
|
db::SaveLayoutOptions options;
|
|
db::OASISWriterOptions oasis_options;
|
|
oasis_options.compression_level = compr;
|
|
oasis_options.recompress = recompress;
|
|
oasis_options.tables_at_end = tables_at_end;
|
|
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::SaveLayoutOptions gds2_options = options;
|
|
gds2_options.set_format ("GDS2");
|
|
db::Writer writer (gds2_options);
|
|
writer.write (layout, stream);
|
|
}
|
|
|
|
{
|
|
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 (tl::TestBase *_this, const char *file, bool scaling_test = true)
|
|
{
|
|
for (int recompress = 0; recompress < 2; ++recompress) {
|
|
run_test (_this, file, scaling_test, 0, recompress, false);
|
|
run_test (_this, file, scaling_test, 1, recompress, false);
|
|
run_test (_this, file, scaling_test, 2, recompress, false);
|
|
run_test (_this, file, scaling_test, 10, recompress, false);
|
|
}
|
|
|
|
// tables at end
|
|
run_test (_this, file, scaling_test, 2, false, true);
|
|
}
|
|
|
|
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 (false);
|
|
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 = tl::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter100.gds"));
|
|
|
|
{
|
|
tl::OutputStream out (tmp_file);
|
|
db::SaveLayoutOptions options;
|
|
options.set_option_by_name ("oasis_strict_mode", false);
|
|
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 {$4}\n"
|
|
"end_cell\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"
|
|
"sref {$4} 90 1 1 {-10 20}\n"
|
|
"end_cell\n"
|
|
"begin_cell {$2}\n"
|
|
"sref {$1} 90 1 1 {-10 20}\n"
|
|
"sref {$3} 90 1 1 {-10 20}\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(101)
|
|
{
|
|
db::Manager m (false);
|
|
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 = tl::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 (false);
|
|
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 = tl::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"
|
|
"sref {$3} 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(103)
|
|
{
|
|
db::Manager m (false);
|
|
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 = tl::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 (false);
|
|
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 = tl::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 (false);
|
|
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 = tl::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 (false);
|
|
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 = tl::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 (false);
|
|
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 = tl::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 (false);
|
|
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 = tl::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 100} {0 1200}\n"
|
|
"path 1 0 0 0 0 {0 100} {1000 1200}\n"
|
|
"path 1 0 0 0 0 {0 1200} {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))
|
|
}
|
|
|
|
TEST(115)
|
|
{
|
|
db::Manager m (false);
|
|
db::Layout g (&m);
|
|
|
|
db::property_names_id_type n1, n2, n3;
|
|
n1 = db::property_names_id (tl::Variant (17));
|
|
n2 = db::property_names_id (tl::Variant ("name"));
|
|
n3 = db::property_names_id (tl::Variant ((unsigned int) 42));
|
|
|
|
db::PropertiesSet s1;
|
|
s1.insert (n1, tl::Variant ("17value"));
|
|
s1.insert (n2, tl::Variant (117));
|
|
|
|
db::PropertiesSet s2;
|
|
s2.insert (n3, tl::Variant (42));
|
|
|
|
db::properties_id_type p1 = db::properties_id (s1);
|
|
db::properties_id_type p2 = db::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 = tl::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter115.gds"));
|
|
|
|
{
|
|
tl::OutputStream out (tmp_file);
|
|
db::SaveLayoutOptions options;
|
|
options.set_option_by_name ("oasis_strict_mode", false);
|
|
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 100} {0 1200}\n"
|
|
"path 1 0 0 0 0 {0 100} {1000 1200}\n"
|
|
"path 1 0 0 0 0 {0 1200} {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))
|
|
}
|
|
|
|
TEST(116)
|
|
{
|
|
db::Manager m (false);
|
|
db::Layout g (&m);
|
|
|
|
db::property_names_id_type n1, n2, n3;
|
|
n1 = db::property_names_id (tl::Variant (17));
|
|
n2 = db::property_names_id (tl::Variant ("name"));
|
|
n3 = db::property_names_id (tl::Variant ((unsigned int) 42));
|
|
|
|
db::PropertiesSet s1;
|
|
s1.insert (n1, tl::Variant ("17value"));
|
|
s1.insert (n2, tl::Variant (117));
|
|
|
|
db::PropertiesSet s2;
|
|
s2.insert (n3, tl::Variant (42));
|
|
|
|
db::properties_id_type p1 = db::properties_id (s1);
|
|
db::properties_id_type p2 = db::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 = tl::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter116a.gds"));
|
|
|
|
{
|
|
tl::OutputStream out (tmp_file);
|
|
db::SaveLayoutOptions write_options;
|
|
write_options.set_option_by_name ("oasis_strict_mode", false);
|
|
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"
|
|
" {17 {17value}}\n"
|
|
#if defined(HAVE_64BIT_COORD)
|
|
" {{S_MAX_SIGNED_INTEGER_WIDTH} {8}}\n"
|
|
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {8}}\n"
|
|
#else
|
|
" {{S_MAX_SIGNED_INTEGER_WIDTH} {4}}\n"
|
|
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {4}}\n"
|
|
#endif
|
|
" {{S_TOP_CELL} {$2}}\n"
|
|
" {{S_TOP_CELL} {$1}}\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"
|
|
"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 = tl::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;
|
|
oas_write_options.strict_mode = false;
|
|
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"
|
|
"begin_cell {$2}\n"
|
|
"end_cell\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"
|
|
"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 = tl::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;
|
|
oas_write_options.strict_mode = false;
|
|
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"
|
|
" {{S_BOUNDING_BOXES_AVAILABLE} {2}}\n"
|
|
#if defined(HAVE_64BIT_COORD)
|
|
" {{S_MAX_SIGNED_INTEGER_WIDTH} {8}}\n"
|
|
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {8}}\n"
|
|
#else
|
|
" {{S_MAX_SIGNED_INTEGER_WIDTH} {4}}\n"
|
|
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {4}}\n"
|
|
#endif
|
|
" {{S_TOP_CELL} {$2}}\n"
|
|
" {{S_TOP_CELL} {$1}}\n"
|
|
" {{name} {117}}\n"
|
|
"}\n"
|
|
"begin_libp $props 0.001\n"
|
|
"set props {\n"
|
|
" {{S_BOUNDING_BOX} {(2,0,0,0,0)}}\n"
|
|
"}\n"
|
|
"begin_cellp $props {$2}\n"
|
|
"end_cell\n"
|
|
"set props {\n"
|
|
" {42 {42}}\n"
|
|
" {{S_BOUNDING_BOX} {(0,0,100,1000,1100)}}\n"
|
|
"}\n"
|
|
"begin_cellp $props {$1}\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 = tl::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;
|
|
oas_write_options.write_cblocks = false;
|
|
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"
|
|
" {17 {17value}}\n"
|
|
" {{S_BOUNDING_BOXES_AVAILABLE} {2}}\n"
|
|
#if defined(HAVE_64BIT_COORD)
|
|
" {{S_MAX_SIGNED_INTEGER_WIDTH} {8}}\n"
|
|
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {8}}\n"
|
|
#else
|
|
" {{S_MAX_SIGNED_INTEGER_WIDTH} {4}}\n"
|
|
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {4}}\n"
|
|
#endif
|
|
" {{S_TOP_CELL} {$2}}\n"
|
|
" {{S_TOP_CELL} {$1}}\n"
|
|
" {{name} {117}}\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))
|
|
}
|
|
|
|
{
|
|
std::string tmp_file = tl::TestBase::tmp_file ("tmp_dbOASISWriter116d2.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 = 1;
|
|
oas_write_options.strict_mode = true;
|
|
oas_write_options.write_cblocks = false;
|
|
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"
|
|
" {17 {17value}}\n"
|
|
#if defined(HAVE_64BIT_COORD)
|
|
" {{S_MAX_SIGNED_INTEGER_WIDTH} {8}}\n"
|
|
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {8}}\n"
|
|
#else
|
|
" {{S_MAX_SIGNED_INTEGER_WIDTH} {4}}\n"
|
|
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {4}}\n"
|
|
#endif
|
|
" {{S_TOP_CELL} {$2}}\n"
|
|
" {{S_TOP_CELL} {$1}}\n"
|
|
" {{name} {117}}\n"
|
|
"}\n"
|
|
"begin_libp $props 0.001\n"
|
|
"set props {\n"
|
|
" {42 {42}}\n"
|
|
" {{S_CELL_OFFSET} {182}}\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_CELL_OFFSET} {180}}\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 = tl::TestBase::tmp_file ("tmp_dbOASISWriter116e.gds");
|
|
|
|
{
|
|
tl::OutputStream out (tmp_file);
|
|
db::SaveLayoutOptions write_options;
|
|
write_options.set_format ("OASIS");
|
|
write_options.set_option_by_name ("oasis_strict_mode", false);
|
|
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"
|
|
" {17 {17value}}\n"
|
|
#if defined(HAVE_64BIT_COORD)
|
|
" {{S_MAX_SIGNED_INTEGER_WIDTH} {8}}\n"
|
|
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {8}}\n"
|
|
#else
|
|
" {{S_MAX_SIGNED_INTEGER_WIDTH} {4}}\n"
|
|
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {4}}\n"
|
|
#endif
|
|
" {{S_TOP_CELL} {$1}}\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 = tl::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");
|
|
write_options.set_option_by_name ("oasis_strict_mode", false);
|
|
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"
|
|
" {17 {17value}}\n"
|
|
#if defined(HAVE_64BIT_COORD)
|
|
" {{S_MAX_SIGNED_INTEGER_WIDTH} {8}}\n"
|
|
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {8}}\n"
|
|
#else
|
|
" {{S_MAX_SIGNED_INTEGER_WIDTH} {4}}\n"
|
|
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {4}}\n"
|
|
#endif
|
|
" {{S_TOP_CELL} {$2}}\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 (false);
|
|
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 = tl::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))
|
|
}
|
|
|
|
TEST(118)
|
|
{
|
|
// 1x1 arrays (#902)
|
|
|
|
db::Manager m (false);
|
|
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 = tl::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 {0 0}\n"
|
|
"sref {$1} 0 0 1 {17 -42}\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(119_WithAndWithoutContext)
|
|
{
|
|
// PCells with context and without
|
|
|
|
db::Manager m (false);
|
|
db::Layout g (&m);
|
|
|
|
// Note: this sample requires the BASIC lib
|
|
|
|
{
|
|
std::string fn (tl::testdata ());
|
|
fn += "/oasis/pcell_test.gds";
|
|
tl::InputStream stream (fn);
|
|
db::Reader reader (stream);
|
|
reader.read (g);
|
|
}
|
|
|
|
std::string tmp_file = tl::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter119a.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);
|
|
|
|
std::pair<bool, db::cell_index_type> tc = gg.cell_by_name ("TEXT");
|
|
tl_assert (tc.first);
|
|
|
|
const db::Cell &text_cell = gg.cell (tc.second);
|
|
EXPECT_EQ (text_cell.is_proxy (), true);
|
|
EXPECT_EQ (text_cell.get_display_name (), "Basic.TEXT(l=1/0,'KLAYOUT RULES')");
|
|
|
|
CHECKPOINT ();
|
|
db::compare_layouts (_this, gg, tl::testdata () + "/oasis/dbOASISWriter119_au.gds", db::NoNormalization);
|
|
}
|
|
|
|
tmp_file = tl::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter119b.oas"));
|
|
|
|
{
|
|
tl::OutputStream out (tmp_file);
|
|
db::SaveLayoutOptions options;
|
|
options.set_write_context_info (false);
|
|
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);
|
|
|
|
std::pair<bool, db::cell_index_type> tc = gg.cell_by_name ("TEXT");
|
|
tl_assert (tc.first);
|
|
|
|
const db::Cell &text_cell = gg.cell (tc.second);
|
|
EXPECT_EQ (text_cell.is_proxy (), false);
|
|
EXPECT_EQ (text_cell.get_display_name (), "TEXT");
|
|
|
|
CHECKPOINT ();
|
|
db::compare_layouts (_this, gg, tl::testdata () + "/oasis/dbOASISWriter119_au.gds", db::NoNormalization);
|
|
}
|
|
|
|
}
|
|
|
|
TEST(120_IrregularInstRepetitions)
|
|
{
|
|
db::Manager m (false);
|
|
db::Layout g (&m);
|
|
|
|
db::cell_index_type top = g.add_cell ("TOP");
|
|
db::cell_index_type c1 = g.add_cell ("C1");
|
|
|
|
db::Vector pts[3] = { db::Vector (0, 10), db::Vector (0, 20), db::Vector (0, 30) };
|
|
|
|
unsigned int l1 = g.insert_layer (db::LayerProperties (1, 0));
|
|
g.cell (c1).shapes (l1).insert (db::Box (-5, -5, 5, 5));
|
|
db::iterated_array<db::Coord> *reps = new db::iterated_array<db::Coord> (pts + 0, pts + 3);
|
|
g.cell (top).shapes (l1).insert (db::array<db::Box, db::UnitTrans> (db::Box (-5, -5, 5, 5), db::UnitTrans (), reps));
|
|
|
|
db::iterated_array<db::Coord> *rep = new db::iterated_array<db::Coord> (pts + 0, pts + 3);
|
|
db::CellInstArray ci1 (db::CellInst (c1), db::Trans (db::Vector (10, 0)), rep);
|
|
g.cell (top).insert (ci1);
|
|
|
|
std::string tmp_file = tl::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter120.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);
|
|
|
|
CHECKPOINT ();
|
|
db::compare_layouts (_this, gg, tl::testdata () + "/oasis/dbOASISWriter120_au.gds", db::NoNormalization);
|
|
}
|
|
|
|
}
|
|
|
|
// Meta info
|
|
static void
|
|
run_test130 (tl::TestBase *_this, bool strict, bool tables_at_end)
|
|
{
|
|
db::Layout layout_org;
|
|
|
|
layout_org.add_cell ("U");
|
|
db::cell_index_type ci = layout_org.add_cell ("X");
|
|
|
|
layout_org.add_meta_info ("a", db::MetaInfo ("description", 17.5, true));
|
|
layout_org.add_meta_info ("b", db::MetaInfo ("", "value", true));
|
|
|
|
layout_org.add_meta_info (ci, "a", db::MetaInfo ("dd", true, true));
|
|
layout_org.add_meta_info (ci, "c", db::MetaInfo ("d", -1, true));
|
|
|
|
std::string tmp_file = _this->tmp_file ("tmp_OASISWriter1.oas");
|
|
|
|
{
|
|
tl::OutputStream out (tmp_file);
|
|
db::OASISWriterOptions oasis_options;
|
|
oasis_options.strict_mode = strict;
|
|
oasis_options.tables_at_end = tables_at_end;
|
|
db::SaveLayoutOptions options;
|
|
options.set_format ("OASIS");
|
|
options.set_options (oasis_options);
|
|
db::Writer writer (options);
|
|
writer.write (layout_org, out);
|
|
}
|
|
|
|
db::Layout layout_read;
|
|
|
|
{
|
|
tl::InputStream in (tmp_file);
|
|
db::Reader reader (in);
|
|
reader.read (layout_read);
|
|
}
|
|
|
|
EXPECT_EQ (layout_read.meta_info ("x").value.to_string (), "nil");
|
|
EXPECT_EQ (layout_read.meta_info ("a").value.to_string (), "17.5");
|
|
EXPECT_EQ (layout_read.meta_info ("a").description, "description");
|
|
EXPECT_EQ (layout_read.meta_info ("b").value.to_string (), "value");
|
|
EXPECT_EQ (layout_read.meta_info ("b").description, "");
|
|
|
|
db::cell_index_type ci2 = layout_read.cell_by_name ("X").second;
|
|
|
|
EXPECT_EQ (layout_read.meta_info (ci2, "x").value.to_string (), "nil");
|
|
EXPECT_EQ (layout_read.meta_info (ci2, "a").value.to_string (), "true");
|
|
EXPECT_EQ (layout_read.meta_info (ci2, "a").description, "dd");
|
|
EXPECT_EQ (layout_read.meta_info (ci2, "c").value.to_string (), "-1");
|
|
EXPECT_EQ (layout_read.meta_info (ci2, "c").description, "d");
|
|
|
|
tmp_file = _this->tmp_file ("tmp_OASISWriter2.oas");
|
|
|
|
{
|
|
tl::OutputStream out (tmp_file);
|
|
db::OASISWriterOptions oasis_options;
|
|
oasis_options.strict_mode = strict;
|
|
oasis_options.tables_at_end = tables_at_end;
|
|
db::SaveLayoutOptions options;
|
|
options.set_format ("OASIS");
|
|
options.set_options (oasis_options);
|
|
options.set_write_context_info (false);
|
|
db::Writer writer (options);
|
|
writer.write (layout_org, out);
|
|
}
|
|
|
|
layout_read = db::Layout ();
|
|
|
|
{
|
|
tl::InputStream in (tmp_file);
|
|
db::Reader reader (in);
|
|
reader.read (layout_read);
|
|
}
|
|
|
|
EXPECT_EQ (layout_read.meta_info ("x").value.to_string (), "nil");
|
|
EXPECT_EQ (layout_read.meta_info ("a").value.to_string (), "nil");
|
|
EXPECT_EQ (layout_read.meta_info ("b").value.to_string (), "nil");
|
|
|
|
ci2 = layout_read.cell_by_name ("X").second;
|
|
|
|
EXPECT_EQ (layout_read.meta_info (ci2, "x").value.to_string (), "nil");
|
|
EXPECT_EQ (layout_read.meta_info ("a").value.to_string (), "nil");
|
|
EXPECT_EQ (layout_read.meta_info ("b").value.to_string (), "nil");
|
|
}
|
|
|
|
// Meta info
|
|
|
|
TEST(130a)
|
|
{
|
|
run_test130 (_this, false, false);
|
|
}
|
|
|
|
TEST(130b)
|
|
{
|
|
run_test130 (_this, true, false);
|
|
}
|
|
|
|
TEST(130c)
|
|
{
|
|
run_test130 (_this, false, true);
|
|
}
|
|
|
|
TEST(130d)
|
|
{
|
|
run_test130 (_this, true, true);
|
|
}
|
|
|
|
// Issue #2088 (name duplication)
|
|
TEST(140)
|
|
{
|
|
db::Layout layout_org;
|
|
|
|
layout_org.add_cell ("X X");
|
|
layout_org.add_cell ("X*X");
|
|
|
|
std::string tmp_file = tl::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter140.oas"));
|
|
|
|
{
|
|
tl::OutputStream out (tmp_file);
|
|
db::SaveLayoutOptions options;
|
|
options.set_format ("OASIS");
|
|
db::Writer writer (options);
|
|
writer.write (layout_org, out);
|
|
}
|
|
|
|
{
|
|
tl::InputStream in (tmp_file);
|
|
db::Reader reader (in);
|
|
db::Layout gg;
|
|
reader.set_warnings_as_errors (true);
|
|
reader.read (gg);
|
|
|
|
db::compare_layouts (_this, gg, tl::testdata () + "/oasis/dbOASISWriter40_au.gds", db::NoNormalization);
|
|
}
|
|
}
|