mirror of https://github.com/KLayout/klayout.git
Some enhancements to layer and cell mapping
* Modification of the mapping is possible now (#map used to ignore mappings if there was one already) * Added DropCell mapping (also for RBA) * Added unit tests for cell mapping, layer mapping db::merge_layouts, db::copy_shapes and db::move_shapes
This commit is contained in:
parent
3499c3856a
commit
b28317fb69
|
|
@ -144,7 +144,7 @@ public:
|
|||
*/
|
||||
void map (db::cell_index_type cell_index_b, db::cell_index_type cell_index_a)
|
||||
{
|
||||
m_b2a_mapping.insert (std::make_pair (cell_index_b, cell_index_a));
|
||||
m_b2a_mapping.insert (std::make_pair (cell_index_b, 0)).first->second = cell_index_a;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ public:
|
|||
*/
|
||||
void map (unsigned int layer_b, unsigned int layer_a)
|
||||
{
|
||||
m_b2a_mapping.insert (std::make_pair (layer_b, layer_a));
|
||||
m_b2a_mapping.insert (std::make_pair (layer_b, 0)).first->second = layer_a;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -126,6 +126,40 @@ PropertyMapper::operator() (db::Layout::properties_id_type source_id)
|
|||
// ------------------------------------------------------------------------------------
|
||||
// merge_layouts implementation
|
||||
|
||||
static void
|
||||
collect_cells_to_copy (const db::Layout &source,
|
||||
const std::vector<db::cell_index_type> &source_cells,
|
||||
const std::map<db::cell_index_type, db::cell_index_type> &cell_mapping,
|
||||
std::set<db::cell_index_type> &all_top_level_cells,
|
||||
std::set<db::cell_index_type> &all_cells_to_copy)
|
||||
{
|
||||
std::vector<db::cell_index_type> dropped_cells;
|
||||
|
||||
for (std::map<db::cell_index_type, db::cell_index_type>::const_iterator m = cell_mapping.begin (); m != cell_mapping.end (); ++m) {
|
||||
if (m->second == DropCell) {
|
||||
dropped_cells.push_back (m->first);
|
||||
}
|
||||
}
|
||||
|
||||
for (std::vector<db::cell_index_type>::const_iterator src = source_cells.begin (); src != source_cells.end (); ++src) {
|
||||
|
||||
all_cells_to_copy.insert (*src);
|
||||
all_top_level_cells.insert (*src);
|
||||
|
||||
// feed the excluded cells into the "all_cells_to_copy" cache. This will make "collect_called_cells" not
|
||||
// dive into their hierarchy. We will later delete them there.
|
||||
all_cells_to_copy.insert (dropped_cells.begin (), dropped_cells.end ());
|
||||
|
||||
source.cell (*src).collect_called_cells (all_cells_to_copy);
|
||||
|
||||
for (std::vector<db::cell_index_type>::const_iterator i = dropped_cells.begin (); i != dropped_cells.end (); ++i) {
|
||||
all_cells_to_copy.erase (*i);
|
||||
all_top_level_cells.erase (*i);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
merge_layouts (db::Layout &target,
|
||||
const db::Layout &source,
|
||||
|
|
@ -135,19 +169,11 @@ merge_layouts (db::Layout &target,
|
|||
const std::map<unsigned int, unsigned int> &layer_mapping,
|
||||
std::map<db::cell_index_type, db::cell_index_type> *final_cell_mapping)
|
||||
{
|
||||
if (final_cell_mapping) {
|
||||
final_cell_mapping->insert (cell_mapping.begin (), cell_mapping.end ());
|
||||
}
|
||||
|
||||
// collect all called cells and all top level cells
|
||||
std::set<db::cell_index_type> all_top_level_cells;
|
||||
std::set<db::cell_index_type> all_cells_to_copy;
|
||||
|
||||
for (std::vector<db::cell_index_type>::const_iterator src = source_cells.begin (); src != source_cells.end (); ++src) {
|
||||
all_cells_to_copy.insert (*src);
|
||||
all_top_level_cells.insert (*src);
|
||||
source.cell (*src).collect_called_cells (all_cells_to_copy);
|
||||
}
|
||||
collect_cells_to_copy (source, source_cells, cell_mapping, all_top_level_cells, all_cells_to_copy);
|
||||
|
||||
// identify all new cells and create new ones
|
||||
std::map<db::cell_index_type, db::cell_index_type> new_cell_mapping;
|
||||
|
|
@ -158,6 +184,11 @@ merge_layouts (db::Layout &target,
|
|||
}
|
||||
|
||||
if (final_cell_mapping) {
|
||||
for (std::map<db::cell_index_type, db::cell_index_type>::const_iterator m = cell_mapping.begin (); m != cell_mapping.end (); ++m) {
|
||||
if (m->second != DropCell) {
|
||||
final_cell_mapping->insert (*m);
|
||||
}
|
||||
}
|
||||
final_cell_mapping->insert (new_cell_mapping.begin (), new_cell_mapping.end ());
|
||||
}
|
||||
|
||||
|
|
@ -248,7 +279,7 @@ copy_or_propagate_shapes (db::Layout &target,
|
|||
|
||||
}
|
||||
|
||||
} else {
|
||||
} else if (cm->second != DropCell) {
|
||||
|
||||
db::Cell &target_cell = target.cell (cm->second);
|
||||
target_cell.shapes (target_layer).insert_transformed (source_cell.shapes (source_layer), trans * propagate_trans, pm);
|
||||
|
|
@ -256,23 +287,20 @@ copy_or_propagate_shapes (db::Layout &target,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
copy_shapes (db::Layout &target,
|
||||
const db::Layout &source,
|
||||
const db::ICplxTrans &trans,
|
||||
const std::vector<db::cell_index_type> &source_cells,
|
||||
const std::map<db::cell_index_type, db::cell_index_type> &cell_mapping,
|
||||
const std::map<unsigned int, unsigned int> &layer_mapping)
|
||||
static void
|
||||
copy_or_move_shapes (db::Layout &target,
|
||||
db::Layout &source,
|
||||
const db::ICplxTrans &trans,
|
||||
const std::vector<db::cell_index_type> &source_cells,
|
||||
const std::map<db::cell_index_type, db::cell_index_type> &cell_mapping,
|
||||
const std::map<unsigned int, unsigned int> &layer_mapping,
|
||||
bool move)
|
||||
{
|
||||
// collect all called cells and all top level cells
|
||||
std::set<db::cell_index_type> all_top_level_cells;
|
||||
std::set<db::cell_index_type> all_cells_to_copy;
|
||||
|
||||
for (std::vector<db::cell_index_type>::const_iterator src = source_cells.begin (); src != source_cells.end (); ++src) {
|
||||
all_cells_to_copy.insert (*src);
|
||||
all_top_level_cells.insert (*src);
|
||||
source.cell (*src).collect_called_cells (all_cells_to_copy);
|
||||
}
|
||||
collect_cells_to_copy (source, source_cells, cell_mapping, all_top_level_cells, all_cells_to_copy);
|
||||
|
||||
// provide the property mapper
|
||||
db::PropertyMapper pm (target, source);
|
||||
|
|
@ -284,10 +312,24 @@ copy_shapes (db::Layout &target,
|
|||
for (std::map<unsigned int, unsigned int>::const_iterator lm = layer_mapping.begin (); lm != layer_mapping.end (); ++lm) {
|
||||
++progress;
|
||||
copy_or_propagate_shapes (target, source, trans, db::ICplxTrans (), pm, *c, *c, lm->second, lm->first, all_cells_to_copy, cell_mapping);
|
||||
if (move) {
|
||||
source.cell (*c).shapes (lm->first).clear ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
copy_shapes (db::Layout &target,
|
||||
const db::Layout &source,
|
||||
const db::ICplxTrans &trans,
|
||||
const std::vector<db::cell_index_type> &source_cells,
|
||||
const std::map<db::cell_index_type, db::cell_index_type> &cell_mapping,
|
||||
const std::map<unsigned int, unsigned int> &layer_mapping)
|
||||
{
|
||||
copy_or_move_shapes (target, const_cast<db::Layout &> (source), trans, source_cells, cell_mapping, layer_mapping, false);
|
||||
}
|
||||
|
||||
void
|
||||
move_shapes (db::Layout &target,
|
||||
db::Layout &source,
|
||||
|
|
@ -296,29 +338,7 @@ move_shapes (db::Layout &target,
|
|||
const std::map<db::cell_index_type, db::cell_index_type> &cell_mapping,
|
||||
const std::map<unsigned int, unsigned int> &layer_mapping)
|
||||
{
|
||||
// collect all called cells and all top level cells
|
||||
std::set<db::cell_index_type> all_top_level_cells;
|
||||
std::set<db::cell_index_type> all_cells_to_copy;
|
||||
|
||||
for (std::vector<db::cell_index_type>::const_iterator src = source_cells.begin (); src != source_cells.end (); ++src) {
|
||||
all_cells_to_copy.insert (*src);
|
||||
all_top_level_cells.insert (*src);
|
||||
source.cell (*src).collect_called_cells (all_cells_to_copy);
|
||||
}
|
||||
|
||||
// provide the property mapper
|
||||
db::PropertyMapper pm (target, source);
|
||||
|
||||
tl::RelativeProgress progress (tl::to_string (QObject::tr ("Merge cells")), all_cells_to_copy.size () * layer_mapping.size (), 1);
|
||||
|
||||
// and copy
|
||||
for (std::set<db::cell_index_type>::const_iterator c = all_cells_to_copy.begin (); c != all_cells_to_copy.end (); ++c) {
|
||||
for (std::map<unsigned int, unsigned int>::const_iterator lm = layer_mapping.begin (); lm != layer_mapping.end (); ++lm) {
|
||||
++progress;
|
||||
copy_or_propagate_shapes (target, source, trans, db::ICplxTrans (), pm, *c, *c, lm->second, lm->first, all_cells_to_copy, cell_mapping);
|
||||
source.cell (*c).shapes (lm->first).clear ();
|
||||
}
|
||||
}
|
||||
copy_or_move_shapes (target, source, trans, source_cells, cell_mapping, layer_mapping, true);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
|
@ -110,6 +111,14 @@ private:
|
|||
std::map <db::Layout::properties_id_type, db::Layout::properties_id_type> m_prop_id_map;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A constant describing "drop cell" mapping
|
||||
*
|
||||
* If used as the target cell index, this constant means "drop the cell".
|
||||
* This cell and it's children will be dropped unless the children are used by other cells.
|
||||
*/
|
||||
const db::cell_index_type DropCell = std::numeric_limits<db::cell_index_type>::max ();
|
||||
|
||||
/**
|
||||
* @brief Merge one layout into another
|
||||
*
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "gsiDecl.h"
|
||||
#include "dbCellMapping.h"
|
||||
#include "dbLayoutUtils.h"
|
||||
#include "dbLayout.h"
|
||||
|
||||
#include <memory>
|
||||
|
|
@ -30,9 +31,25 @@
|
|||
namespace gsi
|
||||
{
|
||||
|
||||
static db::cell_index_type drop_cell_const ()
|
||||
{
|
||||
return db::DropCell;
|
||||
}
|
||||
|
||||
Class<db::CellMapping> decl_CellMapping ("CellMapping",
|
||||
gsi::method ("DropCell", &drop_cell_const,
|
||||
"@brief A constant indicating the reques to drop a cell\n"
|
||||
"\n"
|
||||
"If used as a pseudo-target for the cell mapping, this index indicates "
|
||||
"that the cell shall be dropped rather than created on the target side "
|
||||
"or skipped by flattening. Instead, all shapes of this cell are discarded "
|
||||
"and it's children are not translated unless explicitly requested or "
|
||||
"if required are children for other cells.\n"
|
||||
"\n"
|
||||
"This constant has been introduced in version 0.25."
|
||||
) +
|
||||
gsi::method ("for_single_cell", &db::CellMapping::create_single_mapping,
|
||||
"@brief Initialize the cell mapping for top-level identity\n"
|
||||
"@brief Initializes the cell mapping for top-level identity\n"
|
||||
"\n"
|
||||
"@args layout_a, cell_index_a, layout_b, cell_index_b\n"
|
||||
"@param layout_a The target layout.\n"
|
||||
|
|
@ -42,13 +59,15 @@ Class<db::CellMapping> decl_CellMapping ("CellMapping",
|
|||
"\n"
|
||||
"The cell mapping is created for cell_b to cell_a in the respective layouts. "
|
||||
"This method clears the mapping and creates one for the single cell pair. "
|
||||
"In addition, this method completes the mapping by adding all the child cells "
|
||||
"of cell_b to layout_a and creating the proper instances. "
|
||||
"If used for \\Cell#copy_tree or \\Cell#move_tree, this cell mapping will essentially "
|
||||
"flatten the cell.\n"
|
||||
"\n"
|
||||
"This method is equivalent to \\clear, followed by \\map(cell_index_a, cell_index_b).\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.23."
|
||||
) +
|
||||
gsi::method ("for_single_cell_full", &db::CellMapping::create_single_mapping_full,
|
||||
"@brief Initialize the cell mapping for top-level identity\n"
|
||||
"@brief Initializes the cell mapping for top-level identity\n"
|
||||
"\n"
|
||||
"@args layout_a, cell_index_a, layout_b, cell_index_b\n"
|
||||
"@param layout_a The target layout.\n"
|
||||
|
|
@ -58,11 +77,13 @@ Class<db::CellMapping> decl_CellMapping ("CellMapping",
|
|||
"\n"
|
||||
"The cell mapping is created for cell_b to cell_a in the respective layouts. "
|
||||
"This method clears the mapping and creates one for the single cell pair. "
|
||||
"In addition and in contrast to \\for_single_cell, this method completes the mapping by adding all the child cells "
|
||||
"of cell_b to layout_a and creating the proper instances. "
|
||||
"\n"
|
||||
"This method has been introduced in version 0.23."
|
||||
) +
|
||||
gsi::method ("from_geometry_full", &db::CellMapping::create_from_geometry_full,
|
||||
"@brief Initialize the cell mapping using the geometrical identity in full mapping mode\n"
|
||||
"@brief Initializes the cell mapping using the geometrical identity in full mapping mode\n"
|
||||
"\n"
|
||||
"@args layout_a, cell_index_a, layout_b, cell_index_b\n"
|
||||
"@param layout_a The target layout.\n"
|
||||
|
|
@ -83,7 +104,7 @@ Class<db::CellMapping> decl_CellMapping ("CellMapping",
|
|||
"This method has been introduced in version 0.23."
|
||||
) +
|
||||
gsi::method ("from_geometry", &db::CellMapping::create_from_geometry,
|
||||
"@brief Initialize the cell mapping using the geometrical identity\n"
|
||||
"@brief Initializes the cell mapping using the geometrical identity\n"
|
||||
"\n"
|
||||
"@args layout_a, cell_index_a, layout_b, cell_index_b\n"
|
||||
"@param layout_a The target layout.\n"
|
||||
|
|
@ -99,7 +120,7 @@ Class<db::CellMapping> decl_CellMapping ("CellMapping",
|
|||
"This method has been introduced in version 0.23."
|
||||
) +
|
||||
gsi::method ("from_names", &db::CellMapping::create_from_names,
|
||||
"@brief Initialize the cell mapping using the name identity\n"
|
||||
"@brief Initializes the cell mapping using the name identity\n"
|
||||
"\n"
|
||||
"@args layout_a, cell_index_a, layout_b, cell_index_b\n"
|
||||
"@param layout_a The target layout.\n"
|
||||
|
|
@ -114,7 +135,7 @@ Class<db::CellMapping> decl_CellMapping ("CellMapping",
|
|||
"This method has been introduced in version 0.23."
|
||||
) +
|
||||
gsi::method ("from_names_full", &db::CellMapping::create_from_names_full,
|
||||
"@brief Initialize the cell mapping using the name identity in full mapping mode\n"
|
||||
"@brief Initializes the cell mapping using the name identity in full mapping mode\n"
|
||||
"\n"
|
||||
"@args layout_a, cell_index_a, layout_b, cell_index_b\n"
|
||||
"@param layout_a The target layout.\n"
|
||||
|
|
@ -139,12 +160,12 @@ Class<db::CellMapping> decl_CellMapping ("CellMapping",
|
|||
"This method has been introduced in version 0.23."
|
||||
) +
|
||||
gsi::method ("map", &db::CellMapping::map,
|
||||
"@brief Explicitly specify a mapping.\n"
|
||||
"@brief Explicitly specifies a mapping.\n"
|
||||
"\n"
|
||||
"@args cell_index_b, cell_index_a\n"
|
||||
"\n"
|
||||
"@param cell_index_b The index of the cell in layout B (the \"source\")\n"
|
||||
"@param cell_index_a The index of the cell in layout A (the \"target\")\n"
|
||||
"@param cell_index_a The index of the cell in layout A (the \"target\") - this index can be \\DropCell\n"
|
||||
"\n"
|
||||
"Beside using the mapping generator algorithms provided through \\from_names and \\from_geometry, "
|
||||
"it is possible to explicitly specify cell mappings using this method.\n"
|
||||
|
|
@ -152,20 +173,25 @@ Class<db::CellMapping> decl_CellMapping ("CellMapping",
|
|||
"This method has been introduced in version 0.23."
|
||||
) +
|
||||
gsi::method ("has_mapping?", &db::CellMapping::has_mapping,
|
||||
"@brief Determine if a cell of layout_b has a mapping to a layout_a cell.\n"
|
||||
"@brief Returns as value indicating whether a cell of layout_b has a mapping to a layout_a cell.\n"
|
||||
"\n"
|
||||
"@args cell_index_b\n"
|
||||
"\n"
|
||||
"@param cell_index_b The index of the cell in layout_b whose mapping is requested.\n"
|
||||
"@return true, if the cell has a mapping\n"
|
||||
"\n"
|
||||
"Note that if the cell is supposed to be dropped (see \\DropCell), the respective "
|
||||
"source cell will also be regarded \"mapped\", so has_mapping? will return true in this case.\n"
|
||||
) +
|
||||
gsi::method ("cell_mapping", &db::CellMapping::cell_mapping,
|
||||
"@brief Determine cell mapping of a layout_b cell to the corresponding layout_a cell.\n"
|
||||
"@brief Determines cell mapping of a layout_b cell to the corresponding layout_a cell.\n"
|
||||
"\n"
|
||||
"@args cell_index_b\n"
|
||||
"\n"
|
||||
"@param cell_index_b The index of the cell in layout_b whose mapping is requested.\n"
|
||||
"@return The cell index in layout_a.\n"
|
||||
"\n"
|
||||
"Note that the returned index can be \\DropCell to indicate the cell shall be dropped."
|
||||
),
|
||||
"@brief A cell mapping (source to target layout)\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,616 @@
|
|||
|
||||
/*
|
||||
|
||||
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 "dbLayoutUtils.h"
|
||||
#include "dbLayerMapping.h"
|
||||
#include "dbCellMapping.h"
|
||||
#include "dbReader.h"
|
||||
#include "tlString.h"
|
||||
#include "utHead.h"
|
||||
|
||||
unsigned int find_layer (const db::Layout &l, int ly, int dt)
|
||||
{
|
||||
for (db::Layout::layer_iterator li = l.begin_layers (); li != l.end_layers (); ++li) {
|
||||
if ((*li).second->log_equal (db::LayerProperties (ly, dt))) {
|
||||
return (*li).first;
|
||||
}
|
||||
}
|
||||
tl_assert (false);
|
||||
}
|
||||
|
||||
TEST(1)
|
||||
{
|
||||
db::Layout l1;
|
||||
{
|
||||
std::string fn (ut::testsrc ());
|
||||
fn += "/testdata/algo/layout_utils_l1.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (l1);
|
||||
}
|
||||
|
||||
db::Layout l2;
|
||||
{
|
||||
std::string fn (ut::testsrc ());
|
||||
fn += "/testdata/algo/layout_utils_l2.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (l2);
|
||||
}
|
||||
|
||||
db::LayerMapping lm;
|
||||
lm.create (l2, l1);
|
||||
|
||||
unsigned int li1 = find_layer (l1, 1, 0);
|
||||
unsigned int li2 = find_layer (l1, 2, 0);
|
||||
unsigned int li3 = find_layer (l1, 3, 0);
|
||||
|
||||
EXPECT_EQ (lm.has_mapping (li1), true);
|
||||
EXPECT_EQ (lm.layer_mapping_pair (li1).first, true);
|
||||
EXPECT_EQ (l2.get_properties (lm.layer_mapping_pair (li1).second).to_string (), "1/0");
|
||||
EXPECT_EQ (lm.has_mapping (li2), true);
|
||||
EXPECT_EQ (lm.layer_mapping_pair (li2).first, true);
|
||||
EXPECT_EQ (l2.get_properties (lm.layer_mapping_pair (li2).second).to_string (), "2/0");
|
||||
EXPECT_EQ (lm.has_mapping (li3), false);
|
||||
EXPECT_EQ (lm.layer_mapping_pair (li3).first, false);
|
||||
|
||||
lm.clear ();
|
||||
EXPECT_EQ (lm.has_mapping (li1), false);
|
||||
EXPECT_EQ (lm.has_mapping (li2), false);
|
||||
EXPECT_EQ (lm.has_mapping (li3), false);
|
||||
|
||||
lm.create_full (l2, l1);
|
||||
|
||||
EXPECT_EQ (lm.has_mapping (li1), true);
|
||||
EXPECT_EQ (lm.layer_mapping_pair (li1).first, true);
|
||||
EXPECT_EQ (l2.get_properties (lm.layer_mapping_pair (li1).second).to_string (), "1/0");
|
||||
EXPECT_EQ (lm.has_mapping (li2), true);
|
||||
EXPECT_EQ (lm.layer_mapping_pair (li2).first, true);
|
||||
EXPECT_EQ (l2.get_properties (lm.layer_mapping_pair (li2).second).to_string (), "2/0");
|
||||
EXPECT_EQ (lm.has_mapping (li3), true);
|
||||
EXPECT_EQ (lm.layer_mapping_pair (li3).first, true);
|
||||
EXPECT_EQ (l2.get_properties (lm.layer_mapping_pair (li3).second).to_string (), "3/0");
|
||||
}
|
||||
|
||||
// Tests merge_layout with no specific mapping (plain duplication of the tree)
|
||||
TEST(2)
|
||||
{
|
||||
db::Layout l1;
|
||||
{
|
||||
std::string fn (ut::testsrc ());
|
||||
fn += "/testdata/algo/layout_utils_l1.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (l1);
|
||||
}
|
||||
|
||||
db::Layout l2;
|
||||
{
|
||||
std::string fn (ut::testsrc ());
|
||||
fn += "/testdata/algo/layout_utils_l2.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (l2);
|
||||
}
|
||||
|
||||
unsigned int li1 = find_layer (l1, 1, 0);
|
||||
unsigned int li2 = find_layer (l1, 2, 0);
|
||||
unsigned int li3 = find_layer (l1, 3, 0);
|
||||
|
||||
db::LayerMapping lm;
|
||||
lm.map (li1, l2.insert_layer (db::LayerProperties (11, 0)));
|
||||
lm.map (li2, l2.insert_layer (db::LayerProperties (12, 0)));
|
||||
lm.map (li3, l2.insert_layer (db::LayerProperties (13, 0)));
|
||||
|
||||
db::CellMapping cm;
|
||||
std::map<db::cell_index_type, db::cell_index_type> fm;
|
||||
std::vector<db::cell_index_type> src;
|
||||
src.push_back (l1.cell_by_name ("TOP").second);
|
||||
db::merge_layouts (l2, l1, db::ICplxTrans (), src, cm.table (), lm.table (), &fm);
|
||||
|
||||
CHECKPOINT();
|
||||
compare_layouts (l2, ut::testsrc () + "/testdata/algo/layout_utils_au2.gds");
|
||||
|
||||
EXPECT_EQ (fm.find (l1.cell_by_name ("TOP").second) != fm.end (), true);
|
||||
EXPECT_EQ (l2.cell_name (fm.find (l1.cell_by_name ("TOP").second)->second), "TOP$1");
|
||||
EXPECT_EQ (fm.find (l1.cell_by_name ("A").second) != fm.end (), true);
|
||||
EXPECT_EQ (l2.cell_name (fm.find (l1.cell_by_name ("A").second)->second), "A$1");
|
||||
EXPECT_EQ (fm.find (l1.cell_by_name ("B").second) != fm.end (), true);
|
||||
EXPECT_EQ (l2.cell_name (fm.find (l1.cell_by_name ("B").second)->second), "B$1");
|
||||
EXPECT_EQ (fm.find (l1.cell_by_name ("C").second) != fm.end (), true);
|
||||
EXPECT_EQ (l2.cell_name (fm.find (l1.cell_by_name ("C").second)->second), "C$1");
|
||||
}
|
||||
|
||||
// Tests merge_layout with a single mapped cell (the others are mapped automatically)
|
||||
TEST(3)
|
||||
{
|
||||
db::Layout l1;
|
||||
{
|
||||
std::string fn (ut::testsrc ());
|
||||
fn += "/testdata/algo/layout_utils_l1.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (l1);
|
||||
}
|
||||
|
||||
db::Layout l2;
|
||||
{
|
||||
std::string fn (ut::testsrc ());
|
||||
fn += "/testdata/algo/layout_utils_l2.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (l2);
|
||||
}
|
||||
|
||||
unsigned int li1 = find_layer (l1, 1, 0);
|
||||
unsigned int li2 = find_layer (l1, 2, 0);
|
||||
unsigned int li3 = find_layer (l1, 3, 0);
|
||||
|
||||
db::LayerMapping lm;
|
||||
lm.map (li1, l2.insert_layer (db::LayerProperties (11, 0)));
|
||||
lm.map (li2, l2.insert_layer (db::LayerProperties (12, 0)));
|
||||
lm.map (li3, l2.insert_layer (db::LayerProperties (13, 0)));
|
||||
|
||||
db::CellMapping cm;
|
||||
std::map<db::cell_index_type, db::cell_index_type> fm;
|
||||
std::vector<db::cell_index_type> src;
|
||||
src.push_back (l1.cell_by_name ("TOP").second);
|
||||
cm.map (src.front (), l2.add_cell ("TOPTOP"));
|
||||
db::merge_layouts (l2, l1, db::ICplxTrans (), src, cm.table (), lm.table (), &fm);
|
||||
|
||||
CHECKPOINT();
|
||||
compare_layouts (l2, ut::testsrc () + "/testdata/algo/layout_utils_au3.gds");
|
||||
|
||||
EXPECT_EQ (fm.find (l1.cell_by_name ("TOP").second) != fm.end (), true);
|
||||
EXPECT_EQ (l2.cell_name (fm.find (l1.cell_by_name ("TOP").second)->second), "TOPTOP");
|
||||
EXPECT_EQ (fm.find (l1.cell_by_name ("A").second) != fm.end (), true);
|
||||
EXPECT_EQ (l2.cell_name (fm.find (l1.cell_by_name ("A").second)->second), "A$1");
|
||||
EXPECT_EQ (fm.find (l1.cell_by_name ("B").second) != fm.end (), true);
|
||||
EXPECT_EQ (l2.cell_name (fm.find (l1.cell_by_name ("B").second)->second), "B$1");
|
||||
EXPECT_EQ (fm.find (l1.cell_by_name ("C").second) != fm.end (), true);
|
||||
EXPECT_EQ (l2.cell_name (fm.find (l1.cell_by_name ("C").second)->second), "C$1");
|
||||
}
|
||||
|
||||
// Tests merge_layout with a mapped tree (by name)
|
||||
TEST(4)
|
||||
{
|
||||
db::Layout l1;
|
||||
{
|
||||
std::string fn (ut::testsrc ());
|
||||
fn += "/testdata/algo/layout_utils_l1.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (l1);
|
||||
}
|
||||
|
||||
db::Layout l2;
|
||||
{
|
||||
std::string fn (ut::testsrc ());
|
||||
fn += "/testdata/algo/layout_utils_l2.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (l2);
|
||||
}
|
||||
|
||||
unsigned int li1 = find_layer (l1, 1, 0);
|
||||
unsigned int li2 = find_layer (l1, 2, 0);
|
||||
unsigned int li3 = find_layer (l1, 3, 0);
|
||||
|
||||
db::LayerMapping lm;
|
||||
lm.map (li1, l2.insert_layer (db::LayerProperties (11, 0)));
|
||||
lm.map (li2, l2.insert_layer (db::LayerProperties (12, 0)));
|
||||
lm.map (li3, l2.insert_layer (db::LayerProperties (13, 0)));
|
||||
|
||||
db::CellMapping cm;
|
||||
std::vector<db::cell_index_type> src;
|
||||
src.push_back (l1.cell_by_name ("TOP").second);
|
||||
cm.create_from_names_full (l2, l2.cell_by_name ("TOP").second, l1, src.front ());
|
||||
std::map<db::cell_index_type, db::cell_index_type> fm;
|
||||
db::merge_layouts (l2, l1, db::ICplxTrans (), src, cm.table (), lm.table (), &fm);
|
||||
|
||||
CHECKPOINT();
|
||||
compare_layouts (l2, ut::testsrc () + "/testdata/algo/layout_utils_au4.gds");
|
||||
|
||||
EXPECT_EQ (fm.find (l1.cell_by_name ("TOP").second) != fm.end (), true);
|
||||
EXPECT_EQ (l2.cell_name (fm.find (l1.cell_by_name ("TOP").second)->second), "TOP");
|
||||
EXPECT_EQ (fm.find (l1.cell_by_name ("A").second) != fm.end (), true);
|
||||
EXPECT_EQ (l2.cell_name (fm.find (l1.cell_by_name ("A").second)->second), "A");
|
||||
EXPECT_EQ (fm.find (l1.cell_by_name ("B").second) != fm.end (), true);
|
||||
EXPECT_EQ (l2.cell_name (fm.find (l1.cell_by_name ("B").second)->second), "B");
|
||||
EXPECT_EQ (fm.find (l1.cell_by_name ("C").second) != fm.end (), true);
|
||||
EXPECT_EQ (l2.cell_name (fm.find (l1.cell_by_name ("C").second)->second), "C");
|
||||
}
|
||||
|
||||
// Tests merge_layout with a equivalence-mapped tree
|
||||
TEST(5)
|
||||
{
|
||||
db::Layout l1;
|
||||
{
|
||||
std::string fn (ut::testsrc ());
|
||||
fn += "/testdata/algo/layout_utils_l1.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (l1);
|
||||
}
|
||||
|
||||
db::Layout l2;
|
||||
{
|
||||
std::string fn (ut::testsrc ());
|
||||
fn += "/testdata/algo/layout_utils_l2.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (l2);
|
||||
}
|
||||
|
||||
unsigned int li1 = find_layer (l1, 1, 0);
|
||||
unsigned int li2 = find_layer (l1, 2, 0);
|
||||
unsigned int li3 = find_layer (l1, 3, 0);
|
||||
|
||||
db::LayerMapping lm;
|
||||
lm.map (li1, l2.insert_layer (db::LayerProperties (11, 0)));
|
||||
lm.map (li2, l2.insert_layer (db::LayerProperties (12, 0)));
|
||||
lm.map (li3, l2.insert_layer (db::LayerProperties (13, 0)));
|
||||
|
||||
db::CellMapping cm;
|
||||
std::vector<db::cell_index_type> src;
|
||||
src.push_back (l1.cell_by_name ("TOP").second);
|
||||
cm.create_from_geometry_full (l2, l2.cell_by_name ("TOP").second, l1, src.front ());
|
||||
std::map<db::cell_index_type, db::cell_index_type> fm;
|
||||
db::merge_layouts (l2, l1, db::ICplxTrans (), src, cm.table (), lm.table (), &fm);
|
||||
|
||||
CHECKPOINT();
|
||||
compare_layouts (l2, ut::testsrc () + "/testdata/algo/layout_utils_au5.gds");
|
||||
|
||||
EXPECT_EQ (fm.find (l1.cell_by_name ("TOP").second) != fm.end (), true);
|
||||
EXPECT_EQ (l2.cell_name (fm.find (l1.cell_by_name ("TOP").second)->second), "TOP");
|
||||
EXPECT_EQ (fm.find (l1.cell_by_name ("A").second) != fm.end (), true);
|
||||
EXPECT_EQ (l2.cell_name (fm.find (l1.cell_by_name ("A").second)->second), "A");
|
||||
EXPECT_EQ (fm.find (l1.cell_by_name ("B").second) != fm.end (), true);
|
||||
EXPECT_EQ (l2.cell_name (fm.find (l1.cell_by_name ("B").second)->second), "B");
|
||||
EXPECT_EQ (fm.find (l1.cell_by_name ("C").second) != fm.end (), true);
|
||||
EXPECT_EQ (l2.cell_name (fm.find (l1.cell_by_name ("C").second)->second), "C$1");
|
||||
}
|
||||
|
||||
// Tests merge_layout with dropping of cell B
|
||||
TEST(6)
|
||||
{
|
||||
db::Layout l1;
|
||||
{
|
||||
std::string fn (ut::testsrc ());
|
||||
fn += "/testdata/algo/layout_utils_l1.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (l1);
|
||||
}
|
||||
|
||||
db::Layout l2;
|
||||
{
|
||||
std::string fn (ut::testsrc ());
|
||||
fn += "/testdata/algo/layout_utils_l2.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (l2);
|
||||
}
|
||||
|
||||
unsigned int li1 = find_layer (l1, 1, 0);
|
||||
unsigned int li2 = find_layer (l1, 2, 0);
|
||||
unsigned int li3 = find_layer (l1, 3, 0);
|
||||
|
||||
db::LayerMapping lm;
|
||||
lm.map (li1, l2.insert_layer (db::LayerProperties (11, 0)));
|
||||
lm.map (li2, l2.insert_layer (db::LayerProperties (12, 0)));
|
||||
lm.map (li3, l2.insert_layer (db::LayerProperties (13, 0)));
|
||||
|
||||
db::CellMapping cm;
|
||||
// Drop cell B
|
||||
cm.map (l1.cell_by_name ("B").second, db::DropCell);
|
||||
cm.map (l1.cell_by_name ("TOP").second, l2.cell_by_name ("TOP").second);
|
||||
|
||||
std::map<db::cell_index_type, db::cell_index_type> fm;
|
||||
std::vector<db::cell_index_type> src;
|
||||
src.push_back (l1.cell_by_name ("TOP").second);
|
||||
db::merge_layouts (l2, l1, db::ICplxTrans (), src, cm.table (), lm.table (), &fm);
|
||||
|
||||
CHECKPOINT();
|
||||
compare_layouts (l2, ut::testsrc () + "/testdata/algo/layout_utils_au6.gds");
|
||||
|
||||
EXPECT_EQ (fm.find (l1.cell_by_name ("TOP").second) != fm.end (), true);
|
||||
EXPECT_EQ (l2.cell_name (fm.find (l1.cell_by_name ("TOP").second)->second), "TOP");
|
||||
EXPECT_EQ (fm.find (l1.cell_by_name ("A").second) != fm.end (), true);
|
||||
EXPECT_EQ (l2.cell_name (fm.find (l1.cell_by_name ("A").second)->second), "A$1");
|
||||
EXPECT_EQ (fm.find (l1.cell_by_name ("B").second) != fm.end (), false);
|
||||
EXPECT_EQ (fm.find (l1.cell_by_name ("C").second) != fm.end (), true);
|
||||
EXPECT_EQ (l2.cell_name (fm.find (l1.cell_by_name ("C").second)->second), "C$1");
|
||||
}
|
||||
|
||||
// Tests merge_layout with transformation
|
||||
TEST(7)
|
||||
{
|
||||
db::Layout l1;
|
||||
{
|
||||
std::string fn (ut::testsrc ());
|
||||
fn += "/testdata/algo/layout_utils_l1.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (l1);
|
||||
}
|
||||
|
||||
db::Layout l2;
|
||||
{
|
||||
std::string fn (ut::testsrc ());
|
||||
fn += "/testdata/algo/layout_utils_l3.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (l2);
|
||||
}
|
||||
|
||||
unsigned int li1 = find_layer (l1, 1, 0);
|
||||
unsigned int li2 = find_layer (l1, 2, 0);
|
||||
unsigned int li3 = find_layer (l1, 3, 0);
|
||||
|
||||
db::LayerMapping lm;
|
||||
lm.map (li1, l2.insert_layer (db::LayerProperties (11, 0)));
|
||||
lm.map (li2, l2.insert_layer (db::LayerProperties (12, 0)));
|
||||
lm.map (li3, l2.insert_layer (db::LayerProperties (13, 0)));
|
||||
|
||||
db::Layout l2copy = l2;
|
||||
|
||||
db::CellMapping cm;
|
||||
cm.map (l1.cell_by_name ("TOP").second, l2.cell_by_name ("TOP").second);
|
||||
|
||||
std::map<db::cell_index_type, db::cell_index_type> fm;
|
||||
std::vector<db::cell_index_type> src;
|
||||
src.push_back (l1.cell_by_name ("TOP").second);
|
||||
db::merge_layouts (l2, l1, db::ICplxTrans (4.0), src, cm.table (), lm.table (), &fm);
|
||||
|
||||
CHECKPOINT();
|
||||
compare_layouts (l2, ut::testsrc () + "/testdata/algo/layout_utils_au7.gds");
|
||||
|
||||
EXPECT_EQ (fm.find (l1.cell_by_name ("TOP").second) != fm.end (), true);
|
||||
EXPECT_EQ (l2.cell_name (fm.find (l1.cell_by_name ("TOP").second)->second), "TOP");
|
||||
EXPECT_EQ (fm.find (l1.cell_by_name ("A").second) != fm.end (), true);
|
||||
EXPECT_EQ (l2.cell_name (fm.find (l1.cell_by_name ("A").second)->second), "A$1");
|
||||
EXPECT_EQ (fm.find (l1.cell_by_name ("B").second) != fm.end (), true);
|
||||
EXPECT_EQ (l2.cell_name (fm.find (l1.cell_by_name ("B").second)->second), "B$1");
|
||||
EXPECT_EQ (fm.find (l1.cell_by_name ("C").second) != fm.end (), true);
|
||||
EXPECT_EQ (l2.cell_name (fm.find (l1.cell_by_name ("C").second)->second), "C");
|
||||
|
||||
// Once with final_mapping = 0 ...
|
||||
db::merge_layouts (l2copy, l1, db::ICplxTrans (4.0), src, cm.table (), lm.table ());
|
||||
|
||||
CHECKPOINT();
|
||||
compare_layouts (l2copy, ut::testsrc () + "/testdata/algo/layout_utils_au7.gds");
|
||||
}
|
||||
|
||||
// Tests copy_shapes with no specific mapping (flattening)
|
||||
TEST(12)
|
||||
{
|
||||
db::Layout l1;
|
||||
{
|
||||
std::string fn (ut::testsrc ());
|
||||
fn += "/testdata/algo/layout_utils_l1.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (l1);
|
||||
}
|
||||
|
||||
db::Layout l2;
|
||||
{
|
||||
std::string fn (ut::testsrc ());
|
||||
fn += "/testdata/algo/layout_utils_l2.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (l2);
|
||||
}
|
||||
|
||||
unsigned int li1 = find_layer (l1, 1, 0);
|
||||
unsigned int li2 = find_layer (l1, 2, 0);
|
||||
unsigned int li3 = find_layer (l1, 3, 0);
|
||||
|
||||
db::LayerMapping lm;
|
||||
lm.map (li1, l2.insert_layer (db::LayerProperties (11, 0)));
|
||||
lm.map (li2, l2.insert_layer (db::LayerProperties (12, 0)));
|
||||
lm.map (li3, l2.insert_layer (db::LayerProperties (13, 0)));
|
||||
|
||||
db::CellMapping cm;
|
||||
std::map<db::cell_index_type, db::cell_index_type> fm;
|
||||
std::vector<db::cell_index_type> src;
|
||||
src.push_back (l1.cell_by_name ("TOP").second);
|
||||
cm.map (src.front (), l2.cell_by_name ("TOP").second);
|
||||
db::copy_shapes (l2, l1, db::ICplxTrans (), src, cm.table (), lm.table ());
|
||||
|
||||
CHECKPOINT();
|
||||
compare_layouts (l2, ut::testsrc () + "/testdata/algo/layout_utils_au12.gds");
|
||||
}
|
||||
|
||||
// Tests copy_shapes with full name mapping
|
||||
TEST(13)
|
||||
{
|
||||
db::Layout l1;
|
||||
{
|
||||
std::string fn (ut::testsrc ());
|
||||
fn += "/testdata/algo/layout_utils_l1.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (l1);
|
||||
}
|
||||
|
||||
db::Layout l2;
|
||||
{
|
||||
std::string fn (ut::testsrc ());
|
||||
fn += "/testdata/algo/layout_utils_l2.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (l2);
|
||||
}
|
||||
|
||||
unsigned int li1 = find_layer (l1, 1, 0);
|
||||
unsigned int li2 = find_layer (l1, 2, 0);
|
||||
unsigned int li3 = find_layer (l1, 3, 0);
|
||||
|
||||
db::LayerMapping lm;
|
||||
lm.map (li1, l2.insert_layer (db::LayerProperties (11, 0)));
|
||||
lm.map (li2, l2.insert_layer (db::LayerProperties (12, 0)));
|
||||
lm.map (li3, l2.insert_layer (db::LayerProperties (13, 0)));
|
||||
|
||||
db::CellMapping cm;
|
||||
std::vector<db::cell_index_type> src;
|
||||
src.push_back (l1.cell_by_name ("TOP").second);
|
||||
cm.create_from_names_full (l2, l2.cell_by_name ("TOP").second, l1, src.front ());
|
||||
db::copy_shapes (l2, l1, db::ICplxTrans (), src, cm.table (), lm.table ());
|
||||
|
||||
CHECKPOINT();
|
||||
compare_layouts (l2, ut::testsrc () + "/testdata/algo/layout_utils_au13.gds");
|
||||
}
|
||||
|
||||
// Tests copy_shapes with geo mapping
|
||||
TEST(14)
|
||||
{
|
||||
db::Layout l1;
|
||||
{
|
||||
std::string fn (ut::testsrc ());
|
||||
fn += "/testdata/algo/layout_utils_l1.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (l1);
|
||||
}
|
||||
|
||||
db::Layout l2;
|
||||
{
|
||||
std::string fn (ut::testsrc ());
|
||||
fn += "/testdata/algo/layout_utils_l2.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (l2);
|
||||
}
|
||||
|
||||
unsigned int li1 = find_layer (l1, 1, 0);
|
||||
unsigned int li2 = find_layer (l1, 2, 0);
|
||||
unsigned int li3 = find_layer (l1, 3, 0);
|
||||
|
||||
db::LayerMapping lm;
|
||||
lm.map (li1, l2.insert_layer (db::LayerProperties (11, 0)));
|
||||
lm.map (li2, l2.insert_layer (db::LayerProperties (12, 0)));
|
||||
lm.map (li3, l2.insert_layer (db::LayerProperties (13, 0)));
|
||||
|
||||
db::CellMapping cm;
|
||||
std::vector<db::cell_index_type> src;
|
||||
src.push_back (l1.cell_by_name ("TOP").second);
|
||||
cm.create_from_geometry_full (l2, l2.cell_by_name ("TOP").second, l1, src.front ());
|
||||
db::copy_shapes (l2, l1, db::ICplxTrans (), src, cm.table (), lm.table ());
|
||||
|
||||
CHECKPOINT();
|
||||
compare_layouts (l2, ut::testsrc () + "/testdata/algo/layout_utils_au14.gds");
|
||||
}
|
||||
|
||||
// Tests copy_shapes with flattening minus one cell
|
||||
TEST(15)
|
||||
{
|
||||
db::Layout l1;
|
||||
{
|
||||
std::string fn (ut::testsrc ());
|
||||
fn += "/testdata/algo/layout_utils_l1.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (l1);
|
||||
}
|
||||
|
||||
db::Layout l2;
|
||||
{
|
||||
std::string fn (ut::testsrc ());
|
||||
fn += "/testdata/algo/layout_utils_l2.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (l2);
|
||||
}
|
||||
|
||||
unsigned int li1 = find_layer (l1, 1, 0);
|
||||
unsigned int li2 = find_layer (l1, 2, 0);
|
||||
unsigned int li3 = find_layer (l1, 3, 0);
|
||||
|
||||
db::LayerMapping lm;
|
||||
lm.map (li1, l2.insert_layer (db::LayerProperties (11, 0)));
|
||||
lm.map (li2, l2.insert_layer (db::LayerProperties (12, 0)));
|
||||
lm.map (li3, l2.insert_layer (db::LayerProperties (13, 0)));
|
||||
|
||||
db::CellMapping cm;
|
||||
std::vector<db::cell_index_type> src;
|
||||
src.push_back (l1.cell_by_name ("TOP").second);
|
||||
cm.map (src.front (), l2.cell_by_name ("TOP").second);
|
||||
cm.map (l1.cell_by_name ("B").second, db::DropCell);
|
||||
db::copy_shapes (l2, l1, db::ICplxTrans (), src, cm.table (), lm.table ());
|
||||
|
||||
CHECKPOINT();
|
||||
compare_layouts (l2, ut::testsrc () + "/testdata/algo/layout_utils_au15.gds");
|
||||
}
|
||||
|
||||
// Tests copy_shapes/move_shapes with no specific mapping (flattening)
|
||||
TEST(16)
|
||||
{
|
||||
db::Layout l1;
|
||||
{
|
||||
std::string fn (ut::testsrc ());
|
||||
fn += "/testdata/algo/layout_utils_l1.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (l1);
|
||||
}
|
||||
|
||||
db::Layout l2;
|
||||
{
|
||||
std::string fn (ut::testsrc ());
|
||||
fn += "/testdata/algo/layout_utils_l3.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (l2);
|
||||
}
|
||||
|
||||
unsigned int li1 = find_layer (l1, 1, 0);
|
||||
unsigned int li2 = find_layer (l1, 2, 0);
|
||||
unsigned int li3 = find_layer (l1, 3, 0);
|
||||
|
||||
db::LayerMapping lm;
|
||||
lm.map (li1, l2.insert_layer (db::LayerProperties (11, 0)));
|
||||
lm.map (li2, l2.insert_layer (db::LayerProperties (12, 0)));
|
||||
lm.map (li3, l2.insert_layer (db::LayerProperties (13, 0)));
|
||||
|
||||
db::Layout l2copy = l2;
|
||||
|
||||
db::CellMapping cm;
|
||||
std::map<db::cell_index_type, db::cell_index_type> fm;
|
||||
std::vector<db::cell_index_type> src;
|
||||
src.push_back (l1.cell_by_name ("TOP").second);
|
||||
cm.map (src.front (), l2.cell_by_name ("TOP").second);
|
||||
db::copy_shapes (l2, l1, db::ICplxTrans (4.0), src, cm.table (), lm.table ());
|
||||
|
||||
CHECKPOINT();
|
||||
compare_layouts (l2, ut::testsrc () + "/testdata/algo/layout_utils_au16.gds");
|
||||
|
||||
// ... and one test for move:
|
||||
db::move_shapes (l2copy, l1, db::ICplxTrans (4.0), src, cm.table (), lm.table ());
|
||||
|
||||
CHECKPOINT();
|
||||
compare_layouts (l2copy, ut::testsrc () + "/testdata/algo/layout_utils_au16.gds");
|
||||
compare_layouts (l1, ut::testsrc () + "/testdata/algo/layout_utils_au16b.gds");
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -31,6 +31,7 @@ SOURCES = \
|
|||
dbLayerMapping.cc \
|
||||
dbLayout.cc \
|
||||
dbLayoutDiff.cc \
|
||||
dbLayoutUtils.cc \
|
||||
dbLayoutQuery.cc \
|
||||
dbLibraries.cc \
|
||||
dbMatrix.cc \
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -28,7 +28,12 @@ def mapping_to_s(ly1, ly2, cm)
|
|||
ly1.each_cell_top_down do |c|
|
||||
s = ly1.cell(c).name
|
||||
if cm.has_mapping?(c)
|
||||
s += "=>" + ly2.cell(cm.cell_mapping(c)).name
|
||||
t = cm.cell_mapping(c)
|
||||
if t == RBA::CellMapping::DropCell
|
||||
s += "=>(0)"
|
||||
else
|
||||
s += "=>" + ly2.cell(t).name
|
||||
end
|
||||
end
|
||||
r == "" || (r += ";")
|
||||
r += s
|
||||
|
|
@ -50,6 +55,8 @@ class DBCellMapping_TestClass < TestBase
|
|||
assert_equal(mp.has_mapping?(1), false)
|
||||
mp.map(1, 2)
|
||||
assert_equal(mp.cell_mapping(1), 2)
|
||||
mp.map(1, 3)
|
||||
assert_equal(mp.cell_mapping(1), 3)
|
||||
|
||||
ly = RBA::Layout::new
|
||||
|
||||
|
|
@ -170,6 +177,11 @@ class DBCellMapping_TestClass < TestBase
|
|||
assert_equal(mapping_to_s(ly2, ly1dup, mp), "c0;c2=>c2;c1=>c1;c3=>c3$1")
|
||||
assert_equal(nc.inspect, "[3]")
|
||||
|
||||
mp.clear
|
||||
mp.from_geometry(ly1, top1, ly2, top2)
|
||||
mp.map(ci2, RBA::CellMapping::DropCell)
|
||||
assert_equal(mapping_to_s(ly2, ly1, mp), "c0;c2=>(0);c1=>c1;c3")
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@ class DBLayerMapping_TestClass < TestBase
|
|||
assert_equal(mp.has_mapping?(1), false)
|
||||
mp.map(1, 2)
|
||||
assert_equal(mp.layer_mapping(1), 2)
|
||||
mp.map(1, 3)
|
||||
assert_equal(mp.layer_mapping(1), 3)
|
||||
|
||||
ly1 = RBA::Layout::new
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue