mirror of https://github.com/KLayout/klayout.git
WIP: provisions for DRC/network extractor integration.
This commit is contained in:
parent
36a3540e16
commit
fccdee5186
|
|
@ -268,6 +268,16 @@ DeepShapeStore::DeepShapeStore ()
|
|||
++s_instance_count;
|
||||
}
|
||||
|
||||
DeepShapeStore::DeepShapeStore (const std::string &topcell_name, double dbu)
|
||||
: m_threads (1), m_max_area_ratio (3.0), m_max_vertex_count (16), m_text_property_name (), m_text_enlargement (-1)
|
||||
{
|
||||
++s_instance_count;
|
||||
|
||||
m_layouts.push_back (new LayoutHolder (db::ICplxTrans ()));
|
||||
m_layouts.back ()->layout.dbu (dbu);
|
||||
m_layouts.back ()->layout.add_cell (topcell_name.c_str ());
|
||||
}
|
||||
|
||||
DeepShapeStore::~DeepShapeStore ()
|
||||
{
|
||||
--s_instance_count;
|
||||
|
|
@ -278,6 +288,33 @@ DeepShapeStore::~DeepShapeStore ()
|
|||
m_layouts.clear ();
|
||||
}
|
||||
|
||||
DeepLayer DeepShapeStore::create_from_flat (const db::Region ®ion, double max_area_ratio, size_t max_vertex_count, const db::ICplxTrans &trans)
|
||||
{
|
||||
require_singular ();
|
||||
|
||||
unsigned int layer = layout ().insert_layer ();
|
||||
|
||||
if (max_area_ratio == 0.0) {
|
||||
max_area_ratio = m_max_area_ratio;
|
||||
}
|
||||
if (max_vertex_count == 0) {
|
||||
max_vertex_count = m_max_vertex_count;
|
||||
}
|
||||
|
||||
db::Shapes *shapes = &initial_cell ().shapes (layer);
|
||||
db::Box world = db::Box::world ();
|
||||
|
||||
// The chain of operators for producing clipped and reduced polygon references
|
||||
db::PolygonReferenceHierarchyBuilderShapeReceiver refs (&layout (), m_text_enlargement, m_text_property_name);
|
||||
db::ReducingHierarchyBuilderShapeReceiver red (&refs, max_area_ratio, max_vertex_count);
|
||||
|
||||
for (db::Region::const_iterator p = region.begin (); ! p.at_end (); ++p) {
|
||||
red.push (*p, trans, world, 0, shapes);
|
||||
}
|
||||
|
||||
return DeepLayer (this, 0 /*singular layout index*/, layer);
|
||||
}
|
||||
|
||||
bool DeepShapeStore::is_singular () const
|
||||
{
|
||||
return m_layouts.size () == 1;
|
||||
|
|
|
|||
|
|
@ -232,6 +232,14 @@ public:
|
|||
*/
|
||||
DeepShapeStore ();
|
||||
|
||||
/**
|
||||
* @brief The constructor for a singular DSS
|
||||
*
|
||||
* This DSS will be initialized with one layout and the given database unit
|
||||
* and top level cell name.
|
||||
*/
|
||||
DeepShapeStore (const std::string &topcell_name, double dbu);
|
||||
|
||||
/**
|
||||
* @brief The destructor
|
||||
*/
|
||||
|
|
@ -251,6 +259,14 @@ public:
|
|||
*/
|
||||
bool is_singular () const;
|
||||
|
||||
/**
|
||||
* @brief Creates a new layer from a flat region (or the region is made flat)
|
||||
*
|
||||
* This method is intended for use with singular-created DSS objects (see
|
||||
* singular constructor).
|
||||
*/
|
||||
DeepLayer create_from_flat (const db::Region ®ion, double max_area_ratio = 0.0, size_t max_vertex_count = 0, const db::ICplxTrans &trans = db::ICplxTrans ());
|
||||
|
||||
/**
|
||||
* @brief Inserts a polygon layer into the deep shape store
|
||||
*
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "dbCommon.h"
|
||||
|
||||
#include "dbEdgePair.h"
|
||||
#include "tlUniqueId.h"
|
||||
|
||||
namespace db {
|
||||
|
||||
|
|
@ -58,6 +59,7 @@ public:
|
|||
* @brief The delegate for the actual edge set implementation
|
||||
*/
|
||||
class DB_PUBLIC EdgePairsDelegate
|
||||
: public tl::UniqueId
|
||||
{
|
||||
public:
|
||||
typedef db::Coord coord_type;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "dbEdge.h"
|
||||
#include "dbEdgePairs.h"
|
||||
#include "dbEdgePairRelations.h"
|
||||
#include "tlUniqueId.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
|
|
@ -185,6 +186,7 @@ public:
|
|||
* @brief The delegate for the actual edge set implementation
|
||||
*/
|
||||
class DB_PUBLIC EdgesDelegate
|
||||
: public tl::UniqueId
|
||||
{
|
||||
public:
|
||||
typedef db::Coord coord_type;
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ static bool is_deep (const db::Region &r)
|
|||
// the iterator provides the hierarchical selection (enabling/disabling cells etc.)
|
||||
|
||||
LayoutToNetlist::LayoutToNetlist (const db::RecursiveShapeIterator &iter)
|
||||
: m_iter (iter), m_netlist_extracted (false)
|
||||
: m_iter (iter), m_netlist_extracted (false), m_is_flat (false)
|
||||
{
|
||||
// check the iterator
|
||||
if (iter.has_complex_region () || iter.region () != db::Box::world ()) {
|
||||
|
|
@ -48,46 +48,68 @@ LayoutToNetlist::LayoutToNetlist (const db::RecursiveShapeIterator &iter)
|
|||
init ();
|
||||
}
|
||||
|
||||
LayoutToNetlist::LayoutToNetlist (db::DeepShapeStore *dss, unsigned int layout_index)
|
||||
: mp_dss (dss), m_netlist_extracted (false), m_is_flat (false)
|
||||
{
|
||||
m_iter = db::RecursiveShapeIterator (dss->layout (layout_index), dss->initial_cell (layout_index), std::set<unsigned int> ());
|
||||
|
||||
init ();
|
||||
}
|
||||
|
||||
LayoutToNetlist::LayoutToNetlist (const std::string &topcell_name, double dbu)
|
||||
: m_iter (), m_netlist_extracted (false), m_is_flat (true)
|
||||
{
|
||||
mp_internal_dss.reset (new db::DeepShapeStore (topcell_name, dbu));
|
||||
mp_dss.reset (mp_internal_dss.get ());
|
||||
|
||||
init ();
|
||||
}
|
||||
|
||||
LayoutToNetlist::LayoutToNetlist ()
|
||||
: m_iter (), m_netlist_extracted (false)
|
||||
: m_iter (), mp_internal_dss (new db::DeepShapeStore ()), mp_dss (mp_internal_dss.get ()), m_netlist_extracted (false), m_is_flat (true)
|
||||
{
|
||||
init ();
|
||||
}
|
||||
|
||||
void LayoutToNetlist::init ()
|
||||
{
|
||||
m_dss.set_text_enlargement (1);
|
||||
m_dss.set_text_property_name (tl::Variant ("LABEL"));
|
||||
if (! mp_dss.get ()) {
|
||||
mp_internal_dss.reset (new db::DeepShapeStore ());
|
||||
mp_dss.reset (mp_internal_dss.get ());
|
||||
}
|
||||
|
||||
dss ().set_text_enlargement (1);
|
||||
dss ().set_text_property_name (tl::Variant ("LABEL"));
|
||||
}
|
||||
|
||||
void LayoutToNetlist::set_threads (int n)
|
||||
{
|
||||
m_dss.set_threads (n);
|
||||
dss ().set_threads (n);
|
||||
}
|
||||
|
||||
int LayoutToNetlist::threads () const
|
||||
{
|
||||
return m_dss.threads ();
|
||||
return dss ().threads ();
|
||||
}
|
||||
|
||||
void LayoutToNetlist::set_area_ratio (double ar)
|
||||
{
|
||||
m_dss.set_max_area_ratio (ar);
|
||||
dss ().set_max_area_ratio (ar);
|
||||
}
|
||||
|
||||
double LayoutToNetlist::area_ratio () const
|
||||
{
|
||||
return m_dss.max_area_ratio ();
|
||||
return dss ().max_area_ratio ();
|
||||
}
|
||||
|
||||
void LayoutToNetlist::set_max_vertex_count (size_t n)
|
||||
{
|
||||
m_dss.set_max_vertex_count (n);
|
||||
dss ().set_max_vertex_count (n);
|
||||
}
|
||||
|
||||
size_t LayoutToNetlist::max_vertex_count () const
|
||||
{
|
||||
return m_dss.max_vertex_count ();
|
||||
return dss ().max_vertex_count ();
|
||||
}
|
||||
|
||||
db::Region *LayoutToNetlist::make_layer (const std::string &n)
|
||||
|
|
@ -95,7 +117,7 @@ db::Region *LayoutToNetlist::make_layer (const std::string &n)
|
|||
db::RecursiveShapeIterator si (m_iter);
|
||||
si.shape_flags (db::ShapeIterator::Nothing);
|
||||
|
||||
std::auto_ptr <db::Region> region (new db::Region (si, m_dss));
|
||||
std::auto_ptr <db::Region> region (new db::Region (si, dss ()));
|
||||
if (! n.empty ()) {
|
||||
register_layer (*region, n);
|
||||
}
|
||||
|
|
@ -108,7 +130,7 @@ db::Region *LayoutToNetlist::make_layer (unsigned int layer_index, const std::st
|
|||
si.set_layer (layer_index);
|
||||
si.shape_flags (db::ShapeIterator::All);
|
||||
|
||||
std::auto_ptr <db::Region> region (new db::Region (si, m_dss));
|
||||
std::auto_ptr <db::Region> region (new db::Region (si, dss ()));
|
||||
if (! n.empty ()) {
|
||||
register_layer (*region, n);
|
||||
}
|
||||
|
|
@ -121,7 +143,7 @@ db::Region *LayoutToNetlist::make_text_layer (unsigned int layer_index, const st
|
|||
si.set_layer (layer_index);
|
||||
si.shape_flags (db::ShapeIterator::Texts);
|
||||
|
||||
std::auto_ptr <db::Region> region (new db::Region (si, m_dss));
|
||||
std::auto_ptr <db::Region> region (new db::Region (si, dss ()));
|
||||
if (! n.empty ()) {
|
||||
register_layer (*region, n);
|
||||
}
|
||||
|
|
@ -134,7 +156,7 @@ db::Region *LayoutToNetlist::make_polygon_layer (unsigned int layer_index, const
|
|||
si.set_layer (layer_index);
|
||||
si.shape_flags (db::ShapeIterator::Paths | db::ShapeIterator::Polygons | db::ShapeIterator::Boxes);
|
||||
|
||||
std::auto_ptr <db::Region> region (new db::Region (si, m_dss));
|
||||
std::auto_ptr <db::Region> region (new db::Region (si, dss ()));
|
||||
if (! n.empty ()) {
|
||||
register_layer (*region, n);
|
||||
}
|
||||
|
|
@ -149,7 +171,7 @@ void LayoutToNetlist::extract_devices (db::NetlistDeviceExtractor &extractor, co
|
|||
if (! mp_netlist.get ()) {
|
||||
mp_netlist.reset (new db::Netlist ());
|
||||
}
|
||||
extractor.extract(m_dss, layers, *mp_netlist, m_net_clusters);
|
||||
extractor.extract(dss (), layers, *mp_netlist, m_net_clusters);
|
||||
}
|
||||
|
||||
void LayoutToNetlist::connect (const db::Region &l)
|
||||
|
|
@ -236,7 +258,7 @@ void LayoutToNetlist::extract_netlist (bool join_nets_by_label)
|
|||
}
|
||||
|
||||
db::NetlistExtractor netex;
|
||||
netex.extract_nets(m_dss, m_conn, *mp_netlist, m_net_clusters, join_nets_by_label);
|
||||
netex.extract_nets(dss (), m_conn, *mp_netlist, m_net_clusters, join_nets_by_label);
|
||||
|
||||
m_netlist_extracted = true;
|
||||
}
|
||||
|
|
@ -248,30 +270,30 @@ void LayoutToNetlist::set_netlist_extracted ()
|
|||
|
||||
const db::Layout *LayoutToNetlist::internal_layout () const
|
||||
{
|
||||
return &m_dss.const_layout ();
|
||||
return &dss ().const_layout ();
|
||||
}
|
||||
|
||||
const db::Cell *LayoutToNetlist::internal_top_cell () const
|
||||
{
|
||||
return &m_dss.const_initial_cell ();
|
||||
return &dss ().const_initial_cell ();
|
||||
}
|
||||
|
||||
void LayoutToNetlist::ensure_internal_layout ()
|
||||
{
|
||||
if (m_dss.layouts () == 0) {
|
||||
if (dss ().layouts () == 0) {
|
||||
// the dummy layer acts as a reference holder for the layout
|
||||
m_dummy_layer = m_dss.create_polygon_layer (db::RecursiveShapeIterator ());
|
||||
m_dummy_layer = dss ().create_polygon_layer (db::RecursiveShapeIterator ());
|
||||
}
|
||||
}
|
||||
|
||||
db::Layout *LayoutToNetlist::internal_layout ()
|
||||
{
|
||||
return &m_dss.layout ();
|
||||
return &dss ().layout ();
|
||||
}
|
||||
|
||||
db::Cell *LayoutToNetlist::internal_top_cell ()
|
||||
{
|
||||
return &m_dss.initial_cell ();
|
||||
return &dss ().initial_cell ();
|
||||
}
|
||||
|
||||
void LayoutToNetlist::register_layer (const db::Region ®ion, const std::string &n)
|
||||
|
|
@ -280,18 +302,38 @@ void LayoutToNetlist::register_layer (const db::Region ®ion, const std::strin
|
|||
throw tl::Exception (tl::to_string (tr ("Layer name is already used: ")) + n);
|
||||
}
|
||||
|
||||
db::DeepRegion *delegate = dynamic_cast<db::DeepRegion *> (region.delegate());
|
||||
if (! delegate) {
|
||||
throw tl::Exception (tl::to_string (tr ("Layer is not a deep region")));
|
||||
db::DeepLayer dl;
|
||||
|
||||
if (m_is_flat) {
|
||||
|
||||
dl = dss ().create_from_flat (region);
|
||||
|
||||
} else {
|
||||
|
||||
db::DeepRegion *delegate = dynamic_cast<db::DeepRegion *> (region.delegate());
|
||||
if (! delegate) {
|
||||
|
||||
if (region.empty ()) {
|
||||
dl = dss ().empty_layer ();
|
||||
} else {
|
||||
throw tl::Exception (tl::to_string (tr ("Layer is not a deep region")));
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (is_persisted (region)) {
|
||||
std::string prev_name = name (region);
|
||||
m_named_regions.erase (prev_name);
|
||||
}
|
||||
|
||||
dl = delegate->deep_layer ();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (is_persisted (region)) {
|
||||
std::string prev_name = name (region);
|
||||
m_named_regions.erase (prev_name);
|
||||
}
|
||||
|
||||
m_named_regions [n] = delegate->deep_layer ();
|
||||
m_name_of_layer [layer_of (region)] = n;
|
||||
m_named_regions [n] = dl;
|
||||
m_name_of_layer [dl.layer ()] = n;
|
||||
}
|
||||
|
||||
std::string LayoutToNetlist::name (const db::Region ®ion) const
|
||||
|
|
@ -359,7 +401,7 @@ db::CellMapping LayoutToNetlist::cell_mapping_into (db::Layout &layout, db::Cell
|
|||
}
|
||||
}
|
||||
|
||||
return m_dss.cell_mapping_to_original (layout_index, &layout, cell.cell_index (), &device_cells);
|
||||
return dss ().cell_mapping_to_original (layout_index, &layout, cell.cell_index (), &device_cells);
|
||||
}
|
||||
|
||||
db::CellMapping LayoutToNetlist::const_cell_mapping_into (const db::Layout &layout, const db::Cell &cell)
|
||||
|
|
|
|||
|
|
@ -82,6 +82,28 @@ public:
|
|||
*/
|
||||
LayoutToNetlist (const db::RecursiveShapeIterator &iter);
|
||||
|
||||
/**
|
||||
* @brief Alternative constructor using an external deep shape storage
|
||||
*
|
||||
* This constructor allows using an external DSS. It's intended to be used
|
||||
* with existing DSS instances. Existing layers can be registered with
|
||||
* "register_layer". The LayoutToNetlist object will hold a weak reference
|
||||
* to the DSS but not own the DSS.
|
||||
*
|
||||
* NOTE: if using make_layer, these new layers will be created in the DSS
|
||||
* given in this constructor.
|
||||
*/
|
||||
LayoutToNetlist (db::DeepShapeStore *dss, unsigned int layout_index);
|
||||
|
||||
/**
|
||||
* @brief Alternative constructor for flat mode
|
||||
*
|
||||
* In flat mode, the internal DSS will be initialized to a top-level only
|
||||
* layout. All layers entered through "register_layer" or created with
|
||||
* "make_layer" will become flat ones.
|
||||
*/
|
||||
LayoutToNetlist (const std::string &topcell_name, double dbu);
|
||||
|
||||
/**
|
||||
* @brief The default constructor
|
||||
*/
|
||||
|
|
@ -467,7 +489,8 @@ private:
|
|||
LayoutToNetlist &operator= (const db::LayoutToNetlist &other);
|
||||
|
||||
db::RecursiveShapeIterator m_iter;
|
||||
db::DeepShapeStore m_dss;
|
||||
std::auto_ptr<db::DeepShapeStore> mp_internal_dss;
|
||||
tl::weak_ptr<db::DeepShapeStore> mp_dss;
|
||||
db::Connectivity m_conn;
|
||||
db::hier_clusters<db::PolygonRef> m_net_clusters;
|
||||
std::auto_ptr<db::Netlist> mp_netlist;
|
||||
|
|
@ -475,8 +498,21 @@ private:
|
|||
std::map<std::string, db::DeepLayer> m_named_regions;
|
||||
std::map<unsigned int, std::string> m_name_of_layer;
|
||||
bool m_netlist_extracted;
|
||||
bool m_is_flat;
|
||||
db::DeepLayer m_dummy_layer;
|
||||
|
||||
db::DeepShapeStore &dss ()
|
||||
{
|
||||
tl_assert (mp_dss.get () != 0);
|
||||
return *mp_dss;
|
||||
}
|
||||
|
||||
const db::DeepShapeStore &dss () const
|
||||
{
|
||||
tl_assert (mp_dss.get () != 0);
|
||||
return *mp_dss;
|
||||
}
|
||||
|
||||
void init ();
|
||||
size_t search_net (const db::ICplxTrans &trans, const db::Cell *cell, const db::local_cluster<db::PolygonRef> &test_cluster, std::vector<db::InstElement> &rev_inst_path);
|
||||
void build_net_rec (const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const char *net_cell_name_prefix, const char *cell_name_prefix, const char *device_cell_name_prefix, std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> &cmap, const ICplxTrans &tr) const;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "dbEdges.h"
|
||||
#include "dbEdgePairs.h"
|
||||
#include "dbEdgePairRelations.h"
|
||||
#include "tlUniqueId.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
|
|
@ -181,6 +182,7 @@ public:
|
|||
* @brief The delegate for the actual region implementation
|
||||
*/
|
||||
class DB_PUBLIC RegionDelegate
|
||||
: public tl::UniqueId
|
||||
{
|
||||
public:
|
||||
typedef db::Coord coord_type;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,13 @@ Class<db::DeepShapeStore> decl_dbDeepShapeStore ("db", "DeepShapeStore",
|
|||
gsi::method ("instance_count", &db::DeepShapeStore::instance_count,
|
||||
"@hide\n"
|
||||
) +
|
||||
gsi::method ("is_singular?", &db::DeepShapeStore::is_singular,
|
||||
"@brief Gets a value indicating whether there is a single layout variant\n"
|
||||
"\n"
|
||||
"Specifically for network extraction, singular DSS objects are required. "
|
||||
"Multiple layouts may be present if different sources of layouts have "
|
||||
"been used. Such DSS objects are not usable for network extraction."
|
||||
) +
|
||||
gsi::method ("threads=", &db::DeepShapeStore::set_threads, gsi::arg ("n"),
|
||||
"@brief Sets the number of threads to allocate for the hierarchical processor\n"
|
||||
) +
|
||||
|
|
|
|||
|
|
@ -174,6 +174,11 @@ static bool is_deep (const db::EdgePairs *ep)
|
|||
return dynamic_cast<const db::DeepEdgePairs *> (ep->delegate ()) != 0;
|
||||
}
|
||||
|
||||
static size_t id (const db::EdgePairs *ep)
|
||||
{
|
||||
return tl::id_of (ep->delegate ());
|
||||
}
|
||||
|
||||
Class<db::EdgePairs> decl_EdgePairs ("db", "EdgePairs",
|
||||
constructor ("new", &new_v,
|
||||
"@brief Default constructor\n"
|
||||
|
|
@ -312,6 +317,11 @@ Class<db::EdgePairs> decl_EdgePairs ("db", "EdgePairs",
|
|||
"\n"
|
||||
"This method has been added in version 0.26."
|
||||
) +
|
||||
method_ext ("data_id", &id,
|
||||
"@brief Returns the data ID (a unique identifier for the underlying data storage)\n"
|
||||
"\n"
|
||||
"This method has been added in version 0.26."
|
||||
) +
|
||||
method ("+", &db::EdgePairs::operator+,
|
||||
"@brief Returns the combined edge pair collection of self and the other one\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -400,6 +400,10 @@ static db::Edges *new_texts_as_dots2 (const db::RecursiveShapeIterator &si, db::
|
|||
return new db::Edges (db::OriginalLayerRegion (si, false).texts_as_dots (pat, pattern, dss));
|
||||
}
|
||||
|
||||
static size_t id (const db::Edges *e)
|
||||
{
|
||||
return tl::id_of (e->delegate ());
|
||||
}
|
||||
|
||||
Class<db::Edges> dec_Edges ("db", "Edges",
|
||||
constructor ("new", &new_v,
|
||||
|
|
@ -1466,6 +1470,11 @@ Class<db::Edges> dec_Edges ("db", "Edges",
|
|||
"\n"
|
||||
"This method has been added in version 0.26."
|
||||
) +
|
||||
method_ext ("data_id", &id,
|
||||
"@brief Returns the data ID (a unique identifier for the underlying data storage)\n"
|
||||
"\n"
|
||||
"This method has been added in version 0.26."
|
||||
) +
|
||||
method ("is_merged?", &db::Edges::is_merged,
|
||||
"@brief Returns true if the edge collection is merged\n"
|
||||
"If the region is merged, coincident edges have been merged into single edges. You can ensure merged state "
|
||||
|
|
|
|||
|
|
@ -39,6 +39,16 @@ static db::LayoutToNetlist *make_l2n_default ()
|
|||
return new db::LayoutToNetlist ();
|
||||
}
|
||||
|
||||
static db::LayoutToNetlist *make_l2n_from_existing_dss (db::DeepShapeStore *dss, unsigned int layout_index)
|
||||
{
|
||||
return new db::LayoutToNetlist (dss, layout_index);
|
||||
}
|
||||
|
||||
static db::LayoutToNetlist *make_l2n_flat (const std::string &topcell_name, double dbu)
|
||||
{
|
||||
return new db::LayoutToNetlist (topcell_name, dbu);
|
||||
}
|
||||
|
||||
static db::Layout *l2n_internal_layout (db::LayoutToNetlist *l2n)
|
||||
{
|
||||
// although this isn't very clean, we dare to do so as const references are pretty useless in script languages.
|
||||
|
|
@ -99,6 +109,24 @@ Class<db::LayoutToNetlist> decl_dbLayoutToNetlist ("db", "LayoutToNetlist",
|
|||
"@brief Creates a new and empty extractor object\n"
|
||||
"The main objective for this constructor is to create an object suitable for reading an annotated netlist.\n"
|
||||
) +
|
||||
gsi::constructor ("new", &make_l2n_from_existing_dss, gsi::arg ("dss"), gsi::arg ("layout_index", 0),
|
||||
"@brief Creates a new extractor object reusing an existing \\DeepShapeStore object\n"
|
||||
"This constrcutor can be used if there is a DSS object already from which the "
|
||||
"shapes can be taken. NOTE: in this case, the make_... functions will create "
|
||||
"new layers inside this DSS. To register existing layers (regions) use \\register.\n"
|
||||
) +
|
||||
gsi::constructor ("new", &make_l2n_flat, gsi::arg ("topcell_name"), gsi::arg ("dbu"),
|
||||
"@brief Creates a new extractor object with a flat DSS\n"
|
||||
"@param topcell_name The name of the top cell of the internal flat layout\n"
|
||||
"@param dbu The database unit to use for the internal flat layout\n"
|
||||
"\n"
|
||||
"This constructor will create an extractor for flat extraction. Layers registered "
|
||||
"with \\register will be flattened. New layers created with make_... will be flat "
|
||||
"layers.\n"
|
||||
"\n"
|
||||
"The database unit is mandatory because the physical parameter extraction "
|
||||
"for devices requires this unit for translation of layout to physical dimensions.\n"
|
||||
) +
|
||||
gsi::method ("threads=", &db::LayoutToNetlist::set_threads, gsi::arg ("n"),
|
||||
"@brief Sets the number of threads to use for operations which support multiple threads\n"
|
||||
) +
|
||||
|
|
@ -382,6 +410,10 @@ Class<db::LayoutToNetlist> decl_dbLayoutToNetlist ("db", "LayoutToNetlist",
|
|||
" finding a net by probing a specific location.\n"
|
||||
"@li\n"
|
||||
"\n"
|
||||
"Another use model is using the extractor with an existing \\DeepShapeStore object "
|
||||
"or even flat data. In this case, the preparation step is importing by "
|
||||
"taking existing region data using the \\register method.\n"
|
||||
"\n"
|
||||
"This class has been introduced in version 0.26."
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -600,6 +600,11 @@ static bool is_deep (const db::Region *region)
|
|||
return dynamic_cast<const db::DeepRegion *> (region->delegate ()) != 0;
|
||||
}
|
||||
|
||||
static size_t id (const db::Region *r)
|
||||
{
|
||||
return tl::id_of (r->delegate ());
|
||||
}
|
||||
|
||||
// provided by gsiDeclDbPolygon.cc:
|
||||
int td_simple ();
|
||||
int po_any ();
|
||||
|
|
@ -2231,6 +2236,11 @@ Class<db::Region> decl_Region ("db", "Region",
|
|||
"\n"
|
||||
"This method has been added in version 0.26."
|
||||
) +
|
||||
method_ext ("data_id", &id,
|
||||
"@brief Returns the data ID (a unique identifier for the underlying data storage)\n"
|
||||
"\n"
|
||||
"This method has been added in version 0.26."
|
||||
) +
|
||||
method ("is_merged?", &db::Region::is_merged,
|
||||
"@brief Returns true if the region is merged\n"
|
||||
"If the region is merged, polygons will not touch or overlap. You can ensure merged state "
|
||||
|
|
|
|||
|
|
@ -33,8 +33,10 @@ class DBEdgePairs_TestClass < TestBase
|
|||
assert_equal(r.is_empty?, true)
|
||||
assert_equal(r.size, 0)
|
||||
assert_equal(r.bbox.to_s, "()")
|
||||
data_id = r.data_id
|
||||
|
||||
r.insert(RBA::Edge::new(0, 0, 0, 100), RBA::Edge::new(-10, 0, -20, 50))
|
||||
assert_equal(data_id != r.data_id, true)
|
||||
assert_equal(r.to_s, "(0,0;0,100)/(-10,0;-20,50)")
|
||||
r.clear
|
||||
|
||||
|
|
@ -55,6 +57,7 @@ class DBEdgePairs_TestClass < TestBase
|
|||
assert_equal(r.moved(-10, 10).to_s, "(-10,10;-10,110)/(-20,10;-30,60)")
|
||||
assert_equal(r.moved(RBA::Point::new(-10, 10)).to_s, "(-10,10;-10,110)/(-20,10;-30,60)")
|
||||
rr = r.dup
|
||||
assert_equal(rr.data_id != r.data_id, true)
|
||||
rr.move(-10, 10)
|
||||
assert_equal(rr.to_s, "(-10,10;-10,110)/(-20,10;-30,60)")
|
||||
rr = r.dup
|
||||
|
|
|
|||
|
|
@ -34,8 +34,10 @@ class DBEdges_TestClass < TestBase
|
|||
assert_equal(r.size, 0)
|
||||
assert_equal(r.bbox.to_s, "()")
|
||||
assert_equal(r.is_merged?, true)
|
||||
data_id = r.data_id
|
||||
|
||||
r.assign(RBA::Edges::new([RBA::Edge::new(10, 20, 100, 200)]))
|
||||
assert_equal(data_id != r.data_id, true)
|
||||
assert_equal(r.to_s, "(10,20;100,200)")
|
||||
assert_equal(r.is_empty?, false)
|
||||
assert_equal(r.size, 1)
|
||||
|
|
@ -72,6 +74,7 @@ class DBEdges_TestClass < TestBase
|
|||
assert_equal(r.moved(RBA::Point::new(10, 20)).bbox.to_s, "(20,40;110,220)")
|
||||
assert_equal(r.moved(10, 20).bbox.to_s, "(20,40;110,220)")
|
||||
rr = r.dup
|
||||
assert_equal(rr.data_id != r.data_id, true)
|
||||
rr.move(RBA::Point::new(10, 20))
|
||||
assert_equal(rr.bbox.to_s, "(20,40;110,220)")
|
||||
rr = r.dup
|
||||
|
|
|
|||
|
|
@ -35,8 +35,10 @@ class DBRegion_TestClass < TestBase
|
|||
assert_equal(r.bbox.to_s, "()")
|
||||
assert_equal(r.is_merged?, true)
|
||||
assert_equal(r.is_box?, false)
|
||||
data_id = r.data_id
|
||||
|
||||
r.assign(RBA::Region::new(RBA::Box::new(10, 20, 100, 200)))
|
||||
assert_equal(data_id != r.data_id, true)
|
||||
assert_equal(r.to_s, "(10,20;10,200;100,200;100,20)")
|
||||
assert_equal(r.is_empty?, false)
|
||||
assert_equal(r.size, 1)
|
||||
|
|
@ -48,6 +50,7 @@ class DBRegion_TestClass < TestBase
|
|||
assert_equal(r.moved(RBA::Point::new(10, 20)).bbox.to_s, "(20,40;110,220)")
|
||||
assert_equal(r.moved(10, 20).bbox.to_s, "(20,40;110,220)")
|
||||
rr = r.dup
|
||||
assert_equal(rr.data_id != r.data_id, true)
|
||||
rr.move(RBA::Point::new(10, 20))
|
||||
assert_equal(rr.bbox.to_s, "(20,40;110,220)")
|
||||
rr = r.dup
|
||||
|
|
|
|||
Loading…
Reference in New Issue