mirror of https://github.com/KLayout/klayout.git
WIP: Variant building bug fixed. Needs testing.
This commit is contained in:
parent
990f01adec
commit
51676376e6
|
|
@ -295,9 +295,26 @@ CellMapping::create_from_names (const db::Layout &layout_a, db::cell_index_type
|
|||
}
|
||||
|
||||
std::vector<db::cell_index_type>
|
||||
CellMapping::create_missing_mapping (db::Layout &layout_a, db::cell_index_type /*cell_index_a*/, const db::Layout &layout_b, db::cell_index_type cell_index_b, const std::set<db::cell_index_type> *exclude_cells, const std::set<db::cell_index_type> *include_cells)
|
||||
CellMapping::create_missing_mapping (db::Layout &layout_a, db::cell_index_type cell_index_a, const db::Layout &layout_b, db::cell_index_type cell_index_b, const std::set<db::cell_index_type> *exclude_cells, const std::set<db::cell_index_type> *include_cells)
|
||||
{
|
||||
std::vector<db::cell_index_type> new_cells;
|
||||
do_create_missing_mapping (layout_a, cell_index_a, layout_b, cell_index_b, exclude_cells, include_cells, &new_cells, 0);
|
||||
return new_cells;
|
||||
}
|
||||
|
||||
std::vector<std::pair<db::cell_index_type, db::cell_index_type> >
|
||||
CellMapping::create_missing_mapping2 (db::Layout &layout_a, db::cell_index_type cell_index_a, const db::Layout &layout_b, db::cell_index_type cell_index_b, const std::set<db::cell_index_type> *exclude_cells, const std::set<db::cell_index_type> *include_cells)
|
||||
{
|
||||
std::vector<std::pair<db::cell_index_type, db::cell_index_type> > cell_pairs;
|
||||
do_create_missing_mapping (layout_a, cell_index_a, layout_b, cell_index_b, exclude_cells, include_cells, 0, &cell_pairs);
|
||||
return cell_pairs;
|
||||
}
|
||||
|
||||
void
|
||||
CellMapping::do_create_missing_mapping (db::Layout &layout_a, db::cell_index_type /*cell_index_a*/, const db::Layout &layout_b, db::cell_index_type cell_index_b, const std::set<db::cell_index_type> *exclude_cells, const std::set<db::cell_index_type> *include_cells, std::vector<db::cell_index_type> *new_cells_ptr, std::vector<std::pair<db::cell_index_type, db::cell_index_type> > *mapped_pairs)
|
||||
{
|
||||
std::vector<db::cell_index_type> new_cells_int;
|
||||
std::vector<db::cell_index_type> &new_cells = *(new_cells_ptr ? new_cells_ptr : &new_cells_int);
|
||||
std::vector<db::cell_index_type> new_cells_b;
|
||||
|
||||
std::set<db::cell_index_type> called_b;
|
||||
|
|
@ -308,10 +325,17 @@ CellMapping::create_missing_mapping (db::Layout &layout_a, db::cell_index_type /
|
|||
if (m_b2a_mapping.find (*b) == m_b2a_mapping.end ()
|
||||
&& (! exclude_cells || exclude_cells->find (*b) == exclude_cells->end ())
|
||||
&& (! include_cells || include_cells->find (*b) != include_cells->end ())) {
|
||||
|
||||
db::cell_index_type new_cell = layout_a.add_cell (layout_b.cell_name (*b));
|
||||
new_cells.push_back (new_cell);
|
||||
new_cells_b.push_back (*b);
|
||||
|
||||
if (mapped_pairs) {
|
||||
mapped_pairs->push_back (std::make_pair (*b, new_cell));
|
||||
}
|
||||
|
||||
map (*b, new_cell);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -355,8 +379,6 @@ CellMapping::create_missing_mapping (db::Layout &layout_a, db::cell_index_type /
|
|||
layout_a.end_changes ();
|
||||
|
||||
}
|
||||
|
||||
return new_cells;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -197,6 +197,14 @@ public:
|
|||
*/
|
||||
std::vector<db::cell_index_type> create_missing_mapping (db::Layout &layout_a, db::cell_index_type cell_index_a, const db::Layout &layout_b, db::cell_index_type cell_index_b, const std::set<db::cell_index_type> *exclude_cells = 0, const std::set<db::cell_index_type> *include_cells = 0);
|
||||
|
||||
/**
|
||||
* @brief Like create_missing_mapping, but returns the newly mapped pairs
|
||||
*
|
||||
* The first cell index of the pair is the old cell in layout_a, the second cell index
|
||||
* is the new cell in layout_b.
|
||||
*/
|
||||
std::vector<std::pair<db::cell_index_type, db::cell_index_type> > create_missing_mapping2 (db::Layout &layout_a, db::cell_index_type cell_index_a, const db::Layout &layout_b, db::cell_index_type cell_index_b, const std::set<db::cell_index_type> *exclude_cells = 0, const std::set<db::cell_index_type> *include_cells = 0);
|
||||
|
||||
private:
|
||||
void extract_unique (std::map <db::cell_index_type, std::vector<db::cell_index_type> >::const_iterator cand,
|
||||
std::map<db::cell_index_type, db::cell_index_type> &unique_mapping,
|
||||
|
|
@ -205,6 +213,8 @@ private:
|
|||
void dump_mapping (const std::map <db::cell_index_type, std::vector<db::cell_index_type> > &candidates,
|
||||
const db::Layout &layout_a, const db::Layout &layout_b);
|
||||
|
||||
void do_create_missing_mapping (db::Layout &layout_a, db::cell_index_type cell_index_a, const db::Layout &layout_b, db::cell_index_type cell_index_b, const std::set<db::cell_index_type> *exclude_cells, const std::set<db::cell_index_type> *include_cells, std::vector<db::cell_index_type> *new_cells, std::vector<std::pair<db::cell_index_type, db::cell_index_type> > *mapped_pairs);
|
||||
|
||||
std::map <db::cell_index_type, db::cell_index_type> m_b2a_mapping;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -355,7 +355,7 @@ VariantsCollectorBase::product (const std::map<db::ICplxTrans, size_t> &v1, cons
|
|||
}
|
||||
|
||||
void
|
||||
VariantsCollectorBase::copy_shapes (db::Layout &layout, db::cell_index_type ci_to, db::cell_index_type ci_from) const
|
||||
VariantsCollectorBase::copy_shapes (db::Layout &layout, db::cell_index_type ci_to, db::cell_index_type ci_from)
|
||||
{
|
||||
db::Cell &to = layout.cell (ci_to);
|
||||
const db::Cell &from = layout.cell (ci_from);
|
||||
|
|
|
|||
|
|
@ -225,6 +225,11 @@ public:
|
|||
*/
|
||||
bool has_variants () const;
|
||||
|
||||
/**
|
||||
* @brief Utility: copy all shapes from one cell to another
|
||||
*/
|
||||
static void copy_shapes (db::Layout &layout, db::cell_index_type ci_to, db::cell_index_type ci_from);
|
||||
|
||||
private:
|
||||
std::map<db::cell_index_type, std::map<db::ICplxTrans, size_t> > m_variants;
|
||||
const TransformationReducer *mp_red;
|
||||
|
|
@ -233,7 +238,6 @@ private:
|
|||
void add_variant_non_tl_invariant (std::map<db::ICplxTrans, size_t> &variants, const db::CellInstArray &inst) const;
|
||||
void add_variant_tl_invariant (std::map<db::ICplxTrans, size_t> &variants, const db::CellInstArray &inst) const;
|
||||
void product (const std::map<db::ICplxTrans, size_t> &v1, const std::map<db::ICplxTrans, size_t> &v2, std::map<db::ICplxTrans, size_t> &prod) const;
|
||||
void copy_shapes (db::Layout &layout, db::cell_index_type ci_to, db::cell_index_type ci_from) const;
|
||||
void create_var_instances (db::Cell &in_cell, std::vector<db::CellInstArrayWithProperties> &inst, const db::ICplxTrans &for_var, const std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > &var_table, bool tl_invariant) const;
|
||||
void create_var_instances_non_tl_invariant (db::Cell &in_cell, std::vector<db::CellInstArrayWithProperties> &inst, const db::ICplxTrans &for_var, const std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > &var_table) const;
|
||||
void create_var_instances_tl_invariant (db::Cell &in_cell, std::vector<db::CellInstArrayWithProperties> &inst, const db::ICplxTrans &for_var, const std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > &var_table) const;
|
||||
|
|
|
|||
|
|
@ -889,7 +889,7 @@ DeepShapeStore::issue_variants (unsigned int layout_index, const std::map<db::ce
|
|||
const db::CellMapping &
|
||||
DeepShapeStore::cell_mapping_to_original (unsigned int layout_index, db::Layout *into_layout, db::cell_index_type into_cell, const std::set<db::cell_index_type> *excluded_cells, const std::set<db::cell_index_type> *included_cells)
|
||||
{
|
||||
const db::Layout *source_layout = &m_layouts [layout_index]->layout;
|
||||
db::Layout *source_layout = &m_layouts [layout_index]->layout;
|
||||
if (source_layout->begin_top_down () == source_layout->end_top_cells ()) {
|
||||
// empty source - nothing to do.
|
||||
static db::CellMapping cm;
|
||||
|
|
@ -910,6 +910,9 @@ DeepShapeStore::cell_mapping_to_original (unsigned int layout_index, db::Layout
|
|||
|
||||
cm = m_delivery_mapping_cache.insert (std::make_pair (key, db::CellMapping ())).first;
|
||||
|
||||
// collects the cell mappings we skip because they are variants (variant building or box variants)
|
||||
std::map<db::cell_index_type, std::pair<db::cell_index_type, std::set<db::Box> > > cm_skipped_variants;
|
||||
|
||||
if (into_layout == original_builder.source ().layout () && &into_layout->cell (into_cell) == original_builder.source ().top_cell ()) {
|
||||
|
||||
// This is the case of mapping back to the original. In this case we can use the information
|
||||
|
|
@ -922,15 +925,19 @@ DeepShapeStore::cell_mapping_to_original (unsigned int layout_index, db::Layout
|
|||
HierarchyBuilder::cell_map_type::const_iterator mm = m;
|
||||
++mm;
|
||||
bool skip = original_builder.is_variant (m->second); // skip variant cells
|
||||
while (mm != original_builder.end_cell_map () && mm->first.first == m->first.first && ! skip) {
|
||||
// we have cell variants and cannot simply map
|
||||
while (mm != original_builder.end_cell_map () && mm->first.first == m->first.first) {
|
||||
// we have cell (box) variants and cannot simply map
|
||||
++mm;
|
||||
++m;
|
||||
skip = true;
|
||||
}
|
||||
|
||||
if (! skip) {
|
||||
cm->second.map (m->second, m->first.first);
|
||||
} else {
|
||||
for (HierarchyBuilder::cell_map_type::const_iterator n = m; n != mm; ++n) {
|
||||
tl_assert (cm_skipped_variants.find (n->second) == cm_skipped_variants.end ());
|
||||
cm_skipped_variants [n->second] = n->first;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -948,7 +955,43 @@ DeepShapeStore::cell_mapping_to_original (unsigned int layout_index, db::Layout
|
|||
|
||||
// Add new cells for the variants and (possible) devices which are cells added during the device
|
||||
// extraction process
|
||||
cm->second.create_missing_mapping (*into_layout, into_cell, *source_layout, source_top, excluded_cells, included_cells);
|
||||
std::vector<std::pair<db::cell_index_type, db::cell_index_type> > new_pairs = cm->second.create_missing_mapping2 (*into_layout, into_cell, *source_layout, source_top, excluded_cells, included_cells);
|
||||
|
||||
// the variant's originals we are going to delete
|
||||
std::set<db::cell_index_type> cells_to_delete;
|
||||
|
||||
// We now need to fix the cell map from the hierarchy builder, so we can import back from the modified layout.
|
||||
// This is in particular important if we created new cells for known variants.
|
||||
for (std::vector<std::pair<db::cell_index_type, db::cell_index_type> >::const_iterator np = new_pairs.begin (); np != new_pairs.end (); ++np) {
|
||||
|
||||
db::cell_index_type var_org = original_builder.original_target_for_variant (np->first);
|
||||
|
||||
std::map<db::cell_index_type, std::pair<db::cell_index_type, std::set<db::Box> > >::const_iterator icm = cm_skipped_variants.find (var_org);
|
||||
if (icm != cm_skipped_variants.end ()) {
|
||||
|
||||
// create the variant clone in the original layout too and delete this cell
|
||||
VariantsCollectorBase::copy_shapes (*into_layout, np->second, icm->second.first);
|
||||
cells_to_delete.insert (icm->second.first);
|
||||
|
||||
// forget the original cell (now separated into variants) and map the variants back into the
|
||||
// DSS layout
|
||||
original_builder.unmap (icm->second);
|
||||
original_builder.map (std::make_pair (np->second, icm->second.second), np->first);
|
||||
|
||||
// forget the variant as now it's a real cell in the source layout
|
||||
original_builder.unregister_variant (np->first);
|
||||
|
||||
// rename the cell because it may be a different one now
|
||||
source_layout->rename_cell (np->first, into_layout->cell_name (np->second));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// delete the variant's original cell
|
||||
if (! cells_to_delete.empty ()) {
|
||||
into_layout->delete_cells (cells_to_delete);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -185,6 +185,40 @@ HierarchyBuilder::register_variant (db::cell_index_type non_var, db::cell_index_
|
|||
m_variants_to_original_target_map.insert (std::make_pair (var, non_var));
|
||||
}
|
||||
|
||||
void
|
||||
HierarchyBuilder::unregister_variant (db::cell_index_type var)
|
||||
{
|
||||
variant_to_original_target_map_type::const_iterator v = m_variants_to_original_target_map.find (var);
|
||||
if (v == m_variants_to_original_target_map.end ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
original_target_to_variants_map_type::iterator rv = m_original_targets_to_variants_map.find (v->second);
|
||||
tl_assert (rv != m_original_targets_to_variants_map.end ());
|
||||
|
||||
std::vector<db::cell_index_type> &vv = rv->second;
|
||||
std::vector<db::cell_index_type>::iterator ri = std::find (vv.begin (), vv.end (), var);
|
||||
tl_assert (ri != vv.end ());
|
||||
vv.erase (ri);
|
||||
|
||||
if (vv.empty ()) {
|
||||
m_original_targets_to_variants_map.erase (rv);
|
||||
}
|
||||
|
||||
m_variants_to_original_target_map.erase (v);
|
||||
}
|
||||
|
||||
db::cell_index_type
|
||||
HierarchyBuilder::original_target_for_variant (db::cell_index_type ci) const
|
||||
{
|
||||
variant_to_original_target_map_type::const_iterator v = m_variants_to_original_target_map.find (ci);
|
||||
if (v != m_variants_to_original_target_map.end ()) {
|
||||
return v->second;
|
||||
} else {
|
||||
return ci;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HierarchyBuilder::begin (const RecursiveShapeIterator *iter)
|
||||
{
|
||||
|
|
@ -269,6 +303,7 @@ HierarchyBuilder::new_inst (const RecursiveShapeIterator *iter, const db::CellIn
|
|||
if (all) {
|
||||
|
||||
std::pair<db::cell_index_type, std::set<db::Box> > key (inst.object ().cell_index (), std::set<db::Box> ());
|
||||
|
||||
m_cm_entry = m_cell_map.find (key);
|
||||
m_cm_new_entry = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -284,6 +284,24 @@ public:
|
|||
return m_cell_map.end ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unmaps an original cell/clip box version from the original-to-working copy cell map
|
||||
*
|
||||
* An unmapped cell is never again considered.
|
||||
*/
|
||||
void unmap (const cell_map_type::key_type &k)
|
||||
{
|
||||
m_cell_map.erase (k);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Maps an original cell/clip box version to a original-to-working copy cell
|
||||
*/
|
||||
void map (const cell_map_type::key_type &k, db::cell_index_type ci)
|
||||
{
|
||||
m_cell_map [k] = ci;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Marks a cell as a variant of another
|
||||
*
|
||||
|
|
@ -292,6 +310,11 @@ public:
|
|||
*/
|
||||
void register_variant (db::cell_index_type non_var, db::cell_index_type var);
|
||||
|
||||
/**
|
||||
* @brief Unregisters a cell as a variant
|
||||
*/
|
||||
void unregister_variant (db::cell_index_type var);
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether the given cell is a variant cell
|
||||
*/
|
||||
|
|
@ -300,6 +323,11 @@ public:
|
|||
return m_variants_to_original_target_map.find (ci) != m_variants_to_original_target_map.end ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the original target for a variant cell
|
||||
*/
|
||||
db::cell_index_type original_target_for_variant (db::cell_index_type ci) const;
|
||||
|
||||
private:
|
||||
tl::weak_ptr<db::Layout> mp_target;
|
||||
HierarchyBuilderShapeReceiver *mp_pipe;
|
||||
|
|
|
|||
Loading…
Reference in New Issue