WIP: Variant building bug fixed. Needs testing.

This commit is contained in:
Matthias Koefferlein 2019-11-05 00:46:12 +01:00
parent 990f01adec
commit 51676376e6
7 changed files with 152 additions and 10 deletions

View File

@ -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

View File

@ -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;
};

View File

@ -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);

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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;