mirror of https://github.com/KLayout/klayout.git
Improving Layout::cleanup to consolidate library and cold proxies and to establish proper cell names if possible
This commit is contained in:
parent
dcc7f28c77
commit
a6dce8c2ad
|
|
@ -60,14 +60,36 @@ ColdProxy::ColdProxy (db::cell_index_type ci, db::Layout &layout, const LayoutOr
|
|||
}
|
||||
i->second->push_back (this);
|
||||
}
|
||||
|
||||
layout.register_cold_proxy (this);
|
||||
}
|
||||
|
||||
ColdProxy::~ColdProxy ()
|
||||
{
|
||||
if (layout ()) {
|
||||
layout ()->unregister_cold_proxy (this);
|
||||
}
|
||||
|
||||
delete mp_context_info;
|
||||
mp_context_info = 0;
|
||||
}
|
||||
|
||||
void
|
||||
ColdProxy::unregister ()
|
||||
{
|
||||
if (layout ()) {
|
||||
layout ()->unregister_cold_proxy (this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ColdProxy::reregister ()
|
||||
{
|
||||
if (layout ()) {
|
||||
layout ()->register_cold_proxy (this);
|
||||
}
|
||||
}
|
||||
|
||||
Cell *
|
||||
ColdProxy::clone (Layout &layout) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -81,6 +81,16 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reimplemented from Cell: unregisters the proxy at the layout
|
||||
*/
|
||||
virtual void unregister ();
|
||||
|
||||
/**
|
||||
* @brief Reimplemented from Cell: reregisters the proxy at the layout
|
||||
*/
|
||||
virtual void reregister ();
|
||||
|
||||
/**
|
||||
* @brief Gets a list of cold proxies for a given library name
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -337,6 +337,37 @@ private:
|
|||
// -----------------------------------------------------------------
|
||||
// Implementation of the ProxyContextInfo class
|
||||
|
||||
bool
|
||||
LayoutOrCellContextInfo::operator== (const LayoutOrCellContextInfo &other) const
|
||||
{
|
||||
return lib_name == other.lib_name &&
|
||||
cell_name == other.cell_name &&
|
||||
pcell_name == other.pcell_name &&
|
||||
pcell_parameters == other.pcell_parameters &&
|
||||
meta_info == other.meta_info;
|
||||
}
|
||||
|
||||
bool
|
||||
LayoutOrCellContextInfo::operator< (const LayoutOrCellContextInfo &other) const
|
||||
{
|
||||
if (lib_name != other.lib_name) {
|
||||
return lib_name < other.lib_name;
|
||||
}
|
||||
if (cell_name != other.cell_name) {
|
||||
return cell_name < other.cell_name;
|
||||
}
|
||||
if (pcell_name != other.pcell_name) {
|
||||
return pcell_name < other.pcell_name;
|
||||
}
|
||||
if (pcell_parameters != other.pcell_parameters) {
|
||||
return pcell_parameters < other.pcell_parameters;
|
||||
}
|
||||
if (meta_info != other.meta_info) {
|
||||
return meta_info < other.meta_info;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
LayoutOrCellContextInfo
|
||||
LayoutOrCellContextInfo::deserialize (std::vector<std::string>::const_iterator from, std::vector<std::string>::const_iterator to)
|
||||
{
|
||||
|
|
@ -540,6 +571,7 @@ Layout::clear ()
|
|||
m_pcell_ids.clear ();
|
||||
|
||||
m_lib_proxy_map.clear ();
|
||||
m_cold_proxy_map.clear ();
|
||||
m_meta_info.clear ();
|
||||
}
|
||||
|
||||
|
|
@ -568,6 +600,7 @@ Layout::operator= (const Layout &d)
|
|||
}
|
||||
|
||||
m_lib_proxy_map = d.m_lib_proxy_map;
|
||||
m_cold_proxy_map = d.m_cold_proxy_map;
|
||||
|
||||
m_cell_ptrs.resize (d.m_cell_ptrs.size (), 0);
|
||||
|
||||
|
|
@ -809,6 +842,7 @@ Layout::mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat
|
|||
db::mem_stat (stat, purpose, cat, m_pcells, true, (void *) this);
|
||||
db::mem_stat (stat, purpose, cat, m_pcell_ids, true, (void *) this);
|
||||
db::mem_stat (stat, purpose, cat, m_lib_proxy_map, true, (void *) this);
|
||||
db::mem_stat (stat, purpose, cat, m_cold_proxy_map, true, (void *) this);
|
||||
db::mem_stat (stat, purpose, cat, m_meta_info, true, (void *) this);
|
||||
db::mem_stat (stat, purpose, cat, m_shape_repository, true, (void *) this);
|
||||
db::mem_stat (stat, purpose, cat, m_array_repository, true, (void *) this);
|
||||
|
|
@ -1505,6 +1539,11 @@ Layout::register_cell_name (const char *name, cell_index_type ci)
|
|||
void
|
||||
Layout::rename_cell (cell_index_type id, const char *name)
|
||||
{
|
||||
static const char *anonymous_name = "";
|
||||
if (! name) {
|
||||
name = anonymous_name;
|
||||
}
|
||||
|
||||
tl_assert (id < m_cell_names.size ());
|
||||
|
||||
if (strcmp (m_cell_names [id], name) != 0) {
|
||||
|
|
@ -1521,7 +1560,10 @@ Layout::rename_cell (cell_index_type id, const char *name)
|
|||
delete [] m_cell_names [id];
|
||||
m_cell_names [id] = cp;
|
||||
|
||||
m_cell_map.insert (std::make_pair (cp, id));
|
||||
// NOTE: anonymous cells (empty name string) are not registered in the cell name map
|
||||
if (*cp != 0) {
|
||||
m_cell_map.insert (std::make_pair (cp, id));
|
||||
}
|
||||
|
||||
// to enforce a redraw and a rebuild
|
||||
cell_name_changed ();
|
||||
|
|
@ -1690,27 +1732,119 @@ Layout::cleanup (const std::set<db::cell_index_type> &keep)
|
|||
return;
|
||||
}
|
||||
|
||||
if (tl::verbosity () >= 30) {
|
||||
tl::info << "Cleaning up layout ..";
|
||||
}
|
||||
|
||||
// Do some polishing of the proxies - sometimes, specifically when resolving indirect library references,
|
||||
// different proxies to the same library object exist. We can identify them and clean them up, so there
|
||||
// is a single reference. We can also try to ensure that cell names reflect the library cell names.
|
||||
// The latter is good for LVS for example.
|
||||
|
||||
{
|
||||
db::LayoutLocker locker (this);
|
||||
|
||||
// join library proxies pointing to the same object
|
||||
|
||||
for (auto c = m_lib_proxy_map.begin (); c != m_lib_proxy_map.end (); ) {
|
||||
|
||||
auto c0 = c++;
|
||||
size_t n = 1;
|
||||
while (c != m_lib_proxy_map.end () && c->first == c0->first) {
|
||||
++n;
|
||||
++c;
|
||||
}
|
||||
|
||||
if (n > 1) {
|
||||
auto cc = c0;
|
||||
++cc;
|
||||
while (cc != c) {
|
||||
if (keep.find (cc->second) == keep.end ()) {
|
||||
if (tl::verbosity () >= 30) {
|
||||
tl::info << "Joining lib proxy " << cell_name (cc->second) << " into " << cell_name (c0->second);
|
||||
}
|
||||
replace_instances_of (cc->second, c0->second);
|
||||
}
|
||||
++cc;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// join cold proxies pointing to the same object
|
||||
|
||||
for (auto c = m_cold_proxy_map.begin (); c != m_cold_proxy_map.end (); ) {
|
||||
|
||||
auto c0 = c++;
|
||||
size_t n = 1;
|
||||
while (c != m_cold_proxy_map.end () && c->first == c0->first) {
|
||||
++n;
|
||||
++c;
|
||||
}
|
||||
|
||||
if (n > 1) {
|
||||
auto cc = c0;
|
||||
++cc;
|
||||
while (cc != c) {
|
||||
if (keep.find (cc->second) == keep.end ()) {
|
||||
if (tl::verbosity () >= 30) {
|
||||
tl::info << "Joining cold proxy " << cell_name (cc->second) << " into " << cell_name (c0->second);
|
||||
}
|
||||
replace_instances_of (cc->second, c0->second);
|
||||
}
|
||||
++cc;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::set<cell_index_type> cells_to_delete;
|
||||
|
||||
// deleting cells may create new top cells which need to be deleted as well, hence we iterate
|
||||
// until there are no more cells to delete
|
||||
while (true) {
|
||||
|
||||
// delete all cells that are top cells and are proxies. Those cells are proxies no longer required.
|
||||
std::set<cell_index_type> cells_to_delete;
|
||||
for (top_down_iterator c = begin_top_down (); c != end_top_cells (); ++c) {
|
||||
if (cell (*c).is_proxy ()) {
|
||||
if (cell (*c).is_proxy () && keep.find (*c) == keep.end ()) {
|
||||
cells_to_delete.insert (*c);
|
||||
}
|
||||
}
|
||||
|
||||
for (std::set<db::cell_index_type>::const_iterator k = keep.begin (); k != keep.end (); ++k) {
|
||||
cells_to_delete.erase (*k);
|
||||
}
|
||||
|
||||
if (cells_to_delete.empty ()) {
|
||||
break;
|
||||
}
|
||||
|
||||
delete_cells (cells_to_delete);
|
||||
cells_to_delete.clear ();
|
||||
|
||||
}
|
||||
|
||||
// Try to ensure that cell names reflect the library cell names. The latter is good for LVS for example.
|
||||
|
||||
for (auto c = m_lib_proxy_map.begin (); c != m_lib_proxy_map.end (); ++c) {
|
||||
|
||||
std::string bn = cell (c->second).get_basic_name ();
|
||||
if (bn != cell_name (c->second) && ! cell_by_name (bn.c_str ()).first) {
|
||||
if (tl::verbosity () >= 30) {
|
||||
tl::info << "Renaming lib proxy " << cell_name (c->second) << " to " << bn;
|
||||
}
|
||||
rename_cell (c->second, bn.c_str ());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (auto c = m_cold_proxy_map.begin (); c != m_cold_proxy_map.end (); ++c) {
|
||||
|
||||
std::string bn = cell (c->second).get_basic_name ();
|
||||
if (bn != cell_name (c->second) && ! cell_by_name (bn.c_str ()).first) {
|
||||
if (tl::verbosity () >= 30) {
|
||||
tl::info << "Renaming cold proxy " << cell_name (c->second) << " to " << bn;
|
||||
}
|
||||
rename_cell (c->second, bn.c_str ());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -3151,13 +3285,32 @@ Layout::variant_name (cell_index_type cell_index) const
|
|||
void
|
||||
Layout::register_lib_proxy (db::LibraryProxy *lib_proxy)
|
||||
{
|
||||
m_lib_proxy_map.insert (std::make_pair (std::make_pair (lib_proxy->lib_id (), lib_proxy->library_cell_index ()), lib_proxy->Cell::cell_index ()));
|
||||
auto key = std::make_pair (lib_proxy->lib_id (), lib_proxy->library_cell_index ());
|
||||
|
||||
auto l = m_lib_proxy_map.find (key);
|
||||
while (l != m_lib_proxy_map.end () && l->first == key) {
|
||||
if (l->second == lib_proxy->Cell::cell_index ()) {
|
||||
return;
|
||||
}
|
||||
++l;
|
||||
}
|
||||
|
||||
m_lib_proxy_map.insert (std::make_pair (key, lib_proxy->Cell::cell_index ()));
|
||||
}
|
||||
|
||||
void
|
||||
Layout::unregister_lib_proxy (db::LibraryProxy *lib_proxy)
|
||||
{
|
||||
m_lib_proxy_map.erase (std::make_pair (lib_proxy->lib_id (), lib_proxy->library_cell_index ()));
|
||||
auto key = std::make_pair (lib_proxy->lib_id (), lib_proxy->library_cell_index ());
|
||||
|
||||
auto l = m_lib_proxy_map.find (key);
|
||||
while (l != m_lib_proxy_map.end () && l->first == key) {
|
||||
if (l->second == lib_proxy->Cell::cell_index ()) {
|
||||
m_lib_proxy_map.erase (l);
|
||||
break;
|
||||
}
|
||||
++l;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -3177,9 +3330,13 @@ Layout::get_lib_proxy_as (Library *lib, cell_index_type cell_index, cell_index_t
|
|||
cell_index_type
|
||||
Layout::get_lib_proxy (Library *lib, cell_index_type cell_index)
|
||||
{
|
||||
lib_proxy_map::const_iterator lp = m_lib_proxy_map.find (std::make_pair (lib->get_id (), cell_index));
|
||||
if (lp != m_lib_proxy_map.end ()) {
|
||||
auto key = std::make_pair (lib->get_id (), cell_index);
|
||||
|
||||
lib_proxy_map::const_iterator lp = m_lib_proxy_map.find (key);
|
||||
if (lp != m_lib_proxy_map.end () && lp->first == key) {
|
||||
|
||||
return lp->second;
|
||||
|
||||
} else {
|
||||
|
||||
// create a new unique name
|
||||
|
|
@ -3210,35 +3367,82 @@ Layout::get_lib_proxy (Library *lib, cell_index_type cell_index)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Layout::register_cold_proxy (db::ColdProxy *cold_proxy)
|
||||
{
|
||||
auto l = m_cold_proxy_map.find (cold_proxy->context_info ());
|
||||
while (l != m_cold_proxy_map.end () && l->first == cold_proxy->context_info ()) {
|
||||
if (l->second == cold_proxy->Cell::cell_index ()) {
|
||||
return;
|
||||
}
|
||||
++l;
|
||||
}
|
||||
|
||||
m_cold_proxy_map.insert (std::make_pair (cold_proxy->context_info (), cold_proxy->Cell::cell_index ()));
|
||||
}
|
||||
|
||||
void
|
||||
Layout::unregister_cold_proxy (db::ColdProxy *cold_proxy)
|
||||
{
|
||||
auto l = m_cold_proxy_map.find (cold_proxy->context_info ());
|
||||
while (l != m_cold_proxy_map.end () && l->first == cold_proxy->context_info ()) {
|
||||
if (l->second == cold_proxy->Cell::cell_index ()) {
|
||||
m_cold_proxy_map.erase (l);
|
||||
break;
|
||||
}
|
||||
++l;
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<bool, cell_index_type>
|
||||
Layout::find_cold_proxy (const db::LayoutOrCellContextInfo &info)
|
||||
{
|
||||
cold_proxy_map::const_iterator lp = m_cold_proxy_map.find (info);
|
||||
if (lp != m_cold_proxy_map.end () && lp->first == info) {
|
||||
return std::make_pair (true, lp->second);
|
||||
} else {
|
||||
return std::make_pair (false, 0);
|
||||
}
|
||||
}
|
||||
|
||||
cell_index_type
|
||||
Layout::create_cold_proxy (const db::LayoutOrCellContextInfo &info)
|
||||
{
|
||||
// create a new unique name
|
||||
std::string b;
|
||||
if (! info.cell_name.empty ()) {
|
||||
b = info.cell_name;
|
||||
} else if (! info.pcell_name.empty ()) {
|
||||
b = info.pcell_name;
|
||||
cold_proxy_map::const_iterator lp = m_cold_proxy_map.find (info);
|
||||
if (lp != m_cold_proxy_map.end () && lp->first == info) {
|
||||
|
||||
return lp->second;
|
||||
|
||||
} else {
|
||||
|
||||
// create a new unique name
|
||||
std::string b;
|
||||
if (! info.cell_name.empty ()) {
|
||||
b = info.cell_name;
|
||||
} else if (! info.pcell_name.empty ()) {
|
||||
b = info.pcell_name;
|
||||
}
|
||||
if (m_cell_map.find (b.c_str ()) != m_cell_map.end ()) {
|
||||
b = uniquify_cell_name (b.c_str ());
|
||||
}
|
||||
|
||||
// create a new cell (a LibraryProxy)
|
||||
cell_index_type new_index = allocate_new_cell ();
|
||||
|
||||
ColdProxy *proxy = new ColdProxy (new_index, *this, info);
|
||||
m_cells.push_back_ptr (proxy);
|
||||
m_cell_ptrs [new_index] = proxy;
|
||||
|
||||
// enter its index and cell_name
|
||||
register_cell_name (b.c_str (), new_index);
|
||||
|
||||
if (manager () && manager ()->transacting ()) {
|
||||
manager ()->queue (this, new NewRemoveCellOp (new_index, m_cell_names [new_index], false /*new*/, 0));
|
||||
}
|
||||
|
||||
return new_index;
|
||||
|
||||
}
|
||||
if (m_cell_map.find (b.c_str ()) != m_cell_map.end ()) {
|
||||
b = uniquify_cell_name (b.c_str ());
|
||||
}
|
||||
|
||||
// create a new cell (a LibraryProxy)
|
||||
cell_index_type new_index = allocate_new_cell ();
|
||||
|
||||
ColdProxy *proxy = new ColdProxy (new_index, *this, info);
|
||||
m_cells.push_back_ptr (proxy);
|
||||
m_cell_ptrs [new_index] = proxy;
|
||||
|
||||
// enter its index and cell_name
|
||||
register_cell_name (b.c_str (), new_index);
|
||||
|
||||
if (manager () && manager ()->transacting ()) {
|
||||
manager ()->queue (this, new NewRemoveCellOp (new_index, m_cell_names [new_index], false /*new*/, 0));
|
||||
}
|
||||
|
||||
return new_index;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ class PCellDeclaration;
|
|||
class PCellHeader;
|
||||
class Library;
|
||||
class LibraryProxy;
|
||||
class ColdProxy;
|
||||
class CellMapping;
|
||||
class LayerMapping;
|
||||
class Region;
|
||||
|
|
@ -427,6 +428,9 @@ struct DB_PUBLIC LayoutOrCellContextInfo
|
|||
std::map<std::string, tl::Variant> pcell_parameters;
|
||||
std::map<std::string, std::pair<tl::Variant, std::string> > meta_info;
|
||||
|
||||
bool operator== (const LayoutOrCellContextInfo &other) const;
|
||||
bool operator< (const LayoutOrCellContextInfo &other) const;
|
||||
|
||||
static LayoutOrCellContextInfo deserialize (std::vector<std::string>::const_iterator from, std::vector<std::string>::const_iterator to);
|
||||
void serialize (std::vector<std::string> &strings);
|
||||
|
||||
|
|
@ -469,7 +473,8 @@ public:
|
|||
typedef db::pcell_id_type pcell_id_type;
|
||||
typedef std::map<std::string, pcell_id_type> pcell_name_map;
|
||||
typedef pcell_name_map::const_iterator pcell_iterator;
|
||||
typedef std::map<std::pair<lib_id_type, cell_index_type>, cell_index_type> lib_proxy_map;
|
||||
typedef std::multimap<std::pair<lib_id_type, cell_index_type>, cell_index_type> lib_proxy_map;
|
||||
typedef std::multimap<db::LayoutOrCellContextInfo, cell_index_type> cold_proxy_map;
|
||||
typedef LayerIterator layer_iterator;
|
||||
typedef size_t meta_info_name_id_type;
|
||||
typedef std::map<meta_info_name_id_type, MetaInfo> meta_info_map;
|
||||
|
|
@ -1003,6 +1008,12 @@ public:
|
|||
*/
|
||||
void get_lib_proxy_as (Library *lib, cell_index_type cell_index, cell_index_type target_cell_index, ImportLayerMapping *layer_mapping = 0, bool retain_layout = false);
|
||||
|
||||
/**
|
||||
* @brief Find an existing cold proxy for a given context
|
||||
* @return A pair of success flag and cell index of the proxy
|
||||
*/
|
||||
std::pair<bool, cell_index_type> find_cold_proxy (const db::LayoutOrCellContextInfo &info);
|
||||
|
||||
/**
|
||||
* @brief Creates a cold proxy representing the given context information
|
||||
*/
|
||||
|
|
@ -1839,6 +1850,20 @@ public:
|
|||
*/
|
||||
void unregister_lib_proxy (db::LibraryProxy *lib_proxy);
|
||||
|
||||
/**
|
||||
* @brief Register a cold proxy
|
||||
*
|
||||
* This method is used by ColdProxy to register itself.
|
||||
*/
|
||||
void register_cold_proxy (db::ColdProxy *cold_proxy);
|
||||
|
||||
/**
|
||||
* @brief Unregister a cold proxy
|
||||
*
|
||||
* This method is used by ColdProxy to unregister itself.
|
||||
*/
|
||||
void unregister_cold_proxy (db::ColdProxy *cold_proxy);
|
||||
|
||||
/**
|
||||
* @brief Gets the editable status of this layout
|
||||
*
|
||||
|
|
@ -2153,6 +2178,7 @@ private:
|
|||
std::vector<pcell_header_type *> m_pcells;
|
||||
pcell_name_map m_pcell_ids;
|
||||
lib_proxy_map m_lib_proxy_map;
|
||||
cold_proxy_map m_cold_proxy_map;
|
||||
bool m_do_cleanup;
|
||||
bool m_editable;
|
||||
std::map<std::string, meta_info_name_id_type> m_meta_info_name_map;
|
||||
|
|
|
|||
|
|
@ -221,14 +221,25 @@ LibraryProxy::update (db::ImportLayerMapping *layer_mapping)
|
|||
real_lib = db::LibraryManager::instance ().lib (lp->lib_id ());
|
||||
}
|
||||
|
||||
inst.object ().cell_index (layout ()->get_lib_proxy (real_lib, real_cil));
|
||||
|
||||
ColdProxy *cp = dynamic_cast<ColdProxy *> (&real_lib->layout ().cell (real_cil));
|
||||
if (cp) {
|
||||
|
||||
// The final item is a cold proxy ("<defunct>" cell) - treat it like
|
||||
// a library proxy as it may become one in the future, but replace it
|
||||
// by a cold proxy now.
|
||||
layout ()->create_cold_proxy_as (cp->context_info (), inst.object ().cell_index ());
|
||||
|
||||
auto p = layout ()->find_cold_proxy (cp->context_info ());
|
||||
if (p.first) {
|
||||
// reuse existing proxy
|
||||
inst.object ().cell_index (p.second);
|
||||
} else {
|
||||
// create a new proxy, reusing the first library proxy's replica
|
||||
inst.object ().cell_index (layout ()->get_lib_proxy (real_lib, real_cil));
|
||||
layout ()->create_cold_proxy_as (cp->context_info (), inst.object ().cell_index ());
|
||||
}
|
||||
|
||||
} else {
|
||||
inst.object ().cell_index (layout ()->get_lib_proxy (real_lib, real_cil));
|
||||
}
|
||||
|
||||
inst.transform_into (db::ICplxTrans (lib->layout ().dbu () / layout ()->dbu ()));
|
||||
|
|
|
|||
|
|
@ -129,12 +129,12 @@ public:
|
|||
/**
|
||||
* @brief Reimplemented from Cell: unregisters the proxy at the layout
|
||||
*/
|
||||
void unregister ();
|
||||
virtual void unregister ();
|
||||
|
||||
/**
|
||||
* @brief Reimplemented from Cell: reregisters the proxy at the layout
|
||||
*/
|
||||
void reregister ();
|
||||
virtual void reregister ();
|
||||
|
||||
private:
|
||||
lib_id_type m_lib_id;
|
||||
|
|
|
|||
|
|
@ -773,8 +773,8 @@ TEST(7_monsterlib)
|
|||
}
|
||||
|
||||
// as NOEX and NOEX2 are not present, a number of references are defunct (aka cold proxies)
|
||||
EXPECT_EQ (num_defunct (layout), size_t (15));
|
||||
EXPECT_EQ (num_cells (layout), size_t (46));
|
||||
EXPECT_EQ (num_defunct (layout), size_t (6));
|
||||
EXPECT_EQ (num_cells (layout), size_t (25));
|
||||
EXPECT_EQ (num_top_cells (layout), size_t (1));
|
||||
|
||||
// NOTE: normalization would spoil the layout, so don't do it
|
||||
|
|
@ -794,7 +794,7 @@ TEST(7_monsterlib)
|
|||
|
||||
// all references now need to be resolved
|
||||
EXPECT_EQ (num_defunct (layout), size_t (0));
|
||||
EXPECT_EQ (num_cells (layout), size_t (36));
|
||||
EXPECT_EQ (num_cells (layout), size_t (25));
|
||||
EXPECT_EQ (num_top_cells (layout), size_t (1));
|
||||
|
||||
db::compare_layouts (_this, layout, tl::testsrc () + "/testdata/libman/design_au2.gds", db::NormalizationMode (db::NoNormalization | db::WithoutCellNames | db::AsPolygons));
|
||||
|
|
@ -807,7 +807,7 @@ TEST(7_monsterlib)
|
|||
|
||||
// all references now need to be resolved
|
||||
EXPECT_EQ (num_defunct (layout), size_t (0));
|
||||
EXPECT_EQ (num_cells (layout), size_t (32));
|
||||
EXPECT_EQ (num_cells (layout), size_t (25));
|
||||
EXPECT_EQ (num_top_cells (layout), size_t (1));
|
||||
|
||||
db::compare_layouts (_this, layout, tl::testsrc () + "/testdata/libman/design_au3.gds", db::NormalizationMode (db::NoNormalization | db::WithoutCellNames | db::AsPolygons));
|
||||
|
|
@ -816,8 +816,8 @@ TEST(7_monsterlib)
|
|||
db::LibraryManager::instance ().delete_lib (lib_noex2);
|
||||
|
||||
// after removing the libraries, we have defunct cells again
|
||||
EXPECT_EQ (num_defunct (layout), size_t (11));
|
||||
EXPECT_EQ (num_cells (layout), size_t (32));
|
||||
EXPECT_EQ (num_defunct (layout), size_t (6));
|
||||
EXPECT_EQ (num_cells (layout), size_t (25));
|
||||
EXPECT_EQ (num_top_cells (layout), size_t (1));
|
||||
|
||||
// but the layout did not change
|
||||
|
|
@ -827,8 +827,8 @@ TEST(7_monsterlib)
|
|||
db::LibraryManager::instance ().delete_lib (lib_ex2);
|
||||
|
||||
// after removing all libraries, we have even more defunct cells (i.e. all, except top)
|
||||
EXPECT_EQ (num_defunct (layout), size_t (19));
|
||||
EXPECT_EQ (num_cells (layout), size_t (32));
|
||||
EXPECT_EQ (num_defunct (layout), size_t (12));
|
||||
EXPECT_EQ (num_cells (layout), size_t (25));
|
||||
EXPECT_EQ (num_top_cells (layout), size_t (1));
|
||||
|
||||
// but the layout did not change
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue