diff --git a/src/db/db/dbLayout.cc b/src/db/db/dbLayout.cc index 247fb5c58..aa6d27992 100644 --- a/src/db/db/dbLayout.cc +++ b/src/db/db/dbLayout.cc @@ -2564,6 +2564,8 @@ Layout::get_context_info (cell_index_type cell_index, std::vector bool Layout::get_context_info (cell_index_type cell_index, LayoutOrCellContextInfo &info) const { + bool any_meta = false; + auto cmi = m_meta_info_by_cell.find (cell_index); if (cmi != m_meta_info_by_cell.end ()) { for (auto i = cmi->second.begin (); i != cmi->second.end (); ++i) { @@ -2571,6 +2573,7 @@ Layout::get_context_info (cell_index_type cell_index, LayoutOrCellContextInfo &i std::pair &mi = info.meta_info [m_meta_info_names [i->first] ]; mi.first = i->second.value; mi.second = i->second.description; + any_meta = true; } } } @@ -2590,7 +2593,7 @@ Layout::get_context_info (cell_index_type cell_index, LayoutOrCellContextInfo &i const db::Library *lib = db::LibraryManager::instance ().lib (lib_proxy->lib_id ()); if (! lib) { - return false; // abort + return any_meta; // abort } else { // one level of library indirection diff --git a/src/plugins/streamers/oasis/db_plugin/dbOASISReader.cc b/src/plugins/streamers/oasis/db_plugin/dbOASISReader.cc index 613e50a82..f30a9ea6e 100644 --- a/src/plugins/streamers/oasis/db_plugin/dbOASISReader.cc +++ b/src/plugins/streamers/oasis/db_plugin/dbOASISReader.cc @@ -36,8 +36,6 @@ namespace db { -// --------------------------------------------------------------- - // --------------------------------------------------------------- // OASISReader @@ -680,6 +678,8 @@ OASISReader::do_read (db::Layout &layout) m_instances_with_props.clear (); db::PropertiesRepository::properties_set layout_properties; + bool has_context = false; + std::vector context_strings; mark_start_table (); @@ -1000,7 +1000,16 @@ OASISReader::do_read (db::Layout &layout) read_properties (layout.properties_repository ()); } - store_last_properties (layout.properties_repository (), layout_properties, true); + if (! mm_last_property_is_sprop.get () && mm_last_property_name.get () == m_klayout_context_property_name_id) { + has_context = true; + context_strings.reserve (mm_last_value_list.get ().size ()); + for (std::vector::const_iterator v = mm_last_value_list.get ().begin (); v != mm_last_value_list.get ().end (); ++v) { + context_strings.push_back (v->to_string ()); + } + } else { + // store cell properties + store_last_properties (layout.properties_repository (), layout_properties, true); + } mark_start_table (); @@ -1103,6 +1112,12 @@ OASISReader::do_read (db::Layout &layout) layout_properties.clear (); } + if (has_context) { + // Restore layout meta info + LayoutOrCellContextInfo info = LayoutOrCellContextInfo::deserialize (context_strings.begin (), context_strings.end ()); + layout.fill_meta_info_from_context (info); + } + size_t pt = m_stream.pos (); if (table_offsets_at_end) { @@ -3246,7 +3261,7 @@ OASISReader::do_read_cell (db::cell_index_type cell_index, db::Layout &layout) context_strings.push_back (v->to_string ()); } } else { - // store cell properties + // store layout properties store_last_properties (layout.properties_repository (), cell_properties, true); } @@ -3344,10 +3359,12 @@ OASISReader::do_read_cell (db::cell_index_type cell_index, db::Layout &layout) m_instances_with_props.clear (); } - // Restore proxy cell (link to PCell or Library) + // Restore proxy cell (link to PCell or Library) and cell meta info if (has_context) { CommonReaderLayerMapping layer_mapping (this, &layout); - layout.recover_proxy_as (cell_index, context_strings.begin (), context_strings.end (), &layer_mapping); + LayoutOrCellContextInfo info = LayoutOrCellContextInfo::deserialize (context_strings.begin (), context_strings.end ()); + layout.recover_proxy_as (cell_index, info, &layer_mapping); + layout.fill_meta_info_from_context (cell_index, info); } m_cellname = ""; diff --git a/src/plugins/streamers/oasis/db_plugin/dbOASISWriter.cc b/src/plugins/streamers/oasis/db_plugin/dbOASISWriter.cc index 8e8da55ad..ec461199a 100644 --- a/src/plugins/streamers/oasis/db_plugin/dbOASISWriter.cc +++ b/src/plugins/streamers/oasis/db_plugin/dbOASISWriter.cc @@ -1303,6 +1303,24 @@ OASISWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::Save write_props (layout.prop_id ()); } + std::vector context_prop_strings; + + // write the global layout context information + + if (options.write_context_info () && layout.has_context_info () && layout.get_context_info (context_prop_strings)) { + + std::vector values; + values.reserve (context_prop_strings.size ()); + for (auto i = context_prop_strings.begin (); i != context_prop_strings.end (); ++i) { + values.push_back (tl::Variant (*i)); + } + + write_property_def (klayout_context_name, values, false); + + context_prop_strings.clear (); + + } + // build property name and value string tables { @@ -1360,25 +1378,25 @@ OASISWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::Save } - if (options.write_context_info ()) { + // if needed, emit property name required for the PCell or meta info context information - // emit property name required for the PCell context information - std::vector context_prop_strings; - for (std::vector::const_iterator cell = cells.begin (); cell != cells.end (); ++cell) { + if (options.write_context_info () && m_propnames.find (std::string (klayout_context_name)) == m_propnames.end ()) { - const db::Cell &cref (layout.cell (*cell)); - if (cref.is_proxy () && ! cref.is_top () && layout.get_context_info (*cell, context_prop_strings)) { - - if (m_propnames.insert (std::make_pair (std::string (klayout_context_name), m_propname_id)).second) { - begin_table (propnames_table_pos); - write_record_id (7); - write_nstring (klayout_context_name); - ++m_propname_id; - } - break; - - } + bool has_context = false; + { + LayoutOrCellContextInfo info; + has_context = layout.has_context_info () && layout.get_context_info (info); + } + for (auto cell = cells.begin (); cell != cells.end () && ! has_context; ++cell) { + LayoutOrCellContextInfo ci; + has_context = layout.has_context_info (*cell) && layout.get_context_info (*cell, ci); + } + if (has_context) { + m_propnames.insert (std::make_pair (std::string (klayout_context_name), ++m_propname_id)); + begin_table (propnames_table_pos); + write_record_id (7); + write_nstring (klayout_context_name); } } @@ -1445,27 +1463,36 @@ OASISWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::Save if (options.write_context_info ()) { - // emit property string id's required for the PCell context information + // emit property string id's required for the PCell and meta info context information std::vector context_prop_strings; + + if (layout.has_context_info () && layout.get_context_info (context_prop_strings)) { + + for (std::vector ::const_iterator c = context_prop_strings.begin (); c != context_prop_strings.end (); ++c) { + if (m_propstrings.insert (std::make_pair (*c, m_propstring_id)).second) { + begin_table (propstrings_table_pos); + write_record_id (9); + write_bstring (c->c_str ()); + ++m_propstring_id; + } + } + + } + for (std::vector::const_iterator cell = cells.begin (); cell != cells.end (); ++cell) { m_progress.set (mp_stream->pos ()); + context_prop_strings.clear (); - const db::Cell &cref (layout.cell (*cell)); - if (cref.is_proxy () && ! cref.is_top ()) { + if (layout.has_context_info (*cell) && layout.get_context_info (*cell, context_prop_strings)) { - context_prop_strings.clear (); - if (layout.get_context_info (*cell, context_prop_strings)) { - - for (std::vector ::const_iterator c = context_prop_strings.begin (); c != context_prop_strings.end (); ++c) { - if (m_propstrings.insert (std::make_pair (*c, m_propstring_id)).second) { - begin_table (propstrings_table_pos); - write_record_id (9); - write_bstring (c->c_str ()); - ++m_propstring_id; - } + for (std::vector ::const_iterator c = context_prop_strings.begin (); c != context_prop_strings.end (); ++c) { + if (m_propstrings.insert (std::make_pair (*c, m_propstring_id)).second) { + begin_table (propstrings_table_pos); + write_record_id (9); + write_bstring (c->c_str ()); + ++m_propstring_id; } - } } @@ -1601,8 +1628,6 @@ OASISWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::Save } - std::vector context_prop_strings; - for (std::vector::const_iterator cell = cells.begin (); cell != cells.end (); ++cell) { m_progress.set (mp_stream->pos ()); @@ -1630,7 +1655,7 @@ OASISWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::Save } // context information as property named KLAYOUT_CONTEXT - if (cref.is_proxy () && options.write_context_info ()) { + if (options.write_context_info () && layout.has_context_info (*cell)) { context_prop_strings.clear ();