mirror of https://github.com/KLayout/klayout.git
Merge branch 'wip'
This commit is contained in:
commit
0648ee1bd0
|
|
@ -32,6 +32,7 @@
|
|||
#include "dbLibraryProxy.h"
|
||||
#include "dbLibraryManager.h"
|
||||
#include "dbLibrary.h"
|
||||
#include "dbColdProxy.h"
|
||||
#include "dbLayout.h"
|
||||
#include "dbLayoutUtils.h"
|
||||
#include "dbLayerMapping.h"
|
||||
|
|
@ -949,6 +950,11 @@ static std::vector<db::cell_index_type> caller_cells (const db::Cell *c)
|
|||
return std::vector<db::cell_index_type> (ids.begin (), ids.end ());
|
||||
}
|
||||
|
||||
static bool is_cold_proxy (const db::Cell *cell)
|
||||
{
|
||||
return dynamic_cast<const db::ColdProxy *> (cell) != 0;
|
||||
}
|
||||
|
||||
static bool is_library_cell (const db::Cell *cell)
|
||||
{
|
||||
return dynamic_cast<const db::LibraryProxy *> (cell) != 0;
|
||||
|
|
@ -974,6 +980,36 @@ static db::Library *library (const db::Cell *cell)
|
|||
}
|
||||
}
|
||||
|
||||
static std::string library_name (const db::Cell *cell)
|
||||
{
|
||||
const db::ColdProxy *cp = dynamic_cast<const db::ColdProxy *> (cell);
|
||||
if (cp) {
|
||||
return cp->context_info ().lib_name;
|
||||
} else {
|
||||
const db::Library *l = library (cell);
|
||||
if (l) {
|
||||
return l->get_name ();
|
||||
} else {
|
||||
return std::string ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static std::string library_cell_name (const db::Cell *cell)
|
||||
{
|
||||
const db::ColdProxy *cp = dynamic_cast<const db::ColdProxy *> (cell);
|
||||
if (cp) {
|
||||
return cp->context_info ().cell_name;
|
||||
} else {
|
||||
const db::Library *l = library (cell);
|
||||
if (l) {
|
||||
return l->layout ().cell_name (library_cell_index (cell));
|
||||
} else {
|
||||
return std::string ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void change_library_ref (db::Cell *cell, db::lib_id_type lib_id, db::cell_index_type cell_index)
|
||||
{
|
||||
db::LibraryProxy *l = dynamic_cast<db::LibraryProxy *> (cell);
|
||||
|
|
@ -1173,13 +1209,25 @@ static const std::vector<tl::Variant> &pcell_parameters (const db::Cell *cell)
|
|||
|
||||
static tl::Variant pcell_parameter (const db::Cell *cell, const std::string &name)
|
||||
{
|
||||
return cell->layout ()->get_pcell_parameter (cell->cell_index (), name);
|
||||
const db::ColdProxy *cp = dynamic_cast <const db::ColdProxy *> (cell);
|
||||
if (cp) {
|
||||
const auto &pp = cp->context_info ().pcell_parameters;
|
||||
auto i = pp.find (name);
|
||||
return i != pp.end () ? i->second : tl::Variant ();
|
||||
} else {
|
||||
return cell->layout ()->get_pcell_parameter (cell->cell_index (), name);
|
||||
}
|
||||
}
|
||||
|
||||
static std::map<std::string, tl::Variant> pcell_parameters_by_name (const db::Cell *cell)
|
||||
{
|
||||
tl_assert (cell->layout () != 0);
|
||||
return cell->layout ()->get_named_pcell_parameters (cell->cell_index ());
|
||||
const db::ColdProxy *cp = dynamic_cast <const db::ColdProxy *> (cell);
|
||||
if (cp) {
|
||||
return cp->context_info ().pcell_parameters;
|
||||
} else {
|
||||
tl_assert (cell->layout () != 0);
|
||||
return cell->layout ()->get_named_pcell_parameters (cell->cell_index ());
|
||||
}
|
||||
}
|
||||
|
||||
static void refresh (db::Cell *cell)
|
||||
|
|
@ -1203,6 +1251,21 @@ static const db::PCellDeclaration *pcell_declaration (const db::Cell *cell)
|
|||
}
|
||||
}
|
||||
|
||||
static std::string pcell_name (const db::Cell *cell)
|
||||
{
|
||||
const db::ColdProxy *cp = dynamic_cast <const db::ColdProxy *> (cell);
|
||||
if (cp) {
|
||||
return cp->context_info ().pcell_name;
|
||||
} else {
|
||||
const db::PCellDeclaration *pd = pcell_declaration (cell);
|
||||
if (pd) {
|
||||
return pd->name ();
|
||||
} else {
|
||||
return std::string ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const db::PCellDeclaration *pcell_declaration_of_inst (const db::Cell *cell, const db::Cell::instance_type &ref)
|
||||
{
|
||||
tl_assert (cell->layout () != 0);
|
||||
|
|
@ -3193,7 +3256,7 @@ Class<db::Cell> decl_Cell ("db", "Cell",
|
|||
"This method has been introduced in version 0.20.\n"
|
||||
) +
|
||||
gsi::method ("is_proxy?", &db::Cell::is_proxy,
|
||||
"@brief Returns true, if the cell presents some external entity \n"
|
||||
"@brief Returns true, if the cell presents some external entity\n"
|
||||
"A cell may represent some data which is imported from some other source, i.e.\n"
|
||||
"a library. Such cells are called \"proxy cells\". For a library reference, the\n"
|
||||
"proxy cell is some kind of pointer to the library and the cell within the library.\n"
|
||||
|
|
@ -3201,11 +3264,31 @@ Class<db::Cell> decl_Cell ("db", "Cell",
|
|||
"For PCells, this data can even be computed through some script.\n"
|
||||
"A PCell proxy represents all instances with a given set of parameters.\n"
|
||||
"\n"
|
||||
"Proxy cells cannot be modified, except that pcell parameters can be modified\n"
|
||||
"and PCell instances can be recomputed.\n"
|
||||
"Proxy cells should not be modified directly - i.e. the shapes or instances should not\n"
|
||||
"be touched. However, you can change PCell parameters (\\change_pcell_parameter, \\change_pcell_parameters)\n"
|
||||
"or change the library reference (\\change_ref).\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.22.\n"
|
||||
) +
|
||||
gsi::method_ext ("is_cold_proxy?", &is_cold_proxy,
|
||||
"@brief Returns true, if the cell is a 'cold proxy'\n"
|
||||
"Cold proxies are cells that refer to a library cell or PCell variant, but can temporarily not be resolved -\n"
|
||||
"for example, because the library is not installed. Such cells are basically placeholders\n"
|
||||
"for library references and also carry PCell parameter information needed to establish\n"
|
||||
"the link to the library PCell, once the library is available again.\n"
|
||||
"\n"
|
||||
"You can use \\library_name to obtain the name of the library the proxy points to, "
|
||||
"\\library_cell_name to obtain the cell name in that library, "
|
||||
"\\pcell_name to obtain the PCell name if it is a PCell proxy, "
|
||||
"and \\pcell_parameter or \\pcell_parameters_by_name to obtain the PCell parameters.\n"
|
||||
"\n"
|
||||
"Cold proxies cannot be created or modified. Cold proxies are basically error indicators "
|
||||
"and should be fixed by installing the respective library. Their layout state\n"
|
||||
"reflects the last version of the layout when the cell was functional and properly\n"
|
||||
"linked to a library. Still, they can be used in read-only applications.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.30.9.\n"
|
||||
) +
|
||||
gsi::method_ext ("is_library_cell?", &is_library_cell,
|
||||
"@brief Returns true, if the cell is a proxy cell pointing to a library cell\n"
|
||||
"If the cell is imported from some library, this attribute returns true.\n"
|
||||
|
|
@ -3231,10 +3314,32 @@ Class<db::Cell> decl_Cell ("db", "Cell",
|
|||
) +
|
||||
gsi::method_ext ("library", &library,
|
||||
"@brief Returns a reference to the library from which the cell is imported\n"
|
||||
"if the cell is not imported from a library, this reference is nil.\n"
|
||||
"If the cell is not imported from a library, this reference is nil.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.22.\n"
|
||||
) +
|
||||
gsi::method_ext ("library_cell_name", &library_cell_name,
|
||||
"@brief Returns the cell name inside the library from which the cell is imported\n"
|
||||
"If the cell is not imported from a library, the return value is an empty string.\n"
|
||||
"This method is basically a convenience function, equivalent to taking the name\n"
|
||||
"from \\library and \\library_cell_index.\n"
|
||||
"Note that for PCells, 'library_cell_name' is the name of the PCell proxy cell inside "
|
||||
"the library, not the name of the PCell.\n"
|
||||
"\n"
|
||||
"However, this method also works for 'cold proxies' (see \\is_cold_proxy?)\n"
|
||||
"for which it delivers the name of cell inside the (missing) library.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.30.8.\n"
|
||||
) +
|
||||
gsi::method_ext ("library_name", &library_name,
|
||||
"@brief Returns the name of the library from which the cell is imported\n"
|
||||
"If the cell is not imported from a library, the return value is an empty string.\n"
|
||||
"This method is basically a convenience function, equivalent to taking the name\n"
|
||||
"from \\library. However, this method also works for 'cold proxies' (see \\is_cold_proxy?)\n"
|
||||
"for which it delivers the name of the (missing) library.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.30.8.\n"
|
||||
) +
|
||||
gsi::method_ext ("change_ref", &change_library_ref, gsi::arg ("lib_id"), gsi::arg ("lib_cell_index"),
|
||||
"@brief Changes the reference to a different library cell\n"
|
||||
"This method requires a cell that is a library reference (i.e. \\is_library_cell? is true). It will "
|
||||
|
|
@ -3307,6 +3412,9 @@ Class<db::Cell> decl_Cell ("db", "Cell",
|
|||
"If the cell is not a PCell variant or the name is not a valid PCell parameter name, "
|
||||
"the return value is nil.\n"
|
||||
"\n"
|
||||
"This method also works for 'cold proxies' (see \\is_cold_proxy?)\n"
|
||||
"for which it delivers the value of the given stored PCell parameter.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.25."
|
||||
) +
|
||||
gsi::method_ext ("pcell_parameters_by_name", &pcell_parameters_by_name,
|
||||
|
|
@ -3316,8 +3424,20 @@ Class<db::Cell> decl_Cell ("db", "Cell",
|
|||
"method returns an empty dictionary. This method also returns the PCell parameters if\n"
|
||||
"the cell is a PCell imported from a library.\n"
|
||||
"\n"
|
||||
"This method also works for 'cold proxies' (see \\is_cold_proxy?)\n"
|
||||
"for which it delivers the names and values of the stored PCell parameters.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.24.\n"
|
||||
) +
|
||||
gsi::method_ext ("pcell_name", &pcell_name,
|
||||
"@brief Returns the PCell name if the cell is a PCell variant\n"
|
||||
"If this cell is not a PCell variant, this method returns an empty string.\n"
|
||||
"This method is basically a convenience function, equivalent to taking the name\n"
|
||||
"from \\pcell_declaration. However, this method also works for 'cold proxies' (see \\is_cold_proxy?)\n"
|
||||
"for which it delivers the name of the (missing) PCell.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.30.9.\n"
|
||||
) +
|
||||
gsi::method_ext ("pcell_declaration", &pcell_declaration,
|
||||
"@brief Returns a reference to the PCell declaration\n"
|
||||
"If this cell is not a PCell variant, this method returns nil.\n"
|
||||
|
|
|
|||
|
|
@ -642,12 +642,22 @@ static tl::Variant get_property_from_id (db::properties_id_type id, const tl::Va
|
|||
}
|
||||
|
||||
static void
|
||||
delete_cells (db::Layout *layout, const std::vector<db::cell_index_type> &cell_indices)
|
||||
delete_cells (db::Layout *layout, const std::vector<db::cell_index_type> &cell_indexes)
|
||||
{
|
||||
for (auto ci = cell_indices.begin (); ci != cell_indices.end (); ++ci) {
|
||||
for (auto ci = cell_indexes.begin (); ci != cell_indexes.end (); ++ci) {
|
||||
check_cell_index (layout, *ci);
|
||||
}
|
||||
layout->delete_cells (cell_indices.begin (), cell_indices.end ());
|
||||
layout->delete_cells (cell_indexes.begin (), cell_indexes.end ());
|
||||
}
|
||||
|
||||
static void
|
||||
delete_cells_ptr (db::Layout *layout, const std::vector<db::Cell *> &cells)
|
||||
{
|
||||
std::set<db::cell_index_type> cell_indexes;
|
||||
for (auto c = cells.begin (); c != cells.end (); ++c) {
|
||||
cell_indexes.insert ((*c)->cell_index ());
|
||||
}
|
||||
layout->delete_cells (cell_indexes);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -657,20 +667,76 @@ delete_cell_rec (db::Layout *layout, db::cell_index_type cell_index)
|
|||
layout->delete_cell_rec (cell_index);
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
delete_cell_rec_ptr (db::Layout *layout, db::Cell *cell)
|
||||
{
|
||||
layout->delete_cell_rec (cell->cell_index ());
|
||||
}
|
||||
|
||||
static void
|
||||
prune_cell (db::Layout *layout, db::cell_index_type cell_index, int levels)
|
||||
{
|
||||
check_cell_index (layout, cell_index);
|
||||
layout->prune_cell (cell_index, levels);
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
prune_cell_ptr (db::Layout *layout, db::Cell *cell, int levels)
|
||||
{
|
||||
layout->prune_cell (cell->cell_index (), levels);
|
||||
}
|
||||
|
||||
static void
|
||||
prune_cells (db::Layout *layout, const std::vector<db::cell_index_type> &cell_indexes, int levels)
|
||||
{
|
||||
for (auto ci = cell_indexes.begin (); ci != cell_indexes.end (); ++ci) {
|
||||
check_cell_index (layout, *ci);
|
||||
}
|
||||
layout->prune_cells (cell_indexes.begin (), cell_indexes.end (), levels);
|
||||
}
|
||||
|
||||
static void
|
||||
prune_cells_ptr (db::Layout *layout, const std::vector<db::Cell *> &cells, int levels)
|
||||
{
|
||||
std::set<db::cell_index_type> cell_indexes;
|
||||
for (auto c = cells.begin (); c != cells.end (); ++c) {
|
||||
cell_indexes.insert ((*c)->cell_index ());
|
||||
}
|
||||
layout->prune_cells (cell_indexes, levels);
|
||||
}
|
||||
|
||||
static void
|
||||
prune_subcells (db::Layout *layout, db::cell_index_type cell_index, int levels)
|
||||
{
|
||||
check_cell_index (layout, cell_index);
|
||||
layout->prune_subcells (cell_index, levels);
|
||||
}
|
||||
|
||||
static void
|
||||
prune_subcells_ptr (db::Layout *layout, db::Cell *cell, int levels)
|
||||
{
|
||||
layout->prune_subcells (cell->cell_index (), levels);
|
||||
}
|
||||
|
||||
static void
|
||||
prune_subcells_many (db::Layout *layout, const std::vector<db::cell_index_type> &cell_indexes, int levels)
|
||||
{
|
||||
for (auto ci = cell_indexes.begin (); ci != cell_indexes.end (); ++ci) {
|
||||
check_cell_index (layout, *ci);
|
||||
}
|
||||
layout->prune_subcells (cell_indexes.begin (), cell_indexes.end (), levels);
|
||||
}
|
||||
|
||||
static void
|
||||
prune_subcells_many_ptr (db::Layout *layout, const std::vector<db::Cell *> &cells, int levels)
|
||||
{
|
||||
std::set<db::cell_index_type> cell_indexes;
|
||||
for (auto c = cells.begin (); c != cells.end (); ++c) {
|
||||
cell_indexes.insert ((*c)->cell_index ());
|
||||
}
|
||||
layout->prune_subcells (cell_indexes, levels);
|
||||
}
|
||||
|
||||
static void
|
||||
flatten (db::Layout *layout, db::cell_index_type cell_index, int levels, bool prune)
|
||||
{
|
||||
|
|
@ -678,7 +744,16 @@ flatten (db::Layout *layout, db::cell_index_type cell_index, int levels, bool pr
|
|||
layout->flatten (layout->cell (cell_index), levels, prune);
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
flatten_ptr (db::Layout *layout, db::Cell *cell, int levels, bool prune)
|
||||
{
|
||||
if (! cell) {
|
||||
return;
|
||||
}
|
||||
layout->flatten (*cell, levels, prune);
|
||||
}
|
||||
|
||||
static void
|
||||
flatten_into (db::Layout *layout, db::cell_index_type cell_index, db::cell_index_type target_cell_index, const db::ICplxTrans &t, int levels)
|
||||
{
|
||||
check_cell_index (layout, cell_index);
|
||||
|
|
@ -686,7 +761,16 @@ flatten_into (db::Layout *layout, db::cell_index_type cell_index, db::cell_index
|
|||
layout->flatten (layout->cell (cell_index), layout->cell (target_cell_index), t, levels);
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
flatten_into_ptr (db::Layout *layout, db::Cell *cell, db::Cell *target_cell, const db::ICplxTrans &t, int levels)
|
||||
{
|
||||
if (! cell || ! target_cell) {
|
||||
return;
|
||||
}
|
||||
layout->flatten (*cell, *target_cell, t, levels);
|
||||
}
|
||||
|
||||
static void
|
||||
write_simple (db::Layout *layout, const std::string &filename)
|
||||
{
|
||||
db::SaveLayoutOptions options;
|
||||
|
|
@ -866,6 +950,11 @@ static void delete_cell (db::Layout *ly, db::cell_index_type ci)
|
|||
ly->delete_cell (ci);
|
||||
}
|
||||
|
||||
static void delete_cell_ptr (db::Layout *ly, db::Cell *cell)
|
||||
{
|
||||
ly->delete_cell (cell->cell_index ());
|
||||
}
|
||||
|
||||
static void rename_cell (db::Layout *ly, db::cell_index_type ci, const std::string &name)
|
||||
{
|
||||
check_cell_index (ly, ci);
|
||||
|
|
@ -1655,6 +1744,20 @@ Class<db::Layout> decl_Layout ("db", "Layout",
|
|||
"\n"
|
||||
"This method has been introduced in version 0.20.\n"
|
||||
) +
|
||||
gsi::method_ext ("delete_cell", &delete_cell_ptr, gsi::arg ("cell"),
|
||||
"@brief Deletes a cell\n"
|
||||
"\n"
|
||||
"This deletes a cell but not the sub cells of the cell.\n"
|
||||
"These subcells will likely become new top cells unless they are used\n"
|
||||
"otherwise.\n"
|
||||
"All instances of this cell are deleted as well.\n"
|
||||
"Hint: to delete multiple cells, use \"delete_cells\" which is \n"
|
||||
"far more efficient in this case.\n"
|
||||
"\n"
|
||||
"@param cell The cell to delete\n"
|
||||
"\n"
|
||||
"This convenience variant taking a cell object has been introduced in version 0.30.9.\n"
|
||||
) +
|
||||
gsi::method_ext ("delete_cells", &delete_cells, gsi::arg ("cell_index_list"),
|
||||
"@brief Deletes multiple cells\n"
|
||||
"\n"
|
||||
|
|
@ -1667,19 +1770,73 @@ Class<db::Layout> decl_Layout ("db", "Layout",
|
|||
"\n"
|
||||
"This method has been introduced in version 0.20.\n"
|
||||
) +
|
||||
gsi::method_ext ("prune_subcells", &prune_subcells, gsi::arg ("cell_index"), gsi::arg ("levels"),
|
||||
gsi::method_ext ("delete_cells", &delete_cells_ptr, gsi::arg ("cell_list"),
|
||||
"@brief Deletes multiple cells\n"
|
||||
"\n"
|
||||
"This deletes the cells but not the sub cells of these cells.\n"
|
||||
"These subcells will likely become new top cells unless they are used\n"
|
||||
"otherwise.\n"
|
||||
"All instances of these cells are deleted as well.\n"
|
||||
"\n"
|
||||
"@param cell_list An list of cells to delete\n"
|
||||
"\n"
|
||||
"This convenience variant taking a list of cell objects has been introduced in version 0.30.9.\n"
|
||||
) +
|
||||
gsi::method_ext ("prune_subcells", &prune_subcells, gsi::arg ("cell_index"), gsi::arg ("levels", -1),
|
||||
"@brief Deletes all sub cells of the cell which are not used otherwise down to the specified level of hierarchy\n"
|
||||
"\n"
|
||||
"This deletes all sub cells of the cell which are not used otherwise.\n"
|
||||
"All instances of the deleted cells are deleted as well.\n"
|
||||
"It is possible to specify how many levels of hierarchy below the given root cell are considered.\n"
|
||||
"\n"
|
||||
"A variant exists that takes a list of cell indexes and which is more efficient than calling\n"
|
||||
"'prune_subcells' multiple times on a single cell.\n"
|
||||
"\n"
|
||||
"@param cell_index The root cell from which to delete a sub cells\n"
|
||||
"@param levels The number of hierarchy levels to consider (-1: all, 0: none, 1: one level etc.)\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.20.\n"
|
||||
) +
|
||||
gsi::method_ext ("prune_cell", &prune_cell, gsi::arg ("cell_index"), gsi::arg ("levels"),
|
||||
gsi::method_ext ("prune_subcells", &prune_subcells_ptr, gsi::arg ("cell"), gsi::arg ("levels", -1),
|
||||
"@brief Deletes all sub cells of the cell which are not used otherwise down to the specified level of hierarchy\n"
|
||||
"\n"
|
||||
"This deletes all sub cells of the cell which are not used otherwise.\n"
|
||||
"All instances of the deleted cells are deleted as well.\n"
|
||||
"It is possible to specify how many levels of hierarchy below the given root cell are considered.\n"
|
||||
"\n"
|
||||
"A variant exists that takes a list of cells and which is more efficient than calling\n"
|
||||
"'prune_subcells' multiple times on a single cell.\n"
|
||||
"\n"
|
||||
"@param cell The root cell from which to delete a sub cells\n"
|
||||
"@param levels The number of hierarchy levels to consider (-1: all, 0: none, 1: one level etc.)\n"
|
||||
"\n"
|
||||
"This convenience variant taking a list of cell objects has been introduced in version 0.30.9.\n"
|
||||
) +
|
||||
gsi::method_ext ("prune_subcells", &prune_subcells_many, gsi::arg ("cell_index_list"), gsi::arg ("levels", -1),
|
||||
"@brief Deletes all sub cells of the given cells which are not used otherwise down to the specified level of hierarchy\n"
|
||||
"\n"
|
||||
"This deletes all sub cells of the given cells which are not used otherwise.\n"
|
||||
"All instances of the deleted cells are deleted as well.\n"
|
||||
"It is possible to specify how many levels of hierarchy below the given root cell are considered.\n"
|
||||
"\n"
|
||||
"@param cell_index_list The root cells from which to delete the sub cells\n"
|
||||
"@param levels The number of hierarchy levels to consider (-1: all, 0: none, 1: one level etc.)\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.30.9.\n"
|
||||
) +
|
||||
gsi::method_ext ("prune_subcells", &prune_subcells_many_ptr, gsi::arg ("cell_list"), gsi::arg ("levels", -1),
|
||||
"@brief Deletes all sub cells of the given cells which are not used otherwise down to the specified level of hierarchy\n"
|
||||
"\n"
|
||||
"This deletes all sub cells of the given cells which are not used otherwise.\n"
|
||||
"All instances of the deleted cells are deleted as well.\n"
|
||||
"It is possible to specify how many levels of hierarchy below the given root cell are considered.\n"
|
||||
"\n"
|
||||
"@param cell_list The root cells from which to delete the sub cells\n"
|
||||
"@param levels The number of hierarchy levels to consider (-1: all, 0: none, 1: one level etc.)\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.30.9.\n"
|
||||
) +
|
||||
gsi::method_ext ("prune_cell", &prune_cell, gsi::arg ("cell_index"), gsi::arg ("levels", -1),
|
||||
"@brief Deletes a cell plus subcells not used otherwise\n"
|
||||
"\n"
|
||||
"This deletes a cell and also all sub cells of the cell which are not used otherwise.\n"
|
||||
|
|
@ -1687,10 +1844,53 @@ Class<db::Layout> decl_Layout ("db", "Layout",
|
|||
"only the direct children of the cell are deleted with the cell itself.\n"
|
||||
"All instances of this cell are deleted as well.\n"
|
||||
"\n"
|
||||
"A version that allows pruning multiple cells in one call is \\prune_cells.\n"
|
||||
"\n"
|
||||
"@param cell_index The index of the cell to delete\n"
|
||||
"@param levels The number of hierarchy levels to consider (-1: all, 0: none, 1: one level etc.)\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.20.\n"
|
||||
"This method has been introduced in version 0.20. The 'levels' argument was made optional in version 0.30.9.\n"
|
||||
) +
|
||||
gsi::method_ext ("prune_cell", &prune_cell_ptr, gsi::arg ("cell"), gsi::arg ("levels", -1),
|
||||
"@brief Deletes a cell plus subcells not used otherwise\n"
|
||||
"\n"
|
||||
"This deletes a cell and also all sub cells of the cell which are not used otherwise.\n"
|
||||
"The number of hierarchy levels to consider can be specified as well. One level of hierarchy means that "
|
||||
"only the direct children of the cell are deleted with the cell itself.\n"
|
||||
"All instances of this cell are deleted as well.\n"
|
||||
"\n"
|
||||
"A version that allows pruning multiple cells in one call is \\prune_cells.\n"
|
||||
"\n"
|
||||
"@param cell The cell to delete\n"
|
||||
"@param levels The number of hierarchy levels to consider (-1: all, 0: none, 1: one level etc.)\n"
|
||||
"\n"
|
||||
"This convenience variant taking a cell object has been introduced in version 0.30.9.\n"
|
||||
) +
|
||||
gsi::method_ext ("prune_cells", &prune_cells, gsi::arg ("cell_indexes"), gsi::arg ("levels", -1),
|
||||
"@brief Deletes cells plus subcells not used otherwise\n"
|
||||
"\n"
|
||||
"This deletes the given cells and also all sub cells of the cells which are not used otherwise.\n"
|
||||
"The number of hierarchy levels to consider can be specified as well. One level of hierarchy means that "
|
||||
"only the direct children of the cell are deleted with the cell itself.\n"
|
||||
"All instances of the pruned cells are deleted as well.\n"
|
||||
"\n"
|
||||
"@param cell_indexes The indexes of the cells to delete\n"
|
||||
"@param levels The number of hierarchy levels to consider (-1: all, 0: none, 1: one level etc.)\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.30.9.\n"
|
||||
) +
|
||||
gsi::method_ext ("prune_cells", &prune_cells_ptr, gsi::arg ("cells"), gsi::arg ("levels", -1),
|
||||
"@brief Deletes cells plus subcells not used otherwise\n"
|
||||
"\n"
|
||||
"This deletes the given cells and also all sub cells of the cells which are not used otherwise.\n"
|
||||
"The number of hierarchy levels to consider can be specified as well. One level of hierarchy means that "
|
||||
"only the direct children of the cell are deleted with the cell itself.\n"
|
||||
"All instances of the pruned cells are deleted as well.\n"
|
||||
"\n"
|
||||
"@param cells The cells to delete\n"
|
||||
"@param levels The number of hierarchy levels to consider (-1: all, 0: none, 1: one level etc.)\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.30.9.\n"
|
||||
) +
|
||||
gsi::method_ext ("delete_cell_rec", &delete_cell_rec, gsi::arg ("cell_index"),
|
||||
"@brief Deletes a cell plus all subcells\n"
|
||||
|
|
@ -1702,6 +1902,16 @@ Class<db::Layout> decl_Layout ("db", "Layout",
|
|||
"\n"
|
||||
"This method has been introduced in version 0.20.\n"
|
||||
) +
|
||||
gsi::method_ext ("delete_cell_rec", &delete_cell_rec_ptr, gsi::arg ("cell"),
|
||||
"@brief Deletes a cell plus all subcells\n"
|
||||
"\n"
|
||||
"This deletes a cell and also all sub cells of the cell.\n"
|
||||
"In contrast to \\prune_cell, all cells are deleted together with their instances even if they are used otherwise.\n"
|
||||
"\n"
|
||||
"@param cell The cell to delete\n"
|
||||
"\n"
|
||||
"This convenience variant taking a cell object has been introduced in version 0.30.9.\n"
|
||||
) +
|
||||
gsi::method_ext ("insert", &insert_region,
|
||||
gsi::arg ("cell_index"), gsi::arg ("layer"), gsi::arg ("region"),
|
||||
"@brief Inserts a region into the given cell and layer\n"
|
||||
|
|
@ -1750,7 +1960,7 @@ Class<db::Layout> decl_Layout ("db", "Layout",
|
|||
"\n"
|
||||
"This method has been introduced in version 0.27.\n"
|
||||
) +
|
||||
gsi::method_ext ("flatten", &flatten, gsi::arg ("cell_index"), gsi::arg ("levels"), gsi::arg ("prune"),
|
||||
gsi::method_ext ("flatten", &flatten, gsi::arg ("cell_index"), gsi::arg ("levels", -1), gsi::arg ("prune", true),
|
||||
"@brief Flattens the given cell\n"
|
||||
"\n"
|
||||
"This method propagates all shapes and instances from the specified number of hierarchy levels below into the given cell.\n"
|
||||
|
|
@ -1761,9 +1971,22 @@ Class<db::Layout> decl_Layout ("db", "Layout",
|
|||
"@param levels The number of hierarchy levels to flatten (-1: all, 0: none, 1: one level etc.)\n"
|
||||
"@param prune Set to true to remove orphan cells.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.20.\n"
|
||||
"This method has been introduced in version 0.20. The 'levels' and 'prune' arguments have been made optional in version 0.30.9.\n"
|
||||
) +
|
||||
gsi::method_ext ("flatten_into", &flatten_into, gsi::arg ("source_cell_index"), gsi::arg ("target_cell_index"), gsi::arg ("trans"), gsi::arg ("levels"),
|
||||
gsi::method_ext ("flatten", &flatten_ptr, gsi::arg ("cell"), gsi::arg ("levels", -1), gsi::arg ("prune", true),
|
||||
"@brief Flattens the given cell\n"
|
||||
"\n"
|
||||
"This method propagates all shapes and instances from the specified number of hierarchy levels below into the given cell.\n"
|
||||
"It also removes the instances of the cells from which the shapes came from, but does not remove the cells themselves if prune is set to false.\n"
|
||||
"If prune is set to true, these cells are removed if not used otherwise.\n"
|
||||
"\n"
|
||||
"@param cell The cell which should be flattened\n"
|
||||
"@param levels The number of hierarchy levels to flatten (-1: all, 0: none, 1: one level etc.)\n"
|
||||
"@param prune Set to true to remove orphan cells.\n"
|
||||
"\n"
|
||||
"This convenience variant taking a cell object has been introduced in version 0.30.9.\n"
|
||||
) +
|
||||
gsi::method_ext ("flatten_into", &flatten_into, gsi::arg ("source_cell_index"), gsi::arg ("target_cell_index"), gsi::arg ("trans", db::ICplxTrans (), "unity"), gsi::arg ("levels", -1),
|
||||
"@brief Flattens the given cell into another cell\n"
|
||||
"\n"
|
||||
"This method works like 'flatten', but allows specification of a target cell which can be different from the source cell plus "
|
||||
|
|
@ -1776,7 +1999,22 @@ Class<db::Layout> decl_Layout ("db", "Layout",
|
|||
"@param trans The transformation to apply on the output shapes and instances\n"
|
||||
"@param levels The number of hierarchy levels to flatten (-1: all, 0: none, 1: one level etc.)\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.24.\n"
|
||||
"This method has been introduced in version 0.24. The 'trans' and 'levels' arguments have been made optional is version 0.30.9.\n"
|
||||
) +
|
||||
gsi::method_ext ("flatten_into", &flatten_into_ptr, gsi::arg ("source_cell"), gsi::arg ("target_cell"), gsi::arg ("trans", db::ICplxTrans (), "unity"), gsi::arg ("levels", -1),
|
||||
"@brief Flattens the given cell into another cell\n"
|
||||
"\n"
|
||||
"This method works like 'flatten', but allows specification of a target cell which can be different from the source cell plus "
|
||||
"a transformation which is applied for all shapes and instances in the target cell.\n"
|
||||
"\n"
|
||||
"In contrast to the 'flatten' method, the source cell is not modified.\n"
|
||||
"\n"
|
||||
"@param source_cell The source cell which should be flattened\n"
|
||||
"@param target_cell The target cell into which the resulting objects are written\n"
|
||||
"@param trans The transformation to apply on the output shapes and instances\n"
|
||||
"@param levels The number of hierarchy levels to flatten (-1: all, 0: none, 1: one level etc.)\n"
|
||||
"\n"
|
||||
"This convenience variant taking a cell objects has been introduced in version 0.30.9.\n"
|
||||
) +
|
||||
gsi::method ("start_changes", &db::Layout::start_changes,
|
||||
"@brief Signals the start of an operation bringing the layout into invalid state\n"
|
||||
|
|
|
|||
|
|
@ -335,34 +335,21 @@ class DBLayoutTests1_TestClass < TestBase
|
|||
c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0))))
|
||||
assert_equal(c0.is_empty?, false)
|
||||
|
||||
c0_index = c0.cell_index
|
||||
|
||||
assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)");
|
||||
|
||||
c0_index = c0.cell_index
|
||||
ll = l.dup
|
||||
assert_equal(l.is_valid_cell_index?(c0_index), true)
|
||||
l.delete_cell(c0.cell_index)
|
||||
l.delete_cell(c0_index)
|
||||
assert_equal(l.is_valid_cell_index?(c0_index), false)
|
||||
|
||||
assert_equal(collect_hier(l), "[c1](P=)(C=)/[c2](P=)(C=c3)/[c3](P=c2)(C=)");
|
||||
assert_equal(c3.is_empty?, true)
|
||||
|
||||
l = RBA::Layout.new
|
||||
l.insert_layer_at(0, RBA::LayerInfo.new(1, 0))
|
||||
c0 = l.cell(l.add_cell("c0"))
|
||||
c1 = l.cell(l.add_cell("c1"))
|
||||
c2 = l.cell(l.add_cell("c2"))
|
||||
c3 = l.cell(l.add_cell("c3"))
|
||||
assert_equal(c0.is_empty?, true)
|
||||
l = ll
|
||||
ll = l.dup
|
||||
|
||||
tt = RBA::Trans.new
|
||||
c0.insert(RBA::CellInstArray.new(c1.cell_index, tt))
|
||||
c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100))))
|
||||
c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1)))
|
||||
c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0))))
|
||||
assert_equal(c0.is_empty?, false)
|
||||
|
||||
assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)");
|
||||
|
||||
c0_index = c0.cell_index
|
||||
assert_equal(l.is_valid_cell_index?(c0_index), true)
|
||||
l.cell(c0_index).delete
|
||||
assert_equal(l.is_valid_cell_index?(c0_index), false)
|
||||
|
|
@ -370,6 +357,16 @@ class DBLayoutTests1_TestClass < TestBase
|
|||
assert_equal(collect_hier(l), "[c1](P=)(C=)/[c2](P=)(C=c3)/[c3](P=c2)(C=)");
|
||||
assert_equal(c3.is_empty?, true)
|
||||
|
||||
l = ll
|
||||
ll = l.dup
|
||||
|
||||
assert_equal(l.is_valid_cell_index?(c0_index), true)
|
||||
# with cell object
|
||||
l.delete_cell(l.cell(c0_index))
|
||||
assert_equal(l.is_valid_cell_index?(c0_index), false)
|
||||
assert_equal(collect_hier(l), "[c1](P=)(C=)/[c2](P=)(C=c3)/[c3](P=c2)(C=)");
|
||||
assert_equal(c3.is_empty?, true)
|
||||
|
||||
end
|
||||
|
||||
def test_5b
|
||||
|
|
@ -413,10 +410,17 @@ class DBLayoutTests1_TestClass < TestBase
|
|||
assert_equal(collect_hier(l), "[c1](P=)(C=)/[c3](P=)(C=)");
|
||||
|
||||
l = ll
|
||||
ll = l.dup
|
||||
# Hint: even though we deleted c0 and c2, their indices are still valid
|
||||
l.delete_cells([c2_index, c0_index])
|
||||
assert_equal(collect_hier(l), "[c1](P=)(C=)/[c3](P=)(C=)");
|
||||
|
||||
l = ll
|
||||
ll = l.dup
|
||||
# with cell objects
|
||||
l.delete_cells([l.cell(c2_index), l.cell(c0_index)])
|
||||
assert_equal(collect_hier(l), "[c1](P=)(C=)/[c3](P=)(C=)");
|
||||
|
||||
end
|
||||
|
||||
def test_5d
|
||||
|
|
@ -487,6 +491,7 @@ class DBLayoutTests1_TestClass < TestBase
|
|||
|
||||
c0_index = c0.cell_index
|
||||
c2_index = c2.cell_index
|
||||
c3_index = c3.cell_index
|
||||
|
||||
ll = l.dup
|
||||
|
||||
|
|
@ -499,6 +504,42 @@ class DBLayoutTests1_TestClass < TestBase
|
|||
l.cell(c2_index).prune_cell(-1)
|
||||
assert_equal(collect_hier(l), "[c0](P=)(C=c1,c3)/[c1](P=c0)(C=)/[c3](P=c0)(C=)");
|
||||
|
||||
l = ll
|
||||
ll = l.dup
|
||||
# As method of Layout
|
||||
l.prune_cell(c2_index, -1)
|
||||
assert_equal(collect_hier(l), "[c0](P=)(C=c1,c3)/[c1](P=c0)(C=)/[c3](P=c0)(C=)");
|
||||
|
||||
l = ll
|
||||
ll = l.dup
|
||||
# As method of Layout with default argument
|
||||
l.prune_cell(c2_index)
|
||||
assert_equal(collect_hier(l), "[c0](P=)(C=c1,c3)/[c1](P=c0)(C=)/[c3](P=c0)(C=)");
|
||||
|
||||
l = ll
|
||||
ll = l.dup
|
||||
# As method of Layout with cell object
|
||||
l.prune_cell(l.cell(c2_index), -1)
|
||||
assert_equal(collect_hier(l), "[c0](P=)(C=c1,c3)/[c1](P=c0)(C=)/[c3](P=c0)(C=)");
|
||||
|
||||
l = ll
|
||||
ll = l.dup
|
||||
# As method of Layout with cell object and default argument
|
||||
l.prune_cell(l.cell(c2_index), -1)
|
||||
assert_equal(collect_hier(l), "[c0](P=)(C=c1,c3)/[c1](P=c0)(C=)/[c3](P=c0)(C=)");
|
||||
|
||||
l = ll
|
||||
ll = l.dup
|
||||
# prune c2 and c3
|
||||
l.prune_cells([ c2_index, c3_index ], -1)
|
||||
assert_equal(collect_hier(l), "[c0](P=)(C=c1)/[c1](P=c0)(C=)");
|
||||
|
||||
l = ll
|
||||
ll = l.dup
|
||||
# prune c2 and c3 with cell objects
|
||||
l.prune_cells([ l.cell(c2_index), l.cell(c3_index) ], -1)
|
||||
assert_equal(collect_hier(l), "[c0](P=)(C=c1)/[c1](P=c0)(C=)");
|
||||
|
||||
end
|
||||
|
||||
def test_5e
|
||||
|
|
@ -546,6 +587,12 @@ class DBLayoutTests1_TestClass < TestBase
|
|||
l.delete_cell_rec(c2_index)
|
||||
assert_equal(collect_hier(l), "[c0](P=)(C=c1)/[c1](P=c0)(C=)");
|
||||
|
||||
l = ll
|
||||
ll = l.dup
|
||||
# with cell object
|
||||
l.delete_cell_rec(l.cell(c2_index))
|
||||
assert_equal(collect_hier(l), "[c0](P=)(C=c1)/[c1](P=c0)(C=)");
|
||||
|
||||
end
|
||||
|
||||
def test_5f
|
||||
|
|
@ -589,12 +636,38 @@ class DBLayoutTests1_TestClass < TestBase
|
|||
|
||||
l = ll
|
||||
ll = l.dup
|
||||
l.flatten(c0_index, -1, true)
|
||||
l.flatten(c0_index)
|
||||
assert_equal(collect_hier(l), "[c0](P=)(C=)");
|
||||
|
||||
ii = l.begin_shapes(c0_index, 0);
|
||||
assert_equal(collect(ii, l), "[c0](0,100;1000,1200)/[c0](0,100;1000,1200)/[c0](100,0;1100,1100)/[c0](1200,0;2200,1100)/[c0](-1200,0;-100,1000)");
|
||||
|
||||
l = ll
|
||||
ll = l.dup
|
||||
c0flat = l.create_cell("c0flat")
|
||||
l.flatten_into(c0_index, c0flat.cell_index)
|
||||
assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)/[c0flat](P=)(C=)");
|
||||
|
||||
ii = l.begin_shapes(c0flat, 0);
|
||||
assert_equal(collect(ii, l), "[c0flat](0,100;1000,1200)/[c0flat](0,100;1000,1200)/[c0flat](100,0;1100,1100)/[c0flat](1200,0;2200,1100)/[c0flat](-1200,0;-100,1000)");
|
||||
|
||||
l = ll
|
||||
ll = l.dup
|
||||
l.flatten(l.cell(c0_index), -1, true) # with cell object
|
||||
assert_equal(collect_hier(l), "[c0](P=)(C=)");
|
||||
|
||||
ii = l.begin_shapes(c0_index, 0);
|
||||
assert_equal(collect(ii, l), "[c0](0,100;1000,1200)/[c0](0,100;1000,1200)/[c0](100,0;1100,1100)/[c0](1200,0;2200,1100)/[c0](-1200,0;-100,1000)");
|
||||
|
||||
l = ll
|
||||
ll = l.dup
|
||||
c0flat = l.create_cell("c0flat")
|
||||
l.flatten_into(l.cell(c0_index), c0flat, RBA::ICplxTrans::new(2.0), -1)
|
||||
assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=c3)/[c3](P=c0,c2)(C=)/[c0flat](P=)(C=)");
|
||||
|
||||
ii = l.begin_shapes(c0flat, 0);
|
||||
assert_equal(collect(ii, l), "[c0flat](0,200;2000,2400)/[c0flat](0,200;2000,2400)/[c0flat](200,0;2200,2200)/[c0flat](2400,0;4400,2200)/[c0flat](-2400,0;-200,2000)");
|
||||
|
||||
l = ll
|
||||
ll = l.dup
|
||||
l.flatten(c0_index, 0, false)
|
||||
|
|
@ -748,10 +821,59 @@ class DBLayoutTests1_TestClass < TestBase
|
|||
assert_equal(collect_hier(l), "[c0](P=)(C=c1,c2,c3)/[c1](P=c0)(C=)/[c2](P=c0)(C=)/[c3](P=c0)(C=)");
|
||||
|
||||
l = ll
|
||||
ll = l.dup
|
||||
# Hint: even though we deleted c0 and c2, their indices are still valid
|
||||
l.cell(c0_index).prune_subcells(1)
|
||||
assert_equal(collect_hier(l), "[c0](P=)(C=)");
|
||||
|
||||
l = ll
|
||||
ll = l.dup
|
||||
# As method of Layout
|
||||
l.prune_subcells(c0_index, -1)
|
||||
assert_equal(collect_hier(l), "[c0](P=)(C=)");
|
||||
|
||||
l = ll
|
||||
ll = l.dup
|
||||
# As method of Layout with default argument
|
||||
l.prune_subcells(c0_index)
|
||||
assert_equal(collect_hier(l), "[c0](P=)(C=)");
|
||||
|
||||
l = ll
|
||||
ll = l.dup
|
||||
# As method of Layout with Cell object
|
||||
l.prune_subcells(l.cell(c0_index), -1)
|
||||
assert_equal(collect_hier(l), "[c0](P=)(C=)");
|
||||
|
||||
l = ll
|
||||
ll = l.dup
|
||||
# As method of Layout with Cell object and default argument
|
||||
l.prune_subcells(l.cell(c0_index))
|
||||
assert_equal(collect_hier(l), "[c0](P=)(C=)");
|
||||
|
||||
l = ll
|
||||
ll = l.dup
|
||||
# As method of Layout with multiple cells
|
||||
l.prune_subcells([ c0_index ], -1)
|
||||
assert_equal(collect_hier(l), "[c0](P=)(C=)");
|
||||
|
||||
l = ll
|
||||
ll = l.dup
|
||||
# As method of Layout with multiple cells and default argument
|
||||
l.prune_subcells([ c0_index ])
|
||||
assert_equal(collect_hier(l), "[c0](P=)(C=)");
|
||||
|
||||
l = ll
|
||||
ll = l.dup
|
||||
# As method of Layout with multiple cells and Cell object
|
||||
l.prune_subcells([ l.cell(c0_index) ], -1)
|
||||
assert_equal(collect_hier(l), "[c0](P=)(C=)");
|
||||
|
||||
l = ll
|
||||
ll = l.dup
|
||||
# As method of Layout with multiple cells and Cell object and default argument
|
||||
l.prune_subcells([ l.cell(c0_index) ])
|
||||
assert_equal(collect_hier(l), "[c0](P=)(C=)");
|
||||
|
||||
end
|
||||
|
||||
def test_6
|
||||
|
|
@ -2365,7 +2487,7 @@ class DBLayoutTests1_TestClass < TestBase
|
|||
end
|
||||
|
||||
# Properties IDs
|
||||
def test_issue1549
|
||||
def test_propertyIDs
|
||||
|
||||
ly = RBA::Layout::new
|
||||
|
||||
|
|
|
|||
|
|
@ -277,7 +277,7 @@ end
|
|||
|
||||
class DBPCellAPI_TestClass < TestBase
|
||||
|
||||
def _test_1
|
||||
def test_1
|
||||
|
||||
# PCellParameterDeclaration
|
||||
|
||||
|
|
@ -351,7 +351,7 @@ end
|
|||
|
||||
class DBPCell_TestClass < TestBase
|
||||
|
||||
def _test_1
|
||||
def test_1
|
||||
|
||||
# instantiate and register the library
|
||||
tl = PCellTestLib::new
|
||||
|
|
@ -593,7 +593,7 @@ class DBPCell_TestClass < TestBase
|
|||
|
||||
end
|
||||
|
||||
def _test_2
|
||||
def test_2
|
||||
|
||||
# instantiate and register the library
|
||||
tl = PCellTestLib::new
|
||||
|
|
@ -632,7 +632,7 @@ class DBPCell_TestClass < TestBase
|
|||
|
||||
end
|
||||
|
||||
def _test_3
|
||||
def test_3
|
||||
|
||||
# instantiate and register the library
|
||||
tl = PCellTestLib::new
|
||||
|
|
@ -657,7 +657,7 @@ class DBPCell_TestClass < TestBase
|
|||
|
||||
end
|
||||
|
||||
def _test_4
|
||||
def test_4
|
||||
|
||||
# instantiate and register the library
|
||||
tl = PCellTestLib::new
|
||||
|
|
@ -674,7 +674,7 @@ class DBPCell_TestClass < TestBase
|
|||
|
||||
end
|
||||
|
||||
def _test_5
|
||||
def test_5
|
||||
|
||||
# instantiate and register the library
|
||||
tl = PCellTestLib::new
|
||||
|
|
@ -691,7 +691,7 @@ class DBPCell_TestClass < TestBase
|
|||
|
||||
end
|
||||
|
||||
def _test_6
|
||||
def test_6
|
||||
|
||||
# instantiate and register the library
|
||||
tl = PCellTestLib::new
|
||||
|
|
@ -707,7 +707,7 @@ class DBPCell_TestClass < TestBase
|
|||
|
||||
end
|
||||
|
||||
def _test_7
|
||||
def test_7
|
||||
|
||||
# instantiate and register the library
|
||||
tl = PCellTestLib::new
|
||||
|
|
@ -725,7 +725,7 @@ class DBPCell_TestClass < TestBase
|
|||
|
||||
end
|
||||
|
||||
def _test_8
|
||||
def test_8
|
||||
|
||||
# instantiate and register the library
|
||||
tl = PCellTestLib::new
|
||||
|
|
@ -747,7 +747,7 @@ class DBPCell_TestClass < TestBase
|
|||
|
||||
end
|
||||
|
||||
def _test_9
|
||||
def test_9
|
||||
|
||||
layout = RBA::Layout::new
|
||||
|
||||
|
|
@ -813,7 +813,7 @@ class DBPCell_TestClass < TestBase
|
|||
|
||||
end
|
||||
|
||||
def _test_10
|
||||
def test_10
|
||||
|
||||
lib = CircleLib1782::new("CircleLib")
|
||||
|
||||
|
|
@ -864,7 +864,7 @@ class DBPCell_TestClass < TestBase
|
|||
|
||||
end
|
||||
|
||||
def _test_11
|
||||
def test_11
|
||||
|
||||
lib = CircleLib1782::new("CircleLib")
|
||||
|
||||
|
|
@ -899,7 +899,7 @@ class DBPCell_TestClass < TestBase
|
|||
|
||||
end
|
||||
|
||||
def _test_12
|
||||
def test_12
|
||||
|
||||
if !RBA.constants.member?(:PCellDeclarationHelper)
|
||||
return
|
||||
|
|
@ -924,7 +924,7 @@ class DBPCell_TestClass < TestBase
|
|||
end
|
||||
|
||||
# convert to static cell
|
||||
def _test_13
|
||||
def test_13
|
||||
|
||||
if !RBA.constants.member?(:PCellDeclarationHelper)
|
||||
return
|
||||
|
|
@ -954,11 +954,69 @@ class DBPCell_TestClass < TestBase
|
|||
|
||||
end
|
||||
|
||||
# cold proxies
|
||||
def test_14
|
||||
|
||||
# instantiate and register the library
|
||||
tl = PCellTestLib::new
|
||||
|
||||
ly = RBA::Layout::new(true)
|
||||
ly.dbu = 0.01
|
||||
|
||||
li1 = ly.layer(1, 0)
|
||||
|
||||
scell = ly.create_cell("A")
|
||||
|
||||
param = { "w" => 4.0, "h" => 8.0, "l" => RBA::LayerInfo::new(1, 0) }
|
||||
cell = ly.create_cell("Box", "PCellTestLib", param)
|
||||
cell.name = "B"
|
||||
|
||||
assert_equal(scell.is_proxy?, false)
|
||||
assert_equal(scell.is_library_cell?, false)
|
||||
assert_equal(scell.is_cold_proxy?, false)
|
||||
assert_equal(scell.pcell_parameter("h").to_s, "")
|
||||
assert_equal(scell.pcell_parameter("x").to_s, "")
|
||||
assert_equal(scell.pcell_parameters_by_name.to_s, "{}")
|
||||
assert_equal(scell.pcell_name, "")
|
||||
assert_equal(scell.library_name, "")
|
||||
assert_equal(scell.library_cell_name, "")
|
||||
|
||||
assert_equal(cell.is_proxy?, true)
|
||||
assert_equal(cell.is_library_cell?, true)
|
||||
assert_equal(cell.is_cold_proxy?, false)
|
||||
assert_equal(cell.pcell_parameter("h").to_s, "8.0")
|
||||
assert_equal(cell.pcell_parameter("x").to_s, "")
|
||||
assert_equal(cell.pcell_parameters_by_name.to_s, "{\"h\"=>8.0, \"l\"=><1/0>, \"w\"=>4.0}")
|
||||
assert_equal(cell.pcell_name, "Box")
|
||||
assert_equal(cell.library_cell_name, "Box_L1d0_W4p000_H8p000") # it's the library's PCell proxy
|
||||
assert_equal(cell.library_name, "PCellTestLib")
|
||||
assert_equal(cell.display_title, "PCellTestLib.Box(L=1/0,W=4.000,H=8.000)")
|
||||
|
||||
tl._destroy
|
||||
|
||||
# the cell got destroyed and replaced by a cold proxy
|
||||
assert_equal(cell._destroyed?, true)
|
||||
|
||||
cell = ly.cell("B")
|
||||
|
||||
assert_equal(cell.is_proxy?, true)
|
||||
assert_equal(cell.is_library_cell?, false)
|
||||
assert_equal(cell.is_cold_proxy?, true)
|
||||
assert_equal(cell.pcell_parameter("h").to_s, "8.0")
|
||||
assert_equal(cell.pcell_parameter("x").to_s, "")
|
||||
assert_equal(cell.pcell_parameters_by_name.to_s, "{\"h\"=>8.0, \"l\"=><1/0>, \"w\"=>4.0}")
|
||||
assert_equal(cell.pcell_name, "Box")
|
||||
assert_equal(cell.library_cell_name, "") # it's not a static library cell
|
||||
assert_equal(cell.library_name, "PCellTestLib")
|
||||
assert_equal(cell.display_title, "<defunct>PCellTestLib.Box")
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class DBPCellParameterStates_TestClass < TestBase
|
||||
|
||||
def _test_1
|
||||
def test_1
|
||||
|
||||
ps = RBA::PCellParameterState::new
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue