mirror of https://github.com/KLayout/klayout.git
Implementing variant reporting
Instead of reporting working layout cell names, the original cell names plus a variant indicator is reported. Also, the variant information from the RDB is filled now. Also, the marker browser now shows the qname of the cells instead of the name alone.
This commit is contained in:
parent
aacdc1a4b7
commit
6e3eb568c3
|
|
@ -288,6 +288,7 @@ VariantsCollectorBase::separate_variants (std::map<db::cell_index_type, std::map
|
|||
if (! var_table) {
|
||||
var_table = &var_table_intern;
|
||||
}
|
||||
tl_assert (var_table->empty ());
|
||||
|
||||
for (db::Layout::bottom_up_const_iterator c = mp_layout->begin_bottom_up (); c != mp_layout->end_bottom_up (); ++c) {
|
||||
|
||||
|
|
@ -311,6 +312,9 @@ VariantsCollectorBase::separate_variants (std::map<db::cell_index_type, std::map
|
|||
|
||||
cell.clear_insts ();
|
||||
|
||||
bool original_cell_is_variant = false;
|
||||
db::ICplxTrans original_cell_variant;
|
||||
|
||||
int index = 0;
|
||||
for (auto v = vc->second.begin (); v != vc->second.end (); ++v, ++index) {
|
||||
|
||||
|
|
@ -333,6 +337,8 @@ VariantsCollectorBase::separate_variants (std::map<db::cell_index_type, std::map
|
|||
|
||||
} else {
|
||||
ci_var = *c;
|
||||
original_cell_is_variant = true;
|
||||
original_cell_variant = *v;
|
||||
}
|
||||
|
||||
vt.insert (std::make_pair (*v, ci_var));
|
||||
|
|
@ -341,12 +347,14 @@ VariantsCollectorBase::separate_variants (std::map<db::cell_index_type, std::map
|
|||
}
|
||||
|
||||
// correct the first (remaining) entry
|
||||
if (! vt.begin ()->first.is_unity ()) {
|
||||
std::set<db::ICplxTrans> &tv = m_variants [*c];
|
||||
tv.clear ();
|
||||
tv.insert (vt.begin ()->first);
|
||||
} else {
|
||||
m_variants.erase (*c);
|
||||
if (original_cell_is_variant) {
|
||||
if (! original_cell_variant.is_unity ()) {
|
||||
std::set<db::ICplxTrans> &tv = m_variants [*c];
|
||||
tv.clear ();
|
||||
tv.insert (original_cell_variant);
|
||||
} else {
|
||||
m_variants.erase (*c);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -298,28 +298,57 @@ struct DeepShapeStore::LayoutHolder
|
|||
{
|
||||
public:
|
||||
VariantsCreatedListener (DeepShapeStore::LayoutHolder *lh, db::Layout *ly)
|
||||
: mp_lh (lh)
|
||||
: mp_lh (lh), m_dbu (ly->dbu ())
|
||||
{
|
||||
ly->variants_created_event.add (this, &VariantsCreatedListener::variants_created);
|
||||
}
|
||||
|
||||
private:
|
||||
std::string var_desc (const db::ICplxTrans &t)
|
||||
{
|
||||
std::string s;
|
||||
if (t.is_mirror ()) {
|
||||
s += "m";
|
||||
s += tl::to_string (t.angle () * 0.5);
|
||||
} else {
|
||||
s += "r";
|
||||
s += tl::to_string (t.angle ());
|
||||
}
|
||||
if (t.is_mag ()) {
|
||||
s += tl::sprintf ("*%.9g", t.mag ());
|
||||
}
|
||||
if (t.disp () != db::Vector ()) {
|
||||
s += tl::sprintf ("(%.12g,%.12g)", t.disp ().x () * m_dbu, t.disp ().y () * m_dbu);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void variants_created (const std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> > *var_map)
|
||||
{
|
||||
for (std::map<db::cell_index_type, std::map<db::ICplxTrans, db::cell_index_type> >::const_iterator i = var_map->begin (); i != var_map->end (); ++i) {
|
||||
for (std::map<db::ICplxTrans, db::cell_index_type>::const_iterator j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
mp_lh->builder.register_variant (i->first, j->second);
|
||||
if (i->first != j->second) {
|
||||
mp_lh->builder.register_variant (i->first, j->second, var_desc (j->first));
|
||||
}
|
||||
}
|
||||
// NOTE: variant conversion events are registered after variant formation events, so we can
|
||||
// base the formed variants (first pass) on the originals.
|
||||
for (std::map<db::ICplxTrans, db::cell_index_type>::const_iterator j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
if (i->first == j->second) {
|
||||
mp_lh->builder.register_variant (i->first, j->second, var_desc (j->first));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DeepShapeStore::LayoutHolder *mp_lh;
|
||||
double m_dbu;
|
||||
};
|
||||
|
||||
LayoutHolder (const db::ICplxTrans &trans)
|
||||
: refs (0), layout (false), builder (&layout, trans), variants_created (this, &layout)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
layout.set_hierarchy_builder (&builder);
|
||||
}
|
||||
|
||||
void add_layer_ref (unsigned int layer)
|
||||
|
|
|
|||
|
|
@ -182,14 +182,24 @@ HierarchyBuilder::reset ()
|
|||
|
||||
m_cells_to_be_filled.clear ();
|
||||
m_cell_map.clear ();
|
||||
m_variants_of_sources_map.clear ();
|
||||
m_cells_seen.clear ();
|
||||
m_cell_stack.clear ();
|
||||
m_cm_entry = null_iterator;
|
||||
m_cm_new_entry = false;
|
||||
}
|
||||
|
||||
const std::pair<db::cell_index_type, std::string> &
|
||||
HierarchyBuilder::variant_of_source (db::cell_index_type target) const
|
||||
{
|
||||
static std::pair<db::cell_index_type, std::string> def (std::numeric_limits<db::cell_index_type>::max (), std::string ());
|
||||
|
||||
auto vs = m_variants_of_sources_map.find (target);
|
||||
return vs != m_variants_of_sources_map.end () ? vs->second : def;
|
||||
}
|
||||
|
||||
void
|
||||
HierarchyBuilder::register_variant (db::cell_index_type non_var, db::cell_index_type var)
|
||||
HierarchyBuilder::register_variant (db::cell_index_type non_var, db::cell_index_type var, const std::string &description)
|
||||
{
|
||||
// non_var (despite its name) may be a variant created previously.
|
||||
variant_to_original_target_map_type::const_iterator v = m_variants_to_original_target_map.find (non_var);
|
||||
|
|
@ -199,11 +209,23 @@ HierarchyBuilder::register_variant (db::cell_index_type non_var, db::cell_index_
|
|||
|
||||
m_original_targets_to_variants_map [non_var].push_back (var);
|
||||
m_variants_to_original_target_map.insert (std::make_pair (var, non_var));
|
||||
|
||||
auto vs = m_variants_of_sources_map.find (non_var);
|
||||
if (vs != m_variants_of_sources_map.end ()) {
|
||||
std::string new_description = vs->second.second;
|
||||
if (! new_description.empty ()) {
|
||||
new_description += ";";
|
||||
}
|
||||
new_description += description;
|
||||
m_variants_of_sources_map [var] = std::make_pair (vs->second.first, new_description);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HierarchyBuilder::unregister_variant (db::cell_index_type var)
|
||||
{
|
||||
m_variants_of_sources_map.erase (var);
|
||||
|
||||
variant_to_original_target_map_type::iterator v = m_variants_to_original_target_map.find (var);
|
||||
if (v == m_variants_to_original_target_map.end ()) {
|
||||
return;
|
||||
|
|
@ -257,6 +279,7 @@ HierarchyBuilder::begin (const RecursiveShapeIterator *iter)
|
|||
if (m_cm_entry == m_cell_map.end ()) {
|
||||
db::cell_index_type new_top_index = mp_target->add_cell (iter->layout ()->cell_name (key.original_cell));
|
||||
m_cm_entry = m_cell_map.insert (std::make_pair (key, new_top_index)).first;
|
||||
m_variants_of_sources_map.insert (std::make_pair (new_top_index, std::make_pair (key.original_cell, std::string ())));
|
||||
}
|
||||
|
||||
db::Cell &new_top = mp_target->cell (m_cm_entry->second);
|
||||
|
|
@ -324,17 +347,34 @@ HierarchyBuilder::make_cell_variant (const HierarchyBuilder::CellMapKey &key, co
|
|||
if (m_cm_entry == m_cell_map.end ()) {
|
||||
|
||||
std::string cn = cell_name;
|
||||
std::string description;
|
||||
if (! key.clip_region.empty ()) {
|
||||
cn += "$CLIP_VAR";
|
||||
description += "CLIP";
|
||||
|
||||
}
|
||||
if (key.inactive) {
|
||||
cn += "$DIS";
|
||||
if (! description.empty ()) {
|
||||
description += "/";
|
||||
}
|
||||
description += "DISABLED";
|
||||
}
|
||||
|
||||
new_cell = mp_target->add_cell (cn.c_str ());
|
||||
|
||||
std::string new_name = mp_target->cell_name (new_cell);
|
||||
if (new_name.size () > cn.size ()) {
|
||||
// use cell name extension to uniquify the description
|
||||
description += new_name.c_str () + cn.size ();
|
||||
}
|
||||
|
||||
m_cm_entry = m_cell_map.insert (std::make_pair (key, new_cell)).first;
|
||||
m_cm_new_entry = true;
|
||||
m_cells_to_be_filled.insert (new_cell);
|
||||
|
||||
m_variants_of_sources_map.insert (std::make_pair (new_cell, std::make_pair (key.original_cell, description)));
|
||||
|
||||
} else {
|
||||
new_cell = m_cm_entry->second;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -389,7 +389,7 @@ public:
|
|||
* The first cell is either the original, non-variant target cell or itself a variant.
|
||||
* The second cell will be registered as a variant of the first one.
|
||||
*/
|
||||
void register_variant (db::cell_index_type non_var, db::cell_index_type var);
|
||||
void register_variant (db::cell_index_type non_var, db::cell_index_type var, const std::string &description);
|
||||
|
||||
/**
|
||||
* @brief Unregisters a cell as a variant
|
||||
|
|
@ -404,8 +404,23 @@ public:
|
|||
return m_variants_to_original_target_map.find (ci) != m_variants_to_original_target_map.end ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the information about the target/source + variant relationship
|
||||
*
|
||||
* For a target cell, returns a pointer to a pair with the cell index of the source cell and
|
||||
* a string describing the variant this cell forms of the source cell.
|
||||
*
|
||||
* The description string is empty if the cell is not a variant.
|
||||
*/
|
||||
const std::pair<db::cell_index_type, std::string> &variant_of_source (db::cell_index_type target) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the original target for a variant cell
|
||||
*
|
||||
* The original cell is the first-generation target-space cell that variants have been created for.
|
||||
* This still can mean that the original cell is a clip variant of a source cell.
|
||||
*
|
||||
* Target-to-source variants can be derived with "variant_of_source".
|
||||
*/
|
||||
db::cell_index_type original_target_for_variant (db::cell_index_type ci) const;
|
||||
|
||||
|
|
@ -419,6 +434,7 @@ private:
|
|||
cell_map_type m_cell_map;
|
||||
original_target_to_variants_map_type m_original_targets_to_variants_map;
|
||||
variant_to_original_target_map_type m_variants_to_original_target_map;
|
||||
std::map<db::cell_index_type, std::pair<db::cell_index_type, std::string> > m_variants_of_sources_map;
|
||||
|
||||
std::set<cell_map_type::key_type> m_cells_seen;
|
||||
std::set<db::cell_index_type> m_cells_to_be_filled;
|
||||
|
|
|
|||
|
|
@ -439,6 +439,7 @@ LayoutOrCellContextInfo::has_meta_info () const
|
|||
Layout::Layout (db::Manager *manager)
|
||||
: db::Object (manager),
|
||||
mp_library (0),
|
||||
mp_builder (0),
|
||||
m_cells_size (0),
|
||||
m_invalid (0),
|
||||
m_top_cells (0),
|
||||
|
|
@ -454,6 +455,7 @@ Layout::Layout (db::Manager *manager)
|
|||
Layout::Layout (bool editable, db::Manager *manager)
|
||||
: db::Object (manager),
|
||||
mp_library (0),
|
||||
mp_builder (0),
|
||||
m_cells_size (0),
|
||||
m_invalid (0),
|
||||
m_top_cells (0),
|
||||
|
|
@ -473,6 +475,7 @@ Layout::Layout (const db::Layout &layout)
|
|||
tl::Object (),
|
||||
tl::UniqueId (),
|
||||
mp_library (0),
|
||||
mp_builder (0),
|
||||
m_cells_size (0),
|
||||
m_invalid (0),
|
||||
m_top_cells (0),
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ class Technology;
|
|||
class CellMapping;
|
||||
class LayerMapping;
|
||||
class VariantsCollectorBase;
|
||||
class HierarchyBuilder;
|
||||
|
||||
template <class Coord> class generic_repository;
|
||||
typedef generic_repository<db::Coord> GenericRepository;
|
||||
|
|
@ -2113,6 +2114,24 @@ public:
|
|||
*/
|
||||
const MetaInfo &meta_info (db::cell_index_type ci, meta_info_name_id_type name_id) const;
|
||||
|
||||
/**
|
||||
* @brief Sets the hierarchy builder reference
|
||||
* Used internally
|
||||
*/
|
||||
void set_hierarchy_builder (db::HierarchyBuilder *builder)
|
||||
{
|
||||
mp_builder = builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the hierarchy builder
|
||||
* Used internally
|
||||
*/
|
||||
db::HierarchyBuilder *builder () const
|
||||
{
|
||||
return mp_builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This event is triggered when the technology changes
|
||||
*/
|
||||
|
|
@ -2138,6 +2157,7 @@ protected:
|
|||
|
||||
private:
|
||||
db::Library *mp_library;
|
||||
db::HierarchyBuilder *mp_builder;
|
||||
cell_list m_cells;
|
||||
size_t m_cells_size;
|
||||
cell_ptr_vector m_cell_ptrs;
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ SortByKeyCompareFunc::operator() (MarkerBrowserTreeViewModelCacheEntry *a, Marke
|
|||
const rdb::Cell *ca = mp_rdb->cell_by_id (a->id ());
|
||||
const rdb::Cell *cb = mp_rdb->cell_by_id (b->id ());
|
||||
if (ca && cb) {
|
||||
return m_ascending ? ca->name () < cb->name () : cb->name () < ca->name ();
|
||||
return m_ascending ? ca->qname () < cb->qname () : cb->qname () < ca->qname ();
|
||||
}
|
||||
|
||||
const rdb::Category *xa = mp_rdb->category_by_id (a->id ());
|
||||
|
|
@ -582,7 +582,7 @@ public:
|
|||
if (cell->name ().empty ()) {
|
||||
return QObject::tr ("All Cells");
|
||||
} else {
|
||||
return QVariant (QString::fromUtf8 ("[") + tl::to_qstring (cell->name ()) + QString::fromUtf8 ("]"));
|
||||
return QVariant (QString::fromUtf8 ("[") + tl::to_qstring (cell->qname ()) + QString::fromUtf8 ("]"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -174,10 +174,28 @@ public:
|
|||
const rdb::Cell *cell_for_id (const db::Layout *layout, db::cell_index_type ci)
|
||||
{
|
||||
tl_assert (layout != 0);
|
||||
|
||||
std::string cn = layout->cell_name (ci);
|
||||
const rdb::Cell *rdb_cell = mp_rdb->cell_by_qname (cn);
|
||||
std::string layout_cn = cn;
|
||||
std::string qname = cn;
|
||||
std::string var;
|
||||
|
||||
// resolve references to original cells in deep mode and determine variant
|
||||
if (layout->builder ()) {
|
||||
const db::Layout *source = layout->builder ()->source ().layout ();
|
||||
if (source) {
|
||||
const std::pair<db::cell_index_type, std::string> &vs = layout->builder ()->variant_of_source (ci);
|
||||
if (! vs.second.empty () && source->is_valid_cell_index (vs.first)) {
|
||||
var = vs.second;
|
||||
cn = source->cell_name (vs.first);
|
||||
qname = cn + ":" + var;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const rdb::Cell *rdb_cell = mp_rdb->cell_by_qname (qname);
|
||||
if (! rdb_cell) {
|
||||
return mp_rdb->create_cell (cn);
|
||||
return mp_rdb->create_cell (cn, var, layout_cn);
|
||||
} else {
|
||||
return rdb_cell;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue