mirror of https://github.com/KLayout/klayout.git
1470 lines
50 KiB
C++
1470 lines
50 KiB
C++
|
|
/*
|
|
|
|
KLayout Layout Viewer
|
|
Copyright (C) 2006-2017 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 "utHead.h"
|
|
#include "dbLayoutDiff.h"
|
|
#include "dbLayerProperties.h"
|
|
#include "dbLayout.h"
|
|
|
|
#include <sstream>
|
|
|
|
class TestDifferenceReceiver
|
|
: public db::DifferenceReceiver
|
|
{
|
|
public:
|
|
TestDifferenceReceiver ();
|
|
virtual ~TestDifferenceReceiver () { }
|
|
|
|
std::string text () const { return m_os.str (); }
|
|
void clear () { m_os.str (std::string ()); }
|
|
void dbu_differs (double dbu_a, double dbu_b);
|
|
void layer_in_a_only (const db::LayerProperties &la);
|
|
void layer_in_b_only (const db::LayerProperties &lb);
|
|
void layer_name_differs (const db::LayerProperties &la, const db::LayerProperties &lb);
|
|
void cell_in_a_only (const std::string &cellname, db::cell_index_type ci);
|
|
void cell_in_b_only (const std::string &cellname, db::cell_index_type ci);
|
|
void cell_name_differs (const std::string &cellname_a, db::cell_index_type cia, const std::string &cellname_b, db::cell_index_type cib);
|
|
void begin_cell (const std::string &cellname, db::cell_index_type cia, db::cell_index_type cib);
|
|
void bbox_differs (const db::Box &ba, const db::Box &bb);
|
|
void begin_inst_differences ();
|
|
void instances_in_a (const std::vector <db::CellInstArrayWithProperties> &insts_a, const std::vector <std::string> &cell_names, const db::PropertiesRepository &props);
|
|
void instances_in_b (const std::vector <db::CellInstArrayWithProperties> &insts_b, const std::vector <std::string> &cell_names, const db::PropertiesRepository &props);
|
|
void instances_in_a_only (const std::vector <db::CellInstArrayWithProperties> &anotb, const db::Layout &a);
|
|
void instances_in_b_only (const std::vector <db::CellInstArrayWithProperties> &bnota, const db::Layout &b);
|
|
void end_inst_differences ();
|
|
void begin_layer (const db::LayerProperties &layer, unsigned int layer_index_a, bool is_valid_a, unsigned int layer_index_b, bool is_valid_b);
|
|
void per_layer_bbox_differs (const db::Box &ba, const db::Box &bb);
|
|
void begin_polygon_differences ();
|
|
void detailed_diff (const db::PropertiesRepository &pr, const std::vector <std::pair <db::Polygon, db::properties_id_type> > &a, const std::vector <std::pair <db::Polygon, db::properties_id_type> > &b);
|
|
void end_polygon_differences ();
|
|
void begin_path_differences ();
|
|
void detailed_diff (const db::PropertiesRepository &pr, const std::vector <std::pair <db::Path, db::properties_id_type> > &a, const std::vector <std::pair <db::Path, db::properties_id_type> > &b);
|
|
void end_path_differences ();
|
|
void begin_box_differences ();
|
|
void detailed_diff (const db::PropertiesRepository &pr, const std::vector <std::pair <db::Box, db::properties_id_type> > &a, const std::vector <std::pair <db::Box, db::properties_id_type> > &b);
|
|
void end_box_differences ();
|
|
void begin_edge_differences ();
|
|
void detailed_diff (const db::PropertiesRepository &pr, const std::vector <std::pair <db::Edge, db::properties_id_type> > &a, const std::vector <std::pair <db::Edge, db::properties_id_type> > &b);
|
|
void end_edge_differences ();
|
|
void begin_text_differences ();
|
|
void detailed_diff (const db::PropertiesRepository &pr, const std::vector <std::pair <db::Text, db::properties_id_type> > &a, const std::vector <std::pair <db::Text, db::properties_id_type> > &b);
|
|
void end_text_differences ();
|
|
void end_layer ();
|
|
void end_cell ();
|
|
|
|
private:
|
|
std::string m_cellname;
|
|
std::ostringstream m_os;
|
|
db::LayerProperties m_layer;
|
|
|
|
void print_cell_inst (const db::CellInstArrayWithProperties &ci, const std::vector <std::string> &cell_names);
|
|
void print_cell_inst (const db::CellInstArrayWithProperties &ci, const db::Layout &l);
|
|
template <class SH> void print_diffs (const db::PropertiesRepository &pr, const std::vector <std::pair <SH, db::properties_id_type> > &a, const std::vector <std::pair <SH, db::properties_id_type> > &b);
|
|
};
|
|
|
|
TestDifferenceReceiver::TestDifferenceReceiver ()
|
|
: m_cellname (), m_layer ()
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::print_cell_inst (const db::CellInstArrayWithProperties &ci, const db::Layout &l)
|
|
{
|
|
m_os << " " << l.cell_name (ci.object ().cell_index ()) << " " << ci.complex_trans ().to_string ();
|
|
|
|
db::Vector a, b;
|
|
unsigned long amax, bmax;
|
|
if (ci.is_regular_array (a, b, amax, bmax)) {
|
|
m_os << "[a=" << a.to_string () << ", b=" << b.to_string () << ", na=" << amax << ", nb=" << bmax << "]";
|
|
}
|
|
if (ci.properties_id () != 0) {
|
|
m_os << " [" << ci.properties_id () << "]" << std::endl;
|
|
}
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::print_cell_inst (const db::CellInstArrayWithProperties &ci, const std::vector <std::string> &cell_names)
|
|
{
|
|
m_os << " " << cell_names [ci.object ().cell_index ()] << " " << ci.complex_trans ().to_string ();
|
|
|
|
db::Vector a, b;
|
|
unsigned long amax, bmax;
|
|
if (ci.is_regular_array (a, b, amax, bmax)) {
|
|
m_os << "[a=" << a.to_string () << ", b=" << b.to_string () << ", na=" << amax << ", nb=" << bmax << "]";
|
|
}
|
|
if (ci.properties_id () != 0) {
|
|
m_os << " [" << ci.properties_id () << "]" << std::endl;
|
|
} else {
|
|
m_os << "" << std::endl;
|
|
}
|
|
}
|
|
|
|
template <class SH>
|
|
void
|
|
TestDifferenceReceiver::print_diffs (const db::PropertiesRepository & /*pr*/, const std::vector <std::pair <SH, db::properties_id_type> > &a, const std::vector <std::pair <SH, db::properties_id_type> > &b)
|
|
{
|
|
std::vector <std::pair <SH, db::properties_id_type> > anotb;
|
|
std::set_difference (a.begin (), a.end (), b.begin (), b.end (), std::back_inserter (anotb));
|
|
for (typename std::vector <std::pair <SH, db::properties_id_type> >::const_iterator s = anotb.begin (); s != anotb.end (); ++s) {
|
|
m_os << " " << s->first.to_string ();
|
|
if (s->second != 0) {
|
|
m_os << " [" << s->second << "]" << std::endl;
|
|
} else {
|
|
m_os << "" << std::endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::dbu_differs (double dbu_a, double dbu_b)
|
|
{
|
|
m_os << "layout_diff: database units differ " << dbu_a << " vs. " << dbu_b << std::endl;
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::layer_in_a_only (const db::LayerProperties &la)
|
|
{
|
|
m_os << "layout_diff: layer " << la.to_string () << " is not present in layout b, but in a" << std::endl;
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::layer_in_b_only (const db::LayerProperties &lb)
|
|
{
|
|
m_os << "layout_diff: layer " << lb.to_string () << " is not present in layout a, but in b" << std::endl;
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::layer_name_differs (const db::LayerProperties &la, const db::LayerProperties &lb)
|
|
{
|
|
m_os << "layout_diff: layer names differ between layout a and b for layer " << la.layer << "/" << la.datatype << ": "
|
|
<< la.name << " vs. " << lb.name << std::endl;
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::cell_in_a_only (const std::string &cellname, db::cell_index_type /*ci*/)
|
|
{
|
|
m_os << "layout_diff: cell " << cellname << " is not present in layout b, but in a" << std::endl;
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::cell_in_b_only (const std::string &cellname, db::cell_index_type /*ci*/)
|
|
{
|
|
m_os << "layout_diff: cell " << cellname << " is not present in layout a, but in b" << std::endl;
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::cell_name_differs (const std::string &cellname_a, db::cell_index_type /*cia*/, const std::string &cellname_b, db::cell_index_type /*cib*/)
|
|
{
|
|
m_os << "layout_diff: cell " << cellname_a << " in a is renamed to " << cellname_b << " in b" << std::endl;
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::bbox_differs (const db::Box &ba, const db::Box &bb)
|
|
{
|
|
m_os << "layout_diff: bounding boxes differ for cell " << m_cellname << ", " << ba.to_string () << " vs. " << bb.to_string () << std::endl;
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::begin_cell (const std::string &cellname, db::cell_index_type /*cia*/, db::cell_index_type /*cib*/)
|
|
{
|
|
m_cellname = cellname;
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::begin_inst_differences ()
|
|
{
|
|
m_os << "layout_diff: instances differ in cell " << m_cellname << std::endl;
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::instances_in_a (const std::vector <db::CellInstArrayWithProperties> &insts_a, const std::vector <std::string> &cell_names, const db::PropertiesRepository & /*props*/)
|
|
{
|
|
m_os << "list for a:" << std::endl;
|
|
for (std::vector <db::CellInstArrayWithProperties>::const_iterator s = insts_a.begin (); s != insts_a.end (); ++s) {
|
|
print_cell_inst (*s, cell_names);
|
|
}
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::instances_in_b (const std::vector <db::CellInstArrayWithProperties> &insts_b, const std::vector <std::string> &cell_names, const db::PropertiesRepository & /*props*/)
|
|
{
|
|
m_os << "list for b:" << std::endl;
|
|
for (std::vector <db::CellInstArrayWithProperties>::const_iterator s = insts_b.begin (); s != insts_b.end (); ++s) {
|
|
print_cell_inst (*s, cell_names);
|
|
}
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::instances_in_a_only (const std::vector <db::CellInstArrayWithProperties> &anotb, const db::Layout &a)
|
|
{
|
|
m_os << "Not in b but in a:" << std::endl;
|
|
for (std::vector <db::CellInstArrayWithProperties>::const_iterator s = anotb.begin (); s != anotb.end (); ++s) {
|
|
print_cell_inst (*s, a);
|
|
}
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::instances_in_b_only (const std::vector <db::CellInstArrayWithProperties> &bnota, const db::Layout &b)
|
|
{
|
|
m_os << "Not in a but in b:" << std::endl;
|
|
for (std::vector <db::CellInstArrayWithProperties>::const_iterator s = bnota.begin (); s != bnota.end (); ++s) {
|
|
print_cell_inst (*s, b);
|
|
}
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::end_inst_differences ()
|
|
{
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::begin_layer (const db::LayerProperties &layer, unsigned int /*layer_index_a*/, bool /*is_valid_a*/, unsigned int /*layer_index_b*/, bool /*is_valid_b*/)
|
|
{
|
|
m_layer = layer;
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::per_layer_bbox_differs (const db::Box &ba, const db::Box &bb)
|
|
{
|
|
m_os << "layout_diff: per-layer bounding boxes differ for cell " << m_cellname << ", layer (" << m_layer.to_string () << "), "
|
|
<< ba.to_string () << " vs. " << bb.to_string () << std::endl;
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::begin_polygon_differences ()
|
|
{
|
|
m_os << "layout_diff: polygons differ for layer " << m_layer.to_string () << " in cell " << m_cellname << std::endl;
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::detailed_diff (const db::PropertiesRepository &pr, const std::vector <std::pair <db::Polygon, db::properties_id_type> > &a, const std::vector <std::pair <db::Polygon, db::properties_id_type> > &b)
|
|
{
|
|
m_os << "Not in b but in a:" << std::endl;
|
|
print_diffs (pr, a, b);
|
|
m_os << "Not in a but in b:" << std::endl;
|
|
print_diffs (pr, b, a);
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::end_polygon_differences ()
|
|
{
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::begin_path_differences ()
|
|
{
|
|
m_os << "layout_diff: paths differ for layer " << m_layer.to_string () << " in cell " << m_cellname << std::endl;
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::detailed_diff (const db::PropertiesRepository &pr, const std::vector <std::pair <db::Path, db::properties_id_type> > &a, const std::vector <std::pair <db::Path, db::properties_id_type> > &b)
|
|
{
|
|
m_os << "Not in b but in a:" << std::endl;
|
|
print_diffs (pr, a, b);
|
|
m_os << "Not in a but in b:" << std::endl;
|
|
print_diffs (pr, b, a);
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::end_path_differences ()
|
|
{
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::begin_box_differences ()
|
|
{
|
|
m_os << "layout_diff: boxes differ for layer " << m_layer.to_string () << " in cell " << m_cellname << std::endl;
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::detailed_diff (const db::PropertiesRepository &pr, const std::vector <std::pair <db::Box, db::properties_id_type> > &a, const std::vector <std::pair <db::Box, db::properties_id_type> > &b)
|
|
{
|
|
m_os << "Not in b but in a:" << std::endl;
|
|
print_diffs (pr, a, b);
|
|
m_os << "Not in a but in b:" << std::endl;
|
|
print_diffs (pr, b, a);
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::end_box_differences ()
|
|
{
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::begin_edge_differences ()
|
|
{
|
|
m_os << "layout_diff: edges differ for layer " << m_layer.to_string () << " in cell " << m_cellname << std::endl;
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::detailed_diff (const db::PropertiesRepository &pr, const std::vector <std::pair <db::Edge, db::properties_id_type> > &a, const std::vector <std::pair <db::Edge, db::properties_id_type> > &b)
|
|
{
|
|
m_os << "Not in b but in a:" << std::endl;
|
|
print_diffs (pr, a, b);
|
|
m_os << "Not in a but in b:" << std::endl;
|
|
print_diffs (pr, b, a);
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::end_edge_differences ()
|
|
{
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::begin_text_differences ()
|
|
{
|
|
m_os << "layout_diff: texts differ for layer " << m_layer.to_string () << " in cell " << m_cellname << std::endl;
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::detailed_diff (const db::PropertiesRepository &pr, const std::vector <std::pair <db::Text, db::properties_id_type> > &a, const std::vector <std::pair <db::Text, db::properties_id_type> > &b)
|
|
{
|
|
m_os << "Not in b but in a:" << std::endl;
|
|
print_diffs (pr, a, b);
|
|
m_os << "Not in a but in b:" << std::endl;
|
|
print_diffs (pr, b, a);
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::end_text_differences ()
|
|
{
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::end_layer ()
|
|
{
|
|
}
|
|
|
|
void
|
|
TestDifferenceReceiver::end_cell ()
|
|
{
|
|
}
|
|
|
|
TEST(1)
|
|
{
|
|
db::Layout g;
|
|
g.insert_layer (0);
|
|
g.set_properties (0, db::LayerProperties (17, 0));
|
|
g.insert_layer (1);
|
|
g.set_properties (1, db::LayerProperties (42, 1));
|
|
|
|
db::cell_index_type c1i = g.add_cell ("c1");
|
|
db::cell_index_type c2i = g.add_cell ("c2x");
|
|
db::cell_index_type c3i = g.add_cell ("c3");
|
|
db::cell_index_type c4i = g.add_cell ("c4");
|
|
db::cell_index_type c5i = g.add_cell ("c5x");
|
|
|
|
{
|
|
|
|
db::Cell &c1 (g.cell (c1i));
|
|
db::Cell &c2 (g.cell (c2i));
|
|
db::Cell &c3 (g.cell (c3i));
|
|
db::Cell &c4 (g.cell (c4i));
|
|
db::Cell &c5 (g.cell (c5i));
|
|
c2.shapes (0).insert (db::Box (0, 1, 2, 3));
|
|
|
|
db::FTrans f (1, true);
|
|
db::Vector p (-10, 20);
|
|
db::Trans t (f.rot (), p);
|
|
db::Vector pp (10, -20);
|
|
db::Trans tt (0, pp);
|
|
|
|
// c4->c1 (aref)
|
|
c4.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t, db::Vector(1, 1), db::Vector (0, 2), 2, 3));
|
|
// c5->c1
|
|
c5.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
// c3->c5 (3x)
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5.cell_index ()), t));
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5.cell_index ()), tt));
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5.cell_index ()), t));
|
|
// c4->c3
|
|
c4.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c3.cell_index ()), t));
|
|
// c4->c1
|
|
c4.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), tt));
|
|
// c2->c1 (2x)
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), tt));
|
|
// c2->c4 (2x)
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
|
|
|
|
}
|
|
|
|
db::Layout h = g;
|
|
|
|
TestDifferenceReceiver r;
|
|
bool eq;
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, 0, 0, r);
|
|
|
|
EXPECT_EQ (eq, true);
|
|
EXPECT_EQ (r.text (), "");
|
|
|
|
{
|
|
// c2->c5 (2x)
|
|
db::FTrans f (1, true);
|
|
db::Vector p (-10, 20);
|
|
db::Trans t (f.rot (), p);
|
|
db::Vector pp (10, -20);
|
|
db::Trans tt (0, pp);
|
|
g.cell (c2i).insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5i), t));
|
|
g.cell (c2i).insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5i), tt));
|
|
}
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, 0, 0, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (), "layout_diff: instances differ in cell c2x\n");
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, db::layout_diff::f_verbose, 0, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: instances differ in cell c2x\n"
|
|
"list for a:\n"
|
|
" c1 r0 *1 10,-20\n"
|
|
" c1 m45 *1 -10,20\n"
|
|
" c4 m45 *1 -10,20\n"
|
|
" c4 m45 *1 -10,20\n"
|
|
" c5x r0 *1 10,-20\n"
|
|
" c5x m45 *1 -10,20\n"
|
|
"list for b:\n"
|
|
" c1 r0 *1 10,-20\n"
|
|
" c1 m45 *1 -10,20\n"
|
|
" c4 m45 *1 -10,20\n"
|
|
" c4 m45 *1 -10,20\n"
|
|
"Not in b but in a:\n"
|
|
" c5x r0 *1 10,-20 c5x m45 *1 -10,20Not in a but in b:\n"
|
|
);
|
|
|
|
g = h;
|
|
g.set_properties (1, db::LayerProperties (42, 2));
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, 0, 0, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: layer 42/2 is not present in layout b, but in a\n"
|
|
"layout_diff: layer 42/1 is not present in layout a, but in b\n"
|
|
);
|
|
|
|
g = h;
|
|
g.rename_cell (c2i, "c2");
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, 0, 0, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: cell c2 is not present in layout b, but in a\n"
|
|
"layout_diff: cell c2x is not present in layout a, but in b\n"
|
|
);
|
|
}
|
|
|
|
TEST(2)
|
|
{
|
|
db::Layout g;
|
|
g.insert_layer (0);
|
|
g.set_properties (0, db::LayerProperties (17, 0));
|
|
g.insert_layer (1);
|
|
g.set_properties (1, db::LayerProperties (42, 1));
|
|
|
|
db::cell_index_type c1i = g.add_cell ("c1");
|
|
db::cell_index_type c2i = g.add_cell ("c2x");
|
|
db::cell_index_type c3i = g.add_cell ("c3");
|
|
db::cell_index_type c4i = g.add_cell ("c4");
|
|
db::cell_index_type c5i = g.add_cell ("c5x");
|
|
|
|
{
|
|
|
|
db::Cell &c1 (g.cell (c1i));
|
|
db::Cell &c2 (g.cell (c2i));
|
|
db::Cell &c3 (g.cell (c3i));
|
|
db::Cell &c4 (g.cell (c4i));
|
|
db::Cell &c5 (g.cell (c5i));
|
|
c2.shapes (0).insert (db::Box (0, 1, 2, 3));
|
|
|
|
db::FTrans f (1, true);
|
|
db::Vector p (-10, 20);
|
|
db::Trans t (f.rot (), p);
|
|
db::Vector pp (10, -20);
|
|
db::Trans tt (0, pp);
|
|
|
|
// c4->c1 (aref)
|
|
c4.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t, db::Vector(1, 1), db::Vector (0, 2), 2, 3));
|
|
// c5->c1
|
|
c5.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
// c3->c5 (3x)
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5.cell_index ()), t));
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5.cell_index ()), tt));
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5.cell_index ()), t));
|
|
// c4->c3
|
|
c4.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c3.cell_index ()), t));
|
|
// c4->c1
|
|
c4.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), tt));
|
|
// c2->c1 (2x)
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), tt));
|
|
// c2->c4 (2x)
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
|
|
|
|
}
|
|
|
|
db::Layout h = g;
|
|
|
|
TestDifferenceReceiver r;
|
|
bool eq;
|
|
|
|
g.cell (c2i).shapes (0).insert (db::Box (1, 2, 1003, 1004));
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, 0, 0, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: bounding boxes differ for cell c2x, (0,1;1003,1004) vs. (0,1;2,3)\n"
|
|
"layout_diff: per-layer bounding boxes differ for cell c2x, layer (17/0), (0,1;1003,1004) vs. (0,1;2,3)\n"
|
|
"layout_diff: boxes differ for layer 17/0 in cell c2x\n"
|
|
);
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, db::layout_diff::f_verbose, 0, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: boxes differ for layer 17/0 in cell c2x\n"
|
|
"Not in b but in a:\n"
|
|
" (1,2;1003,1004)\n"
|
|
"Not in a but in b:\n"
|
|
);
|
|
|
|
db::Layout hh = h;
|
|
|
|
db::Cell &c2h = h.cell (c2i);
|
|
c2h.shapes (0).insert (db::Box (1, 2, 1003, 1005));
|
|
c2h.shapes (0).insert (db::Box (2, 2, 1003, 1004));
|
|
c2h.shapes (0).insert (db::Box (1, 2, 1003, 1006));
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, db::layout_diff::f_verbose, 0, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: boxes differ for layer 17/0 in cell c2x\n"
|
|
"Not in b but in a:\n"
|
|
" (1,2;1003,1004)\n"
|
|
"Not in a but in b:\n"
|
|
" (1,2;1003,1005)\n"
|
|
" (1,2;1003,1006)\n"
|
|
" (2,2;1003,1004)\n"
|
|
);
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, db::layout_diff::f_verbose, 1, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: boxes differ for layer 17/0 in cell c2x\n"
|
|
"Not in b but in a:\n"
|
|
"Not in a but in b:\n"
|
|
" (2,2;1003,1004)\n"
|
|
" (1,2;1003,1006)\n"
|
|
);
|
|
}
|
|
|
|
std::string ps2string (const db::PropertiesRepository &rep, db::properties_id_type pi)
|
|
{
|
|
std::string s;
|
|
db::PropertiesRepository::properties_set ps = rep.properties (pi);
|
|
for (db::PropertiesRepository::properties_set::const_iterator i = ps.begin (); i != ps.end (); ++i) {
|
|
if (!s.empty ()) {
|
|
s += ",";
|
|
}
|
|
s += rep.prop_name (i->first).to_string ();
|
|
s += ":";
|
|
s += i->second.to_string ();
|
|
}
|
|
return s;
|
|
}
|
|
|
|
TEST(2P)
|
|
{
|
|
db::Layout g;
|
|
g.insert_layer (0);
|
|
g.set_properties (0, db::LayerProperties (17, 0));
|
|
g.insert_layer (1);
|
|
g.set_properties (1, db::LayerProperties (42, 1));
|
|
|
|
db::cell_index_type c1i = g.add_cell ("c1");
|
|
db::cell_index_type c2i = g.add_cell ("c2x");
|
|
db::cell_index_type c3i = g.add_cell ("c3");
|
|
db::cell_index_type c4i = g.add_cell ("c4");
|
|
db::cell_index_type c5i = g.add_cell ("c5x");
|
|
|
|
{
|
|
|
|
db::Cell &c1 (g.cell (c1i));
|
|
db::Cell &c2 (g.cell (c2i));
|
|
db::Cell &c3 (g.cell (c3i));
|
|
db::Cell &c4 (g.cell (c4i));
|
|
db::Cell &c5 (g.cell (c5i));
|
|
c2.shapes (0).insert (db::Box (0, 1, 2, 3));
|
|
|
|
db::FTrans f (1, true);
|
|
db::Vector p (-10, 20);
|
|
db::Trans t (f.rot (), p);
|
|
db::Vector pp (10, -20);
|
|
db::Trans tt (0, pp);
|
|
|
|
// c4->c1 (aref)
|
|
c4.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t, db::Vector(1, 1), db::Vector (0, 2), 2, 3));
|
|
// c5->c1
|
|
c5.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
// c3->c5 (3x)
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5.cell_index ()), t));
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5.cell_index ()), tt));
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5.cell_index ()), t));
|
|
// c4->c3
|
|
c4.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c3.cell_index ()), t));
|
|
// c4->c1
|
|
c4.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), tt));
|
|
// c2->c1 (2x)
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), tt));
|
|
// c2->c4 (2x)
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
|
|
|
|
}
|
|
|
|
{
|
|
db::properties_id_type pi1, pi2, pi3;
|
|
|
|
db::PropertiesRepository::properties_set ps;
|
|
ps.insert (std::make_pair (g.properties_repository ().prop_name_id ("A"), tl::Variant (1)));
|
|
pi1 = g.properties_repository ().properties_id (ps);
|
|
EXPECT_EQ (pi1, db::properties_id_type (1));
|
|
|
|
ps.clear ();
|
|
ps.insert (std::make_pair (g.properties_repository ().prop_name_id ("B"), tl::Variant (2)));
|
|
pi2 = g.properties_repository ().properties_id (ps);
|
|
EXPECT_EQ (pi2, db::properties_id_type (2));
|
|
|
|
ps.insert (std::make_pair (g.properties_repository ().prop_name_id ("C"), tl::Variant ("c")));
|
|
pi3 = g.properties_repository ().properties_id (ps);
|
|
EXPECT_EQ (pi3, db::properties_id_type (3));
|
|
|
|
EXPECT_EQ (ps2string (g.properties_repository (), 1), "A:1");
|
|
EXPECT_EQ (ps2string (g.properties_repository (), 2), "B:2");
|
|
EXPECT_EQ (ps2string (g.properties_repository (), 3), "B:2,C:c");
|
|
}
|
|
|
|
db::Layout h = g;
|
|
|
|
{
|
|
EXPECT_EQ (ps2string (h.properties_repository (), 1), "A:1");
|
|
EXPECT_EQ (ps2string (h.properties_repository (), 2), "B:2");
|
|
EXPECT_EQ (ps2string (h.properties_repository (), 3), "B:2,C:c");
|
|
}
|
|
|
|
TestDifferenceReceiver r;
|
|
bool eq;
|
|
|
|
g.cell (c2i).shapes (0).insert (db::BoxWithProperties (db::Box (1, 2, 1003, 1004), 1));
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, 0, 0, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: bounding boxes differ for cell c2x, (0,1;1003,1004) vs. (0,1;2,3)\n"
|
|
"layout_diff: per-layer bounding boxes differ for cell c2x, layer (17/0), (0,1;1003,1004) vs. (0,1;2,3)\n"
|
|
"layout_diff: boxes differ for layer 17/0 in cell c2x\n"
|
|
);
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, db::layout_diff::f_verbose, 0, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: boxes differ for layer 17/0 in cell c2x\n"
|
|
"Not in b but in a:\n"
|
|
" (1,2;1003,1004) [1]\n"
|
|
"Not in a but in b:\n"
|
|
);
|
|
|
|
db::Layout hh = h;
|
|
|
|
// Note: properties are "normalized" (mapped to a common layout). In order to maintain
|
|
// their meaning later, keep these inserts sorted by property ID:
|
|
h.cell (c2i).shapes (0).insert (db::BoxWithProperties (db::Box (1, 2, 1003, 1006), 1));
|
|
h.cell (c2i).shapes (0).insert (db::BoxWithProperties (db::Box (1, 2, 1003, 1005), 2));
|
|
h.cell (c2i).shapes (0).insert (db::BoxWithProperties (db::Box (2, 2, 1003, 1004), 3));
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, db::layout_diff::f_verbose, 0, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: boxes differ for layer 17/0 in cell c2x\n"
|
|
"Not in b but in a:\n"
|
|
" (1,2;1003,1004) [1]\n"
|
|
"Not in a but in b:\n"
|
|
" (1,2;1003,1006) [1]\n"
|
|
" (1,2;1003,1005) [2]\n"
|
|
" (2,2;1003,1004) [3]\n"
|
|
);
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, db::layout_diff::f_verbose, 1, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: boxes differ for layer 17/0 in cell c2x\n"
|
|
"Not in b but in a:\n"
|
|
" (1,2;1003,1004) [1]\n"
|
|
"Not in a but in b:\n"
|
|
" (1,2;1003,1006) [1]\n"
|
|
" (1,2;1003,1005) [2]\n"
|
|
" (2,2;1003,1004) [3]\n"
|
|
);
|
|
|
|
h = hh;
|
|
|
|
{
|
|
EXPECT_EQ (ps2string (h.properties_repository (), 1), "A:1");
|
|
EXPECT_EQ (ps2string (h.properties_repository (), 2), "B:2");
|
|
EXPECT_EQ (ps2string (h.properties_repository (), 3), "B:2,C:c");
|
|
}
|
|
|
|
// Note: properties are "normalized" (mapped to a common layout). In order to maintain
|
|
// their meaning later, keep these inserts sorted by property ID:
|
|
h.cell (c2i).shapes (0).insert (db::BoxWithProperties (db::Box (1, 2, 1003, 1005), 1));
|
|
h.cell (c2i).shapes (0).insert (db::BoxWithProperties (db::Box (1, 2, 1003, 1006), 2));
|
|
h.cell (c2i).shapes (0).insert (db::BoxWithProperties (db::Box (2, 2, 1003, 1004), 3));
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, db::layout_diff::f_verbose, 0, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: boxes differ for layer 17/0 in cell c2x\n"
|
|
"Not in b but in a:\n"
|
|
" (1,2;1003,1004) [1]\n"
|
|
"Not in a but in b:\n"
|
|
" (1,2;1003,1005) [1]\n"
|
|
" (1,2;1003,1006) [2]\n"
|
|
" (2,2;1003,1004) [3]\n"
|
|
);
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, db::layout_diff::f_verbose, 1, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: boxes differ for layer 17/0 in cell c2x\n"
|
|
"Not in b but in a:\n"
|
|
"Not in a but in b:\n"
|
|
" (1,2;1003,1006) [2]\n"
|
|
" (2,2;1003,1004) [3]\n"
|
|
);
|
|
|
|
h = hh;
|
|
|
|
h.cell (c2i).shapes (0).insert (db::BoxWithProperties (db::Box (2, 2, 1003, 1004), 1));
|
|
h.cell (c2i).shapes (0).insert (db::BoxWithProperties (db::Box (1, 2, 1003, 1006), 2));
|
|
h.cell (c2i).shapes (0).insert (db::BoxWithProperties (db::Box (1, 2, 1003, 1005), 3));
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, db::layout_diff::f_verbose, 1, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: boxes differ for layer 17/0 in cell c2x\n"
|
|
"Not in b but in a:\n"
|
|
"Not in a but in b:\n"
|
|
" (1,2;1003,1006) [2]\n"
|
|
" (1,2;1003,1005) [3]\n"
|
|
);
|
|
|
|
h = hh;
|
|
|
|
h.cell (c2i).shapes (0).insert (db::Box (2, 2, 1003, 1004));
|
|
h.cell (c2i).shapes (0).insert (db::BoxWithProperties (db::Box (1, 2, 1003, 1006), 1));
|
|
h.cell (c2i).shapes (0).insert (db::BoxWithProperties (db::Box (1, 2, 1003, 1005), 1));
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, db::layout_diff::f_verbose, 1, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: boxes differ for layer 17/0 in cell c2x\n"
|
|
"Not in b but in a:\n"
|
|
" (1,2;1003,1004) [1]\n"
|
|
"Not in a but in b:\n"
|
|
" (2,2;1003,1004)\n"
|
|
" (1,2;1003,1006) [1]\n"
|
|
" (1,2;1003,1005) [1]\n"
|
|
);
|
|
}
|
|
|
|
TEST(3)
|
|
{
|
|
db::Layout g;
|
|
g.insert_layer (0);
|
|
g.set_properties (0, db::LayerProperties (17, 0));
|
|
g.insert_layer (1);
|
|
g.set_properties (1, db::LayerProperties (42, 1));
|
|
|
|
db::cell_index_type c1i = g.add_cell ("c1");
|
|
db::cell_index_type c2i = g.add_cell ("c2x");
|
|
db::cell_index_type c3i = g.add_cell ("c3");
|
|
db::cell_index_type c4i = g.add_cell ("c4");
|
|
db::cell_index_type c5i = g.add_cell ("c5x");
|
|
|
|
{
|
|
|
|
db::Cell &c1 (g.cell (c1i));
|
|
db::Cell &c2 (g.cell (c2i));
|
|
db::Cell &c3 (g.cell (c3i));
|
|
db::Cell &c4 (g.cell (c4i));
|
|
db::Cell &c5 (g.cell (c5i));
|
|
c2.shapes (0).insert (db::Box (0, 1, 2, 3));
|
|
|
|
db::FTrans f (1, true);
|
|
db::Vector p (-10, 20);
|
|
db::Trans t (f.rot (), p);
|
|
db::Vector pp (10, -20);
|
|
db::Trans tt (0, pp);
|
|
|
|
// c4->c1 (aref)
|
|
c4.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t, db::Vector(1, 1), db::Vector (0, 2), 2, 3));
|
|
// c5->c1
|
|
c5.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
// c3->c5 (3x)
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5.cell_index ()), t));
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5.cell_index ()), tt));
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5.cell_index ()), t));
|
|
// c4->c3
|
|
c4.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c3.cell_index ()), t));
|
|
// c4->c1
|
|
c4.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), tt));
|
|
// c2->c1 (2x)
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), tt));
|
|
// c2->c4 (2x)
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
|
|
|
|
}
|
|
|
|
db::Layout h = g;
|
|
|
|
TestDifferenceReceiver r;
|
|
bool eq;
|
|
|
|
g.cell (c2i).shapes (0).insert (db::Polygon (db::Box (1, 2, 1003, 1004)));
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, 0, 0, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: bounding boxes differ for cell c2x, (0,1;1003,1004) vs. (0,1;2,3)\n"
|
|
"layout_diff: per-layer bounding boxes differ for cell c2x, layer (17/0), (0,1;1003,1004) vs. (0,1;2,3)\n"
|
|
"layout_diff: polygons differ for layer 17/0 in cell c2x\n"
|
|
);
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, db::layout_diff::f_verbose, 0, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: polygons differ for layer 17/0 in cell c2x\n"
|
|
"Not in b but in a:\n"
|
|
" (1,2;1,1004;1003,1004;1003,2)\n"
|
|
"Not in a but in b:\n"
|
|
);
|
|
|
|
db::Layout hh = h;
|
|
|
|
db::Cell &c2h = h.cell (c2i);
|
|
c2h.shapes (0).insert (db::Polygon (db::Box (1, 2, 1003, 1005)));
|
|
c2h.shapes (0).insert (db::Polygon (db::Box (2, 2, 1003, 1004)));
|
|
c2h.shapes (0).insert (db::Polygon (db::Box (1, 2, 1003, 1006)));
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, db::layout_diff::f_verbose, 0, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: polygons differ for layer 17/0 in cell c2x\n"
|
|
"Not in b but in a:\n"
|
|
" (1,2;1,1004;1003,1004;1003,2)\n"
|
|
"Not in a but in b:\n"
|
|
" (1,2;1,1005;1003,1005;1003,2)\n"
|
|
" (1,2;1,1006;1003,1006;1003,2)\n"
|
|
" (2,2;2,1004;1003,1004;1003,2)\n"
|
|
);
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, db::layout_diff::f_verbose, 1, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: polygons differ for layer 17/0 in cell c2x\n"
|
|
"Not in b but in a:\n"
|
|
"Not in a but in b:\n"
|
|
" (2,2;2,1004;1003,1004;1003,2)\n"
|
|
" (1,2;1,1006;1003,1006;1003,2)\n"
|
|
);
|
|
}
|
|
|
|
TEST(4)
|
|
{
|
|
db::Layout g;
|
|
g.insert_layer (0);
|
|
g.set_properties (0, db::LayerProperties (17, 0));
|
|
g.insert_layer (1);
|
|
g.set_properties (1, db::LayerProperties (42, 1));
|
|
|
|
db::cell_index_type c1i = g.add_cell ("c1");
|
|
db::cell_index_type c2i = g.add_cell ("c2x");
|
|
db::cell_index_type c3i = g.add_cell ("c3");
|
|
db::cell_index_type c4i = g.add_cell ("c4");
|
|
db::cell_index_type c5i = g.add_cell ("c5x");
|
|
|
|
{
|
|
|
|
db::Cell &c1 (g.cell (c1i));
|
|
db::Cell &c2 (g.cell (c2i));
|
|
db::Cell &c3 (g.cell (c3i));
|
|
db::Cell &c4 (g.cell (c4i));
|
|
db::Cell &c5 (g.cell (c5i));
|
|
c2.shapes (0).insert (db::Box (0, 1, 2, 3));
|
|
|
|
db::FTrans f (1, true);
|
|
db::Vector p (-10, 20);
|
|
db::Trans t (f.rot (), p);
|
|
db::Vector pp (10, -20);
|
|
db::Trans tt (0, pp);
|
|
|
|
// c4->c1 (aref)
|
|
c4.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t, db::Vector(1, 1), db::Vector (0, 2), 2, 3));
|
|
// c5->c1
|
|
c5.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
// c3->c5 (3x)
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5.cell_index ()), t));
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5.cell_index ()), tt));
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5.cell_index ()), t));
|
|
// c4->c3
|
|
c4.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c3.cell_index ()), t));
|
|
// c4->c1
|
|
c4.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), tt));
|
|
// c2->c1 (2x)
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), tt));
|
|
// c2->c4 (2x)
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
|
|
|
|
}
|
|
|
|
db::Layout h = g;
|
|
|
|
TestDifferenceReceiver r;
|
|
bool eq;
|
|
|
|
g.cell (c2i).shapes (0).insert (db::Edge (1, 2, 1003, 1004));
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, 0, 0, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: bounding boxes differ for cell c2x, (0,1;1003,1004) vs. (0,1;2,3)\n"
|
|
"layout_diff: per-layer bounding boxes differ for cell c2x, layer (17/0), (0,1;1003,1004) vs. (0,1;2,3)\n"
|
|
"layout_diff: edges differ for layer 17/0 in cell c2x\n"
|
|
);
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, db::layout_diff::f_verbose, 0, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: edges differ for layer 17/0 in cell c2x\n"
|
|
"Not in b but in a:\n"
|
|
" (1,2;1003,1004)\n"
|
|
"Not in a but in b:\n"
|
|
);
|
|
|
|
db::Layout hh = h;
|
|
|
|
db::Cell &c2h = h.cell (c2i);
|
|
c2h.shapes (0).insert (db::Edge (1, 2, 1003, 1005));
|
|
c2h.shapes (0).insert (db::Edge (2, 2, 1003, 1004));
|
|
c2h.shapes (0).insert (db::Edge (1, 2, 1003, 1006));
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, db::layout_diff::f_verbose, 0, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: edges differ for layer 17/0 in cell c2x\n"
|
|
"Not in b but in a:\n"
|
|
" (1,2;1003,1004)\n"
|
|
"Not in a but in b:\n"
|
|
" (1,2;1003,1005)\n"
|
|
" (1,2;1003,1006)\n"
|
|
" (2,2;1003,1004)\n"
|
|
);
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, db::layout_diff::f_verbose, 1, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: edges differ for layer 17/0 in cell c2x\n"
|
|
"Not in b but in a:\n"
|
|
"Not in a but in b:\n"
|
|
" (2,2;1003,1004)\n"
|
|
" (1,2;1003,1006)\n"
|
|
);
|
|
}
|
|
|
|
TEST(5)
|
|
{
|
|
db::Layout g;
|
|
g.insert_layer (0);
|
|
g.set_properties (0, db::LayerProperties (17, 0));
|
|
g.insert_layer (1);
|
|
g.set_properties (1, db::LayerProperties (42, 1));
|
|
|
|
db::cell_index_type c1i = g.add_cell ("c1");
|
|
db::cell_index_type c2i = g.add_cell ("c2x");
|
|
db::cell_index_type c3i = g.add_cell ("c3");
|
|
db::cell_index_type c4i = g.add_cell ("c4");
|
|
db::cell_index_type c5i = g.add_cell ("c5x");
|
|
|
|
{
|
|
|
|
db::Cell &c1 (g.cell (c1i));
|
|
db::Cell &c2 (g.cell (c2i));
|
|
db::Cell &c3 (g.cell (c3i));
|
|
db::Cell &c4 (g.cell (c4i));
|
|
db::Cell &c5 (g.cell (c5i));
|
|
c2.shapes (0).insert (db::Box (0, 1, 2, 3));
|
|
|
|
db::FTrans f (1, true);
|
|
db::Vector p (-10, 20);
|
|
db::Trans t (f.rot (), p);
|
|
db::Vector pp (10, -20);
|
|
db::Trans tt (0, pp);
|
|
|
|
// c4->c1 (aref)
|
|
c4.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t, db::Vector(1, 1), db::Vector (0, 2), 2, 3));
|
|
// c5->c1
|
|
c5.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
// c3->c5 (3x)
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5.cell_index ()), t));
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5.cell_index ()), tt));
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5.cell_index ()), t));
|
|
// c4->c3
|
|
c4.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c3.cell_index ()), t));
|
|
// c4->c1
|
|
c4.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), tt));
|
|
// c2->c1 (2x)
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), tt));
|
|
// c2->c4 (2x)
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
|
|
|
|
}
|
|
|
|
db::Layout h = g;
|
|
|
|
TestDifferenceReceiver r;
|
|
bool eq;
|
|
|
|
db::Text t;
|
|
t = db::Text ("X", db::Trans (1, db::Vector (2, 3)), 17);
|
|
g.cell (c2i).shapes (0).insert (t);
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, 0, 0, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: texts differ for layer 17/0 in cell c2x\n"
|
|
);
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, db::layout_diff::f_verbose, 0, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: texts differ for layer 17/0 in cell c2x\n"
|
|
"Not in b but in a:\n"
|
|
" ('X',r90 2,3)\n"
|
|
"Not in a but in b:\n"
|
|
);
|
|
|
|
db::Layout hh = h;
|
|
hh.cell (c2i).shapes (0).insert (t);
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, hh, db::layout_diff::f_verbose, 0, r);
|
|
|
|
EXPECT_EQ (eq, true);
|
|
EXPECT_EQ (r.text (), "");
|
|
|
|
hh = h;
|
|
|
|
db::Cell &c2h = h.cell (c2i);
|
|
c2h.shapes (0).insert (db::Text ("Y", db::Trans (1, db::Vector (2, 3)), 17));
|
|
c2h.shapes (0).insert (db::Text ("X", db::Trans (2, db::Vector (2, 3)), 17));
|
|
c2h.shapes (0).insert (db::Text ("X", db::Trans (1, db::Vector (3, 4)), 17));
|
|
c2h.shapes (0).insert (db::Text ("X", db::Trans (1, db::Vector (2, 3)), 18));
|
|
// Text attributes like font and alignment are not compared, hence this text matches the one of g:
|
|
c2h.shapes (0).insert (db::Text ("X", db::Trans (1, db::Vector (2, 3)), 17, db::DefaultFont, db::HAlignCenter, db::VAlignCenter));
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, db::layout_diff::f_verbose, 0, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: texts differ for layer 17/0 in cell c2x\n"
|
|
"Not in b but in a:\n"
|
|
"Not in a but in b:\n"
|
|
" ('X',r90 3,4)\n"
|
|
" ('X',r90 2,3)\n"
|
|
" ('X',r180 2,3)\n"
|
|
" ('Y',r90 2,3)\n"
|
|
);
|
|
|
|
// two more to match more of h:
|
|
g.cell (c2i).shapes (0).insert (t);
|
|
g.cell (c2i).shapes (0).insert (t);
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, db::layout_diff::f_verbose, 1, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: texts differ for layer 17/0 in cell c2x\n"
|
|
"Not in b but in a:\n"
|
|
"Not in a but in b:\n"
|
|
" ('X',r180 2,3)\n"
|
|
" ('Y',r90 2,3)\n"
|
|
);
|
|
}
|
|
|
|
TEST(6)
|
|
{
|
|
db::Layout g;
|
|
g.insert_layer (0);
|
|
g.set_properties (0, db::LayerProperties (17, 0));
|
|
g.insert_layer (1);
|
|
g.set_properties (1, db::LayerProperties (42, 1));
|
|
|
|
db::cell_index_type c1i = g.add_cell ("c1");
|
|
db::cell_index_type c2i = g.add_cell ("c2x");
|
|
db::cell_index_type c3i = g.add_cell ("c3");
|
|
db::cell_index_type c4i = g.add_cell ("c4");
|
|
db::cell_index_type c5i = g.add_cell ("c5x");
|
|
|
|
{
|
|
|
|
db::Cell &c1 (g.cell (c1i));
|
|
db::Cell &c2 (g.cell (c2i));
|
|
db::Cell &c3 (g.cell (c3i));
|
|
db::Cell &c4 (g.cell (c4i));
|
|
db::Cell &c5 (g.cell (c5i));
|
|
c2.shapes (0).insert (db::Box (0, 1, 2, 3));
|
|
|
|
db::FTrans f (1, true);
|
|
db::Vector p (-10, 20);
|
|
db::Trans t (f.rot (), p);
|
|
db::Vector pp (10, -20);
|
|
db::Trans tt (0, pp);
|
|
|
|
// c4->c1 (aref)
|
|
c4.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t, db::Vector(1, 1), db::Vector (0, 2), 2, 3));
|
|
// c5->c1
|
|
c5.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
// c3->c5 (3x)
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5.cell_index ()), t));
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5.cell_index ()), tt));
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5.cell_index ()), t));
|
|
// c4->c3
|
|
c4.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c3.cell_index ()), t));
|
|
// c4->c1
|
|
c4.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), tt));
|
|
// c2->c1 (2x)
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), tt));
|
|
// c2->c4 (2x)
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
|
|
|
|
}
|
|
|
|
db::Layout h = g;
|
|
|
|
TestDifferenceReceiver r;
|
|
bool eq;
|
|
|
|
db::Point pts1[] = { db::Point (1, 2), db::Point (11, 12) };
|
|
db::Point pts2[] = { db::Point (1, 3), db::Point (11, 12) };
|
|
db::Point pts3[] = { db::Point (1, 3), db::Point (11, 11) };
|
|
|
|
db::Path p;
|
|
p = db::Path (&pts1[0], &pts1[sizeof (pts1) / sizeof (pts1[0])], 17, 0, 0, false);
|
|
g.cell (c2i).shapes (0).insert (p);
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, 0, 0, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: bounding boxes differ for cell c2x, (-5,-4;17,18) vs. (0,1;2,3)\n"
|
|
"layout_diff: per-layer bounding boxes differ for cell c2x, layer (17/0), (-5,-4;17,18) vs. (0,1;2,3)\n"
|
|
"layout_diff: paths differ for layer 17/0 in cell c2x\n"
|
|
);
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, db::layout_diff::f_verbose, 0, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: paths differ for layer 17/0 in cell c2x\n"
|
|
"Not in b but in a:\n"
|
|
" (1,2;11,12) w=17 bx=0 ex=0 r=false\n"
|
|
"Not in a but in b:\n"
|
|
);
|
|
|
|
db::Layout hh = h;
|
|
hh.cell (c2i).shapes (0).insert (p);
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, hh, db::layout_diff::f_verbose, 0, r);
|
|
|
|
EXPECT_EQ (eq, true);
|
|
EXPECT_EQ (r.text (), "");
|
|
|
|
hh = h;
|
|
|
|
db::Cell &c2h = h.cell (c2i);
|
|
c2h.shapes (0).insert (db::Path (&pts1[0], &pts1[sizeof (pts1) / sizeof (pts1[0])], 18, 0, 0, false));
|
|
c2h.shapes (0).insert (db::Path (&pts1[0], &pts1[sizeof (pts1) / sizeof (pts1[0])], 17, 1, 0, false));
|
|
c2h.shapes (0).insert (db::Path (&pts1[0], &pts1[sizeof (pts1) / sizeof (pts1[0])], 17, 0, -1, false));
|
|
c2h.shapes (0).insert (db::Path (&pts1[0], &pts1[sizeof (pts1) / sizeof (pts1[0])], 17, 0, 0, true));
|
|
c2h.shapes (0).insert (db::Path (&pts2[0], &pts2[sizeof (pts2) / sizeof (pts2[0])], 17, 0, 0, false));
|
|
c2h.shapes (0).insert (db::Path (&pts3[0], &pts3[sizeof (pts3) / sizeof (pts3[0])], 17, 0, 0, false));
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, db::layout_diff::f_verbose, 0, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: paths differ for layer 17/0 in cell c2x\n"
|
|
"Not in b but in a:\n"
|
|
"Not in a but in b:\n"
|
|
" (1,2;11,12) w=17 bx=0 ex=-1 r=false\n"
|
|
" (1,3;11,11) w=17 bx=0 ex=0 r=false\n"
|
|
" (1,2;11,12) w=17 bx=0 ex=0 r=true\n"
|
|
" (1,2;11,12) w=17 bx=1 ex=0 r=false\n"
|
|
" (1,2;11,12) w=18 bx=0 ex=0 r=false\n"
|
|
);
|
|
|
|
// two more to match more of h:
|
|
g.cell (c2i).shapes (0).insert (p);
|
|
g.cell (c2i).shapes (0).insert (p);
|
|
g.cell (c2i).shapes (0).insert (p);
|
|
g.cell (c2i).shapes (0).insert (p);
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, db::layout_diff::f_verbose, 1, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: paths differ for layer 17/0 in cell c2x\n"
|
|
"Not in b but in a:\n"
|
|
"Not in a but in b:\n"
|
|
" (1,2;11,12) w=17 bx=0 ex=0 r=true\n"
|
|
);
|
|
}
|
|
|
|
TEST(7)
|
|
{
|
|
db::Layout g;
|
|
g.insert_layer (0);
|
|
g.set_properties (0, db::LayerProperties (17, 0));
|
|
g.insert_layer (1);
|
|
g.set_properties (1, db::LayerProperties (42, 1));
|
|
|
|
db::cell_index_type c1i = g.add_cell ("c1");
|
|
db::cell_index_type c2i = g.add_cell ("c2x");
|
|
db::cell_index_type c3i = g.add_cell ("c3");
|
|
db::cell_index_type c4i = g.add_cell ("c4");
|
|
db::cell_index_type c5i = g.add_cell ("c5x");
|
|
|
|
{
|
|
|
|
db::Cell &c1 (g.cell (c1i));
|
|
db::Cell &c2 (g.cell (c2i));
|
|
db::Cell &c3 (g.cell (c3i));
|
|
db::Cell &c4 (g.cell (c4i));
|
|
db::Cell &c5 (g.cell (c5i));
|
|
c2.shapes (0).insert (db::Box (0, 1, 2, 3));
|
|
|
|
db::FTrans f (1, true);
|
|
db::Vector p (-10, 20);
|
|
db::Trans t (f.rot (), p);
|
|
db::Vector pp (10, -20);
|
|
db::Trans tt (0, pp);
|
|
|
|
// c4->c1 (aref)
|
|
c4.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t, db::Vector(1, 1), db::Vector (0, 2), 2, 3));
|
|
// c5->c1
|
|
c5.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
// c3->c5 (3x)
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5.cell_index ()), t));
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5.cell_index ()), tt));
|
|
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c5.cell_index ()), t));
|
|
// c4->c3
|
|
c4.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c3.cell_index ()), t));
|
|
// c4->c1
|
|
c4.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), tt));
|
|
// c2->c1 (2x)
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), tt));
|
|
// c2->c4 (2x)
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
|
|
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
|
|
|
|
}
|
|
|
|
db::Layout h = g;
|
|
db::Layout hh = g;
|
|
db::Layout hhh = g;
|
|
|
|
TestDifferenceReceiver r;
|
|
bool eq;
|
|
|
|
g.cell (c2i).shapes (0).insert (db::Box (1, 2, 1003, 1004));
|
|
g.cell (c2i).shapes (0).insert (db::Box (2, 3, 1004, 1005));
|
|
g.cell (c2i).shapes (0).insert (db::Box (3, 4, 1005, 1006));
|
|
g.cell (c2i).shapes (0).insert (db::Box (4, 5, 1006, 1007));
|
|
g.cell (c2i).shapes (0).insert (db::Box (5, 6, 1007, 1008));
|
|
g.cell (c2i).shapes (0).insert (db::Box (3, 7, 1008, 1009));
|
|
g.cell (c2i).shapes (0).insert (db::Box (3, 8, 1009, 1010));
|
|
|
|
h.cell (c2i).shapes (0).insert (db::Box (3, 8, 1009, 1010));
|
|
h.cell (c2i).shapes (0).insert (db::Box (3, 7, 1008, 1009));
|
|
h.cell (c2i).shapes (0).insert (db::Box (5, 6, 1007, 1008));
|
|
h.cell (c2i).shapes (0).insert (db::Box (4, 5, 1006, 1009));
|
|
h.cell (c2i).shapes (0).insert (db::Box (3, 4, 1005, 1006));
|
|
h.cell (c2i).shapes (0).insert (db::Box (2, 3, 1004, 1005));
|
|
h.cell (c2i).shapes (0).insert (db::Box (1, 2, 1003, 1004));
|
|
|
|
hh.cell (c2i).shapes (0).insert (db::Box (3, 8, 1009, 1010));
|
|
hh.cell (c2i).shapes (0).insert (db::Box (3, 7, 1008, 1009));
|
|
hh.cell (c2i).shapes (0).insert (db::Box (5, 6, 1007, 1008));
|
|
hh.cell (c2i).shapes (0).insert (db::Box (4, 5, 1006, 1007));
|
|
hh.cell (c2i).shapes (0).insert (db::Box (3, 4, 1005, 1006));
|
|
hh.cell (c2i).shapes (0).insert (db::Box (2, 3, 1004, 1005));
|
|
hh.cell (c2i).shapes (0).insert (db::Box (1, 2, 1003, 1004));
|
|
|
|
hhh.cell (c2i).shapes (0).insert (db::Box (3, 8, 1009, 1010));
|
|
hhh.cell (c2i).shapes (0).insert (db::Box (3, 7, 1008, 1009));
|
|
hhh.cell (c2i).shapes (0).insert (db::Box (5, 6, 1007, 1008));
|
|
hhh.cell (c2i).shapes (0).insert (db::Box (4, 5, 1006, 1008));
|
|
hhh.cell (c2i).shapes (0).insert (db::Box (3, 4, 1005, 1006));
|
|
hhh.cell (c2i).shapes (0).insert (db::Box (2, 3, 1004, 1005));
|
|
hhh.cell (c2i).shapes (0).insert (db::Box (1, 2, 1003, 1004));
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, db::layout_diff::f_verbose, 0, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: boxes differ for layer 17/0 in cell c2x\n"
|
|
"Not in b but in a:\n"
|
|
" (4,5;1006,1007)\n"
|
|
"Not in a but in b:\n"
|
|
" (4,5;1006,1009)\n"
|
|
);
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, h, db::layout_diff::f_verbose, 1, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: boxes differ for layer 17/0 in cell c2x\n"
|
|
"Not in b but in a:\n"
|
|
" (4,5;1006,1007)\n"
|
|
"Not in a but in b:\n"
|
|
" (4,5;1006,1009)\n"
|
|
);
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, hh, db::layout_diff::f_verbose, 0, r);
|
|
|
|
EXPECT_EQ (eq, true);
|
|
EXPECT_EQ (r.text (), "");
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, hh, db::layout_diff::f_verbose, 1, r);
|
|
|
|
EXPECT_EQ (eq, true);
|
|
EXPECT_EQ (r.text (), "");
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, hhh, db::layout_diff::f_verbose, 0, r);
|
|
|
|
EXPECT_EQ (eq, false);
|
|
EXPECT_EQ (r.text (),
|
|
"layout_diff: boxes differ for layer 17/0 in cell c2x\n"
|
|
"Not in b but in a:\n"
|
|
" (4,5;1006,1007)\n"
|
|
"Not in a but in b:\n"
|
|
" (4,5;1006,1008)\n"
|
|
);
|
|
|
|
r.clear ();
|
|
eq = db::compare_layouts (g, hhh, db::layout_diff::f_verbose, 1, r);
|
|
|
|
EXPECT_EQ (eq, true);
|
|
EXPECT_EQ (r.text (), "");
|
|
}
|
|
|
|
|