Skip to content

Commit

Permalink
Fixed issue #1609 (Cell.read doesn't read LayoutMetaInfo)
Browse files Browse the repository at this point in the history
This also includes some more functions:
- Layout#merge_meta_info, Layout#copy_meta_info
- Layout#clear_all_meta_info
- Cell#merge_meta_info, Cell#copy_meta_info

In addition, meta info is merged when importing a layout from
another file (Layout/Import -> Other Layouts into current).
  • Loading branch information
Matthias Koefferlein committed Feb 5, 2024
1 parent 1e51cf6 commit 4eb1b3f
Show file tree
Hide file tree
Showing 6 changed files with 282 additions and 0 deletions.
41 changes: 41 additions & 0 deletions src/db/db/dbLayout.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1904,6 +1904,13 @@ Layout::clear_meta (db::cell_index_type ci)
m_meta_info_by_cell.erase (ci);
}

void
Layout::clear_all_meta ()
{
m_meta_info.clear ();
m_meta_info_by_cell.clear ();
}

void
Layout::add_meta_info (db::cell_index_type ci, meta_info_name_id_type name_id, const MetaInfo &i)
{
Expand Down Expand Up @@ -1945,6 +1952,40 @@ Layout::has_meta_info (db::cell_index_type ci, meta_info_name_id_type name_id) c
}
}

void
Layout::merge_meta_info (const db::Layout &other)
{
for (auto mi = other.begin_meta (); mi != other.end_meta (); ++mi) {
add_meta_info (other.meta_info_name (mi->first), mi->second);
}
}

void
Layout::merge_meta_info (db::cell_index_type into_cell, const db::Layout &other, db::cell_index_type other_cell)
{
auto mi_begin = other.begin_meta (other_cell);
auto mi_end = other.end_meta (other_cell);
for (auto mi = mi_begin; mi != mi_end; ++mi) {
add_meta_info (into_cell, other.meta_info_name (mi->first), mi->second);
}
}

void
Layout::merge_meta_info (const db::Layout &other, const db::CellMapping &cm)
{
for (auto i = cm.begin (); i != cm.end (); ++i) {
merge_meta_info (i->second, other, i->first);
}
}

void
Layout::copy_meta_info (const db::Layout &other, const db::CellMapping &cm)
{
for (auto i = cm.begin (); i != cm.end (); ++i) {
copy_meta_info (i->second, other, i->first);
}
}

void
Layout::swap_layers (unsigned int a, unsigned int b)
{
Expand Down
49 changes: 49 additions & 0 deletions src/db/db/dbLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -1993,6 +1993,11 @@ class DB_PUBLIC Layout
*/
void clear_meta (db::cell_index_type ci);

/**
* @brief Clears all meta information (cells and layout)
*/
void clear_all_meta ();

/**
* @brief Adds meta information for a given cell
* The given meta information object is to the meta information list for the given cell.
Expand Down Expand Up @@ -2021,6 +2026,50 @@ class DB_PUBLIC Layout
}
}

/**
* @brief Merges meta information from the other layout into self
* This applies to the layout-only meta information. Same keys get overwritten, new ones are added.
*/
void merge_meta_info (const db::Layout &other);

/**
* @brief Copies meta information from the other layout into self
* This applies to the layout-only meta information. All keys are replaced.
*/
void copy_meta_info (const db::Layout &other)
{
clear_meta ();
merge_meta_info (other);
}

/**
* @brief Merges meta information from the other cell into the target cell from sel.
* This applies to the cell-specific meta information. Same keys get overwritten, new ones are added.
*/
void merge_meta_info (db::cell_index_type into_cell, const db::Layout &other, db::cell_index_type other_cell);

/**
* @brief Copies meta information from the other cell into the target cell from sel.
* This applies to the cell-specific meta information. All keys are replaced.
*/
void copy_meta_info (db::cell_index_type into_cell, const db::Layout &other, db::cell_index_type other_cell)
{
clear_meta (into_cell);
merge_meta_info (into_cell, other, other_cell);
}

/**
* @brief Merges meta information from the other cell into the target cell from sel using the given cell mapping.
* The cell mapping specifies which meta information to merge from which cell into which cell.
*/
void merge_meta_info (const db::Layout &other, const db::CellMapping &cm);

/**
* @brief Copies meta information from the other cell into the target cell from sel using the given cell mapping.
* The cell mapping specifies which meta information to copy from which cell into which cell.
*/
void copy_meta_info (const db::Layout &other, const db::CellMapping &cm);

/**
* @brief Gets a value indicating whether a meta info with the given name is present for the given cell
*/
Expand Down
3 changes: 3 additions & 0 deletions src/db/db/dbLayoutUtils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,9 @@ merge_layouts (db::Layout &target,
const db::Cell &source_cell = source.cell (*c);
db::Cell &target_cell = target.cell (target_cell_index);

// merge meta info
target.merge_meta_info (target_cell_index, source, *c);

// NOTE: this implementation employs the safe but cumbersome "local transformation" feature.
// This means, all cells are transformed according to the given transformation and their
// references are transformed to account for that effect. This will lead to somewhat strange
Expand Down
32 changes: 32 additions & 0 deletions src/db/db/gsiDeclDbCell.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1004,6 +1004,22 @@ static void cell_add_meta_info (db::Cell *cell, const MetaInfo &mi)
}
}

static void cell_merge_meta_info (db::Cell *cell, const db::Cell *source)
{
if (! source || ! cell->layout () || ! source->layout ()) {
return;
}
cell->layout ()->merge_meta_info (cell->cell_index (), *source->layout (), source->cell_index ());
}

static void cell_copy_meta_info (db::Cell *cell, const db::Cell *source)
{
if (! source || ! cell->layout () || ! source->layout ()) {
return;
}
cell->layout ()->copy_meta_info (cell->cell_index (), *source->layout (), source->cell_index ());
}

static const tl::Variant &cell_meta_info_value (db::Cell *cell, const std::string &name)
{
if (! cell->layout ()) {
Expand Down Expand Up @@ -1755,6 +1771,7 @@ read_options (db::Cell *cell, const std::string &path, const db::LoadLayoutOptio
db::CellMapping cm;
std::vector<db::cell_index_type> new_cells = cm.create_single_mapping_full (*cell->layout (), cell->cell_index (), tmp, *tmp.begin_top_down ());
cell->move_tree_shapes (tmp.cell (*tmp.begin_top_down ()), cm);
cell->layout ()->merge_meta_info (tmp, cm);

return new_cells;
}
Expand Down Expand Up @@ -1834,6 +1851,21 @@ Class<db::Cell> decl_Cell ("db", "Cell",
"\n"
"This method has been introduced in version 0.28.8."
) +
gsi::method_ext ("merge_meta_info", &cell_merge_meta_info, gsi::arg ("other"),
"@brief Merges the meta information from the other cell into this cell\n"
"See \\LayoutMetaInfo for details about cells and meta information.\n"
"Existing keys in this cell will be overwritten by the respective values from the other cell.\n"
"New keys will be added.\n"
"\n"
"This method has been introduced in version 0.28.16."
) +
gsi::method_ext ("copy_meta_info", &cell_copy_meta_info, gsi::arg ("other"),
"@brief Copies the meta information from the other cell into this cell\n"
"See \\LayoutMetaInfo for details about cells and meta information.\n"
"The meta information from this cell will be replaced by the meta information from the other cell.\n"
"\n"
"This method has been introduced in version 0.28.16."
) +
gsi::method_ext ("clear_meta_info", &cell_clear_meta_info,
"@brief Clears the meta information of the cell\n"
"See \\LayoutMetaInfo for details about cells and meta information.\n"
Expand Down
42 changes: 42 additions & 0 deletions src/db/db/gsiDeclDbLayout.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1105,12 +1105,54 @@ Class<db::Layout> decl_Layout ("db", "Layout",
"\n"
"This method has been introduced in version 0.25."
) +
gsi::method ("merge_meta_info", static_cast<void (db::Layout::*) (const db::Layout &)> (&db::Layout::merge_meta_info), gsi::arg ("other"),
"@brief Merges the meta information from the other layout into this layout\n"
"See \\LayoutMetaInfo for details about cells and meta information.\n"
"Existing keys in this layout will be overwritten by the respective values from the other layout.\n"
"New keys will be added.\n"
"\n"
"This method has been introduced in version 0.28.16."
) +
gsi::method ("merge_meta_info", static_cast<void (db::Layout::*) (const db::Layout &, const db::CellMapping &cm)> (&db::Layout::merge_meta_info), gsi::arg ("other"), gsi::arg ("cm"),
"@brief Merges the meta information from the other layout into this layout for the cells given by the cell mapping\n"
"See \\LayoutMetaInfo for details about cells and meta information.\n"
"This method will use the source/target cell pairs from the cell mapping object and merge the meta information "
"from each source cell from the 'other' layout into the mapped cell inside self.\n"
"This method can be used with '\\copy_tree_shapes' and similar to copy meta information in addition to the shapes.\n"
"Existing cell-specific keys in this layout will be overwritten by the respective values from the other layout.\n"
"New keys will be added.\n"
"\n"
"This method has been introduced in version 0.28.16."
) +
gsi::method ("copy_meta_info", static_cast<void (db::Layout::*) (const db::Layout &)> (&db::Layout::copy_meta_info), gsi::arg ("other"),
"@brief Copies the meta information from the other layout into this layout\n"
"See \\LayoutMetaInfo for details about cells and meta information.\n"
"The meta information from this layout will be replaced by the meta information from the other layout.\n"
"\n"
"This method has been introduced in version 0.28.16."
) +
gsi::method ("copy_meta_info", static_cast<void (db::Layout::*) (const db::Layout &, const db::CellMapping &cm)> (&db::Layout::copy_meta_info), gsi::arg ("other"), gsi::arg ("cm"),
"@brief Copies the meta information from the other layout into this layout for the cells given by the cell mapping\n"
"See \\LayoutMetaInfo for details about cells and meta information.\n"
"This method will use the source/target cell pairs from the cell mapping object and merge the meta information "
"from each source cell from the 'other' layout into the mapped cell inside self.\n"
"This method can be used with '\\copy_tree_shapes' and similar to copy meta information in addition to the shapes.\n"
"All cell-specific keys in this layout will be replaced by the respective values from the other layout.\n"
"\n"
"This method has been introduced in version 0.28.16."
) +
gsi::method ("clear_meta_info", static_cast<void (db::Layout::*) ()> (&db::Layout::clear_meta),
"@brief Clears the meta information of the layout\n"
"See \\LayoutMetaInfo for details about layouts and meta information."
"\n"
"This method has been introduced in version 0.28.8."
) +
gsi::method ("clear_all_meta_info", static_cast<void (db::Layout::*) ()> (&db::Layout::clear_all_meta),
"@brief Clears all meta information of the layout (cell specific and global)\n"
"See \\LayoutMetaInfo for details about layouts and meta information."
"\n"
"This method has been introduced in version 0.28.16."
) +
gsi::method ("remove_meta_info", static_cast<void (db::Layout::*) (const std::string &name)> (&db::Layout::remove_meta_info), gsi::arg ("name"),
"@brief Removes meta information from the layout\n"
"See \\LayoutMetaInfo for details about layouts and meta information."
Expand Down
115 changes: 115 additions & 0 deletions testdata/ruby/dbLayoutTests2.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@

load("test_prologue.rb")

def mi2s(obj)
obj.each_meta_info.collect { |mi| mi.name + ":" + mi.value.to_s }.sort.join(";")
end

class DBLayoutTests2_TestClass < TestBase

# LayerInfo
Expand Down Expand Up @@ -1253,6 +1257,117 @@ def test_15

end

# Cell#read and meta info (issue #1609)
def test_16

tmp = File::join($ut_testtmp, "test16.gds")

ly1 = RBA::Layout::new
a = ly1.create_cell("A")
b = ly1.create_cell("B")
a.insert(RBA::DCellInstArray::new(b, RBA::Trans::new))

a.add_meta_info(RBA::LayoutMetaInfo::new("am1", 42.0, "", true))
a.add_meta_info(RBA::LayoutMetaInfo::new("am2", "u", "", true))
assert_equal(mi2s(a), "am1:42.0;am2:u")

b.add_meta_info(RBA::LayoutMetaInfo::new("bm1", 17, "", true))
assert_equal(mi2s(b), "bm1:17")

ly1.add_meta_info(RBA::LayoutMetaInfo::new("lm1", -2.0, "", true))
ly1.add_meta_info(RBA::LayoutMetaInfo::new("lm2", "v", "", true))
assert_equal(mi2s(ly1), "lm1:-2.0;lm2:v")

ly1.write(tmp)

ly2 = RBA::Layout::new
top = ly2.create_cell("TOP")
a = ly2.create_cell("A")
c = ly2.create_cell("C")
top.insert(RBA::DCellInstArray::new(a, RBA::Trans::new))
a.insert(RBA::DCellInstArray::new(c, RBA::Trans::new))

top.add_meta_info(RBA::LayoutMetaInfo::new("topm1", "abc"))
assert_equal(mi2s(top), "topm1:abc")
a.add_meta_info(RBA::LayoutMetaInfo::new("am1", "a number"))
a.add_meta_info(RBA::LayoutMetaInfo::new("am3", 0))
assert_equal(mi2s(a), "am1:a number;am3:0")
c.add_meta_info(RBA::LayoutMetaInfo::new("cm1", 3))
assert_equal(mi2s(c), "cm1:3")

ly2.add_meta_info(RBA::LayoutMetaInfo::new("lm1", 5))
assert_equal(mi2s(ly2), "lm1:5")

a.read(tmp)
# not modified
assert_equal(mi2s(ly2), "lm1:5")
# merged
assert_equal(mi2s(a), "am1:42.0;am2:u;am3:0")
# not modified
assert_equal(mi2s(c), "cm1:3")

b2 = ly2.cell("B")
# imported
assert_equal(mi2s(b2), "bm1:17")

puts "done."

end

# Layout, meta info diverse
def test_17

ly = RBA::Layout::new
a = ly.create_cell("A")
ly.add_meta_info(RBA::LayoutMetaInfo::new("lm1", 17))
a.add_meta_info(RBA::LayoutMetaInfo::new("am1", "u"))
assert_equal(mi2s(ly), "lm1:17")
assert_equal(mi2s(a), "am1:u")

ly.clear_all_meta_info
assert_equal(mi2s(ly), "")
assert_equal(mi2s(a), "")

ly2 = RBA::Layout::new
ly.add_meta_info(RBA::LayoutMetaInfo::new("lm1", 17))
ly2.add_meta_info(RBA::LayoutMetaInfo::new("lm2", 42))
assert_equal(mi2s(ly), "lm1:17")
ly.merge_meta_info(ly2)
assert_equal(mi2s(ly), "lm1:17;lm2:42")
ly.copy_meta_info(ly2)
assert_equal(mi2s(ly), "lm2:42")

a = ly.create_cell("A")
a.add_meta_info(RBA::LayoutMetaInfo::new("am1", "u"))
b = ly2.create_cell("B")
b.add_meta_info(RBA::LayoutMetaInfo::new("bm1", "v"))

assert_equal(mi2s(a), "am1:u")
a.merge_meta_info(b)
assert_equal(mi2s(a), "am1:u;bm1:v")
a.copy_meta_info(b)
assert_equal(mi2s(a), "bm1:v")

ly = RBA::Layout::new
ly2 = RBA::Layout::new

a = ly.create_cell("A")
a.add_meta_info(RBA::LayoutMetaInfo::new("am1", "u"))
ly2.create_cell("X")
b = ly2.create_cell("B")
b.add_meta_info(RBA::LayoutMetaInfo::new("bm1", "v"))

cm = RBA::CellMapping::new
cm.map(b.cell_index, a.cell_index)

assert_equal(mi2s(a), "am1:u")
ly.merge_meta_info(ly2, cm)
assert_equal(mi2s(a), "am1:u;bm1:v")
ly.copy_meta_info(ly2, cm)
assert_equal(mi2s(a), "bm1:v")

end

end

load("test_epilogue.rb")

0 comments on commit 4eb1b3f

Please sign in to comment.