mirror of https://github.com/KLayout/klayout.git
WIP: net generation from region layers
This commit is contained in:
parent
d7bdbae60b
commit
1b9a532f48
|
|
@ -262,6 +262,7 @@ HEADERS = \
|
|||
dbLayoutLayers.h \
|
||||
dbLayoutQuery.h \
|
||||
dbLayoutStateModel.h \
|
||||
dbLayoutToNetlistEnums.h \
|
||||
dbLayoutUtils.h \
|
||||
dbLibrary.h \
|
||||
dbLibraryManager.h \
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
#include "dbRegionLocalOperations.h"
|
||||
#include "dbLocalOperationUtils.h"
|
||||
#include "dbCompoundOperation.h"
|
||||
#include "dbLayoutToNetlist.h"
|
||||
#include "tlTimer.h"
|
||||
|
||||
namespace db
|
||||
|
|
@ -742,6 +743,30 @@ DeepRegion::insert_into (db::Layout *layout, db::cell_index_type into_cell, unsi
|
|||
deep_layer ().insert_into (layout, into_cell, into_layer);
|
||||
}
|
||||
|
||||
RegionDelegate *
|
||||
DeepRegion::nets (LayoutToNetlist *l2n, NetPropertyMode prop_mode, const tl::Variant &net_prop_name, const std::vector<const db::Net *> *nets) const
|
||||
{
|
||||
db::NetBuilder &net_builder = deep_layer ().store_non_const ()->net_builder_for (l2n);
|
||||
|
||||
if (&l2n->dss () != deep_layer ().store ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Extracted netlist is from different scope as this layer - cannot pull net shapes")));
|
||||
}
|
||||
|
||||
DeepLayer result = deep_layer ().derived ();
|
||||
|
||||
std::unique_ptr<db::Region> region_for_layer (l2n->layer_by_original (this));
|
||||
if (! region_for_layer) {
|
||||
throw tl::Exception (tl::to_string (tr ("The given layer is not an original layer used in netlist extraction")));
|
||||
}
|
||||
|
||||
std::map<unsigned int, const db::Region *> lmap;
|
||||
lmap.insert (std::make_pair (result.layer (), region_for_layer.get ()));
|
||||
|
||||
net_builder.build_nets (nets, lmap, prop_mode, net_prop_name);
|
||||
|
||||
return new db::DeepRegion (result);
|
||||
}
|
||||
|
||||
RegionDelegate *
|
||||
DeepRegion::and_with (const Region &other, PropertyConstraint property_constraint) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -139,6 +139,8 @@ public:
|
|||
|
||||
virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const;
|
||||
|
||||
virtual RegionDelegate *nets (LayoutToNetlist *l2n, NetPropertyMode prop_mode, const tl::Variant &net_prop_name, const std::vector<const Net *> *nets) const;
|
||||
|
||||
virtual DeepShapeCollectionDelegateBase *deep ()
|
||||
{
|
||||
return this;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "dbDeepEdgePairs.h"
|
||||
#include "dbDeepTexts.h"
|
||||
#include "dbShapeCollection.h"
|
||||
#include "dbLayoutToNetlist.h"
|
||||
|
||||
#include "tlTimer.h"
|
||||
|
||||
|
|
@ -261,10 +262,31 @@ DeepLayer::check_dss () const
|
|||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
||||
struct DeepShapeStore::LayoutHolder
|
||||
{
|
||||
class L2NStatusChangedListener
|
||||
: public tl::Object
|
||||
{
|
||||
public:
|
||||
L2NStatusChangedListener (DeepShapeStore::LayoutHolder *lh, db::LayoutToNetlist *l2n)
|
||||
: mp_lh (lh), mp_l2n (l2n)
|
||||
{
|
||||
mp_l2n->status_changed_event ().add (this, &L2NStatusChangedListener::l2n_destroyed);
|
||||
}
|
||||
|
||||
private:
|
||||
void l2n_destroyed (gsi::ObjectBase::StatusEventType ev)
|
||||
{
|
||||
if (ev == gsi::ObjectBase::ObjectDestroyed) {
|
||||
// CAUTION: this will eventually delete *this!
|
||||
mp_lh->remove_l2n (mp_l2n);
|
||||
}
|
||||
}
|
||||
|
||||
DeepShapeStore::LayoutHolder *mp_lh;
|
||||
db::LayoutToNetlist *mp_l2n;
|
||||
};
|
||||
|
||||
LayoutHolder (const db::ICplxTrans &trans)
|
||||
: refs (0), layout (false), builder (&layout, trans)
|
||||
{
|
||||
|
|
@ -287,9 +309,34 @@ struct DeepShapeStore::LayoutHolder
|
|||
}
|
||||
}
|
||||
|
||||
bool has_net_builder_for (db::LayoutToNetlist *l2n) const
|
||||
{
|
||||
auto l = net_builders.find (l2n);
|
||||
return (l != net_builders.end ());
|
||||
}
|
||||
|
||||
db::NetBuilder &net_builder_for (db::Cell &top, db::LayoutToNetlist *l2n)
|
||||
{
|
||||
auto l = net_builders.find (l2n);
|
||||
if (l == net_builders.end ()) {
|
||||
// @@@ what happens if layout is the same than used inside l2n (l2n has weak reference to same DSS)??
|
||||
l = net_builders.insert (std::make_pair (l2n, std::make_pair (L2NStatusChangedListener (this, l2n), db::NetBuilder (&layout, l2n->cell_mapping_into (layout, top, false), l2n)))).first;
|
||||
}
|
||||
return l->second.second;
|
||||
}
|
||||
|
||||
void remove_l2n (db::LayoutToNetlist *l2n)
|
||||
{
|
||||
auto l = net_builders.find (l2n);
|
||||
if (l != net_builders.end ()) {
|
||||
net_builders.erase (l);
|
||||
}
|
||||
}
|
||||
|
||||
int refs;
|
||||
db::Layout layout;
|
||||
db::HierarchyBuilder builder;
|
||||
std::map<db::LayoutToNetlist *, std::pair<L2NStatusChangedListener, db::NetBuilder> > net_builders;
|
||||
std::map<unsigned int, int> layer_refs;
|
||||
};
|
||||
|
||||
|
|
@ -653,6 +700,18 @@ DeepShapeStore::add_breakout_cells (unsigned int layout_index, const std::set<db
|
|||
m_state.add_breakout_cells (layout_index, cc);
|
||||
}
|
||||
|
||||
bool
|
||||
DeepShapeStore::has_net_builder_for (unsigned int layout_index, db::LayoutToNetlist *l2n)
|
||||
{
|
||||
return m_layouts [layout_index]->has_net_builder_for (l2n);
|
||||
}
|
||||
|
||||
db::NetBuilder &
|
||||
DeepShapeStore::net_builder_for (unsigned int layout_index, db::LayoutToNetlist *l2n)
|
||||
{
|
||||
return m_layouts [layout_index]->net_builder_for (initial_cell (layout_index), l2n);
|
||||
}
|
||||
|
||||
void DeepShapeStore::set_threads (int n)
|
||||
{
|
||||
m_state.set_threads (n);
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ class Edges;
|
|||
class EdgePairs;
|
||||
class Texts;
|
||||
class ShapeCollection;
|
||||
class NetBuilder;
|
||||
class LayoutToNetlist;
|
||||
|
||||
/**
|
||||
* @brief Represents a shape collection from the deep shape store
|
||||
|
|
@ -220,6 +222,16 @@ public:
|
|||
return mp_store.get ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the non-const shape store object
|
||||
* This feature is intended for internal purposes.
|
||||
*/
|
||||
DeepShapeStore *store_non_const () const
|
||||
{
|
||||
check_dss ();
|
||||
return const_cast<DeepShapeStore *> (mp_store.get ());
|
||||
}
|
||||
|
||||
private:
|
||||
friend class DeepShapeStore;
|
||||
|
||||
|
|
@ -668,6 +680,37 @@ public:
|
|||
*/
|
||||
bool is_valid_layout_index (unsigned int n) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the net builder object for a given layout index and LayoutToNetlist database
|
||||
*
|
||||
* If no net builder is available, one will be created. Use \\has_net_builder to check whether one is
|
||||
* already created.
|
||||
*/
|
||||
db::NetBuilder &net_builder_for (unsigned int layout_index, db::LayoutToNetlist *l2n);
|
||||
|
||||
/**
|
||||
* @brief Gets the net builder object for a given LayoutToNetlist database (requires the DSS to be singular)
|
||||
*/
|
||||
db::NetBuilder &net_builder_for (db::LayoutToNetlist *l2n)
|
||||
{
|
||||
require_singular ();
|
||||
return net_builder_for (0, l2n);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether a net building is available
|
||||
*/
|
||||
bool has_net_builder_for(unsigned int layout_index, db::LayoutToNetlist *l2n);
|
||||
|
||||
/**
|
||||
* @brief Gets the net builder object for a given LayoutToNetlist database (requires the DSS to be singular)
|
||||
*/
|
||||
bool has_net_builder_for (db::LayoutToNetlist *l2n)
|
||||
{
|
||||
require_singular ();
|
||||
return has_net_builder_for (0, l2n);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The deep shape store also keeps the number of threads to allocate for the hierarchical processor
|
||||
*
|
||||
|
|
|
|||
|
|
@ -150,6 +150,8 @@ public:
|
|||
|
||||
virtual void insert_into (Layout *, db::cell_index_type, unsigned int) const { }
|
||||
|
||||
virtual RegionDelegate *nets (LayoutToNetlist *, NetPropertyMode, const tl::Variant &, const std::vector<const db::Net *> *) const { return new EmptyRegion (); }
|
||||
|
||||
private:
|
||||
EmptyRegion &operator= (const EmptyRegion &other);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -436,6 +436,12 @@ const db::PropertiesRepository *FlatRegion::properties_repository () const
|
|||
return mp_properties_repository.get_const ();
|
||||
}
|
||||
|
||||
RegionDelegate *FlatRegion::nets (LayoutToNetlist *l2n, NetPropertyMode prop_mode, const tl::Variant &net_prop_name, const std::vector<const db::Net *> *net_filter) const
|
||||
{
|
||||
// @@@ TODO: implement (how?)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FlatRegion::insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const
|
||||
{
|
||||
db::PropertyMapper pm (&layout->properties_repository (), mp_properties_repository.get_const ());
|
||||
|
|
|
|||
|
|
@ -103,6 +103,8 @@ public:
|
|||
virtual db::PropertiesRepository *properties_repository ();
|
||||
virtual const db::PropertiesRepository *properties_repository () const;
|
||||
|
||||
virtual RegionDelegate *nets (LayoutToNetlist *l2n, NetPropertyMode prop_mode, const tl::Variant &net_prop_name, const std::vector<const db::Net *> *net_filter) const;
|
||||
|
||||
void do_insert (const db::Polygon &polygon, db::properties_id_type prop_id);
|
||||
|
||||
void do_transform (const db::Trans &t)
|
||||
|
|
|
|||
|
|
@ -433,6 +433,7 @@ void LayoutToNetlist::mem_stat (MemStatistics *stat, MemStatistics::purpose_t pu
|
|||
db::mem_stat (stat, purpose, cat, m_dlrefs, true, (void *) this);
|
||||
db::mem_stat (stat, purpose, cat, m_named_regions, true, (void *) this);
|
||||
db::mem_stat (stat, purpose, cat, m_name_of_layer, true, (void *) this);
|
||||
db::mem_stat (stat, purpose, cat, m_region_by_original, true, (void *) this);
|
||||
db::mem_stat (stat, purpose, cat, m_joined_net_names, true, (void *) this);
|
||||
db::mem_stat (stat, purpose, cat, m_joined_net_names_per_cell, true, (void *) this);
|
||||
db::mem_stat (stat, purpose, cat, m_joined_nets, true, (void *) this);
|
||||
|
|
@ -537,7 +538,7 @@ db::Region *LayoutToNetlist::layer_by_name (const std::string &name)
|
|||
|
||||
db::Region *LayoutToNetlist::layer_by_index (unsigned int index)
|
||||
{
|
||||
std::map<unsigned int, std::string>::const_iterator n = m_name_of_layer.find (index);
|
||||
auto n = m_name_of_layer.find (index);
|
||||
if (n == m_name_of_layer.end ()) {
|
||||
return 0;
|
||||
} else {
|
||||
|
|
@ -545,6 +546,16 @@ db::Region *LayoutToNetlist::layer_by_index (unsigned int index)
|
|||
}
|
||||
}
|
||||
|
||||
db::Region *LayoutToNetlist::layer_by_original (const ShapeCollectionDelegateBase *original_delegate)
|
||||
{
|
||||
auto n = m_region_by_original.find (original_delegate);
|
||||
if (n == m_region_by_original.end ()) {
|
||||
return 0;
|
||||
} else {
|
||||
return new db::Region (new db::DeepRegion (n->second));
|
||||
}
|
||||
}
|
||||
|
||||
static db::DeepLayer dss_create_from_flat (db::DeepShapeStore &dss, const db::ShapeCollection &coll)
|
||||
{
|
||||
const db::Region *region = dynamic_cast<const db::Region *> (&coll);
|
||||
|
|
@ -601,6 +612,7 @@ void LayoutToNetlist::register_layer (const ShapeCollection &collection, const s
|
|||
}
|
||||
|
||||
m_named_regions [n] = dl;
|
||||
m_region_by_original [collection.get_delegate ()] = dl;
|
||||
m_name_of_layer [dl.layer ()] = n;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "dbCellMapping.h"
|
||||
#include "dbNetlistExtractor.h"
|
||||
#include "dbNetlistDeviceExtractor.h"
|
||||
#include "dbLayoutToNetlistEnums.h"
|
||||
#include "tlGlobPattern.h"
|
||||
|
||||
namespace db
|
||||
|
|
@ -34,60 +35,6 @@ namespace db
|
|||
|
||||
class NetlistBuilder;
|
||||
|
||||
/**
|
||||
* @brief An enum describing the way how net information is attached to shapes as properties in "build_nets"
|
||||
*/
|
||||
enum NetPropertyMode
|
||||
{
|
||||
/**
|
||||
* @brief Do no generate properties
|
||||
*/
|
||||
NPM_NoProperties,
|
||||
|
||||
/**
|
||||
* @brief Attach all net properties plus the net name (if a "netname_prop" is specified to "build_nets")
|
||||
*/
|
||||
NPM_AllProperties,
|
||||
|
||||
/**
|
||||
* @brief Attach net name only (if a "netname_prop" is specified to "build_nets")
|
||||
*/
|
||||
NPM_NetNameOnly,
|
||||
|
||||
/**
|
||||
* @brief Like NetNameOnly, but use a unique net ID (db::Net address actually) instead of name
|
||||
*/
|
||||
NPM_NetIDOnly,
|
||||
|
||||
/**
|
||||
* @brief Like NetNameOnly, but use a tuple of name and ID
|
||||
*/
|
||||
NPM_NetNameAndIDOnly,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An enum describing the way the net hierarchy is mapped
|
||||
*/
|
||||
enum BuildNetHierarchyMode
|
||||
{
|
||||
/**
|
||||
* @brief Flatten the net
|
||||
* Collects all shapes of a net and puts that into the net cell or circuit cell
|
||||
*/
|
||||
BNH_Flatten = 0,
|
||||
/**
|
||||
* @brief Build a net hierarchy adding cells for each subcircuit on the net
|
||||
* Uses the circuit_cell_prefix to build the subcircuit cell names
|
||||
*/
|
||||
BNH_SubcircuitCells = 1,
|
||||
/**
|
||||
* @brief No hierarchy
|
||||
* Just output the shapes of the net belonging to the circuit cell.
|
||||
* Connections are not indicated!
|
||||
*/
|
||||
BNH_Disconnected = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A generic framework for extracting netlists from layouts
|
||||
*
|
||||
|
|
@ -353,6 +300,20 @@ public:
|
|||
*/
|
||||
db::Region *layer_by_index (unsigned int index);
|
||||
|
||||
/**
|
||||
* @brief Gets the internal layer from the original layer
|
||||
*/
|
||||
db::Region *layer_by_original (const ShapeCollection &original_layer)
|
||||
{
|
||||
return layer_by_original (original_layer.get_delegate ());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the layer from the original layer's delegate
|
||||
* Returns 0 if the original layer was not registered as an input_layer.
|
||||
*/
|
||||
db::Region *layer_by_original (const ShapeCollectionDelegateBase *original_delegate);
|
||||
|
||||
/**
|
||||
* @brief Iterates over the layer indexes and names managed by this object (begin)
|
||||
*/
|
||||
|
|
@ -971,6 +932,7 @@ private:
|
|||
std::set<db::DeepLayer> m_dlrefs;
|
||||
std::map<std::string, db::DeepLayer> m_named_regions;
|
||||
std::map<unsigned int, std::string> m_name_of_layer;
|
||||
std::map<const db::ShapeCollectionDelegateBase *, db::DeepLayer> m_region_by_original;
|
||||
bool m_netlist_extracted;
|
||||
bool m_is_flat;
|
||||
double m_device_scaling;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,85 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2023 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _HDR_dbLayoutToNetlistEnums
|
||||
#define _HDR_dbLayoutToNetlistEnums
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief An enum describing the way how net information is attached to shapes as properties in "build_nets"
|
||||
*/
|
||||
enum NetPropertyMode
|
||||
{
|
||||
/**
|
||||
* @brief Do no generate properties
|
||||
*/
|
||||
NPM_NoProperties,
|
||||
|
||||
/**
|
||||
* @brief Attach all net properties plus the net name (if a "netname_prop" is specified to "build_nets")
|
||||
*/
|
||||
NPM_AllProperties,
|
||||
|
||||
/**
|
||||
* @brief Attach net name only (if a "netname_prop" is specified to "build_nets")
|
||||
*/
|
||||
NPM_NetNameOnly,
|
||||
|
||||
/**
|
||||
* @brief Like NetNameOnly, but use a unique net ID (db::Net address actually) instead of name
|
||||
*/
|
||||
NPM_NetIDOnly,
|
||||
|
||||
/**
|
||||
* @brief Like NetNameOnly, but use a tuple of name and ID
|
||||
*/
|
||||
NPM_NetNameAndIDOnly,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An enum describing the way the net hierarchy is mapped
|
||||
*/
|
||||
enum BuildNetHierarchyMode
|
||||
{
|
||||
/**
|
||||
* @brief Flatten the net
|
||||
* Collects all shapes of a net and puts that into the net cell or circuit cell
|
||||
*/
|
||||
BNH_Flatten = 0,
|
||||
/**
|
||||
* @brief Build a net hierarchy adding cells for each subcircuit on the net
|
||||
* Uses the circuit_cell_prefix to build the subcircuit cell names
|
||||
*/
|
||||
BNH_SubcircuitCells = 1,
|
||||
/**
|
||||
* @brief No hierarchy
|
||||
* Just output the shapes of the net belonging to the circuit cell.
|
||||
* Connections are not indicated!
|
||||
*/
|
||||
BNH_Disconnected = 2
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -440,6 +440,12 @@ OriginalLayerRegion::insert_into (Layout *layout, db::cell_index_type into_cell,
|
|||
}
|
||||
}
|
||||
|
||||
RegionDelegate *OriginalLayerRegion::nets (LayoutToNetlist *l2n, NetPropertyMode prop_mode, const tl::Variant &net_prop_name, const std::vector<const db::Net *> *net_filter) const
|
||||
{
|
||||
// @@@ TODO: implement (how?)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
OriginalLayerRegion::ensure_merged_polygons_valid () const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -76,6 +76,8 @@ public:
|
|||
|
||||
virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const;
|
||||
|
||||
virtual RegionDelegate *nets (LayoutToNetlist *l2n, NetPropertyMode prop_mode, const tl::Variant &net_prop_name, const std::vector<const db::Net *> *net_filter) const;
|
||||
|
||||
protected:
|
||||
virtual void merged_semantics_changed ();
|
||||
virtual void min_coherence_changed ();
|
||||
|
|
|
|||
|
|
@ -1830,6 +1830,20 @@ public:
|
|||
return mp_delegate->insert_into (layout, into_cell, into_layer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pulls the net shapes from a LayoutToNetlist database
|
||||
*
|
||||
* This will pull the net shapes from the LayoutToNetlist database, provided that this
|
||||
* layer was an input to the netlist extraction.
|
||||
*
|
||||
* Netlist names will be attached as properties according to prop_mode and net_prop_name.
|
||||
* A net filter can be provided so that only certain nets are produced.
|
||||
*/
|
||||
Region nets (LayoutToNetlist *l2n, NetPropertyMode prop_mode, const tl::Variant &net_prop_name, const std::vector<const db::Net *> *nets = 0) const
|
||||
{
|
||||
return Region (mp_delegate->nets (l2n, prop_mode, net_prop_name, nets));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delivers texts as dots (degenerated edges)
|
||||
*
|
||||
|
|
|
|||
|
|
@ -35,8 +35,10 @@
|
|||
#include "dbGenericShapeIterator.h"
|
||||
#include "dbRegionLocalOperations.h"
|
||||
#include "dbHash.h"
|
||||
#include "dbLayoutToNetlistEnums.h"
|
||||
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace db {
|
||||
|
|
@ -46,6 +48,8 @@ class EdgeFilterBase;
|
|||
class EdgesDelegate;
|
||||
class EdgePairsDelegate;
|
||||
class CompoundRegionOperationNode;
|
||||
class LayoutToNetlist;
|
||||
class Net;
|
||||
|
||||
/**
|
||||
* @brief A base class for polygon filters
|
||||
|
|
@ -326,6 +330,8 @@ public:
|
|||
|
||||
virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const = 0;
|
||||
|
||||
virtual RegionDelegate *nets (LayoutToNetlist *l2n, NetPropertyMode prop_mode, const tl::Variant &net_prop_name, const std::vector<const db::Net *> *net_filter) const = 0;
|
||||
|
||||
const std::string &progress_desc () const
|
||||
{
|
||||
return m_progress_desc;
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ static unsigned int define_layer (db::Layout &ly, db::LayerMap &lmap, int gds_la
|
|||
TEST(0_Develop)
|
||||
{
|
||||
db::Layout ly;
|
||||
db::DeepShapeStore dss;
|
||||
db::LayerMap lmap;
|
||||
|
||||
unsigned int poly = define_layer (ly, lmap, 7);
|
||||
|
|
@ -72,77 +73,57 @@ TEST(0_Develop)
|
|||
}
|
||||
|
||||
db::Cell &tc = ly.cell (*ly.begin_top_down ());
|
||||
db::LayoutToNetlist l2n (db::RecursiveShapeIterator (ly, tc, std::set<unsigned int> ()));
|
||||
|
||||
std::unique_ptr<db::Region> rpoly (l2n.make_polygon_layer (poly, "poly"));
|
||||
std::unique_ptr<db::Region> rcont (l2n.make_polygon_layer (cont, "cont"));
|
||||
std::unique_ptr<db::Region> rmetal1 (l2n.make_polygon_layer (metal1, "metal1"));
|
||||
std::unique_ptr<db::Region> rvia1 (l2n.make_polygon_layer (via1, "via1"));
|
||||
std::unique_ptr<db::Region> rmetal2 (l2n.make_polygon_layer (metal2, "metal2"));
|
||||
std::unique_ptr<db::Region> rvia2 (l2n.make_polygon_layer (via1, "via2"));
|
||||
std::unique_ptr<db::Region> rmetal3 (l2n.make_polygon_layer (metal2, "metal3"));
|
||||
std::unique_ptr<db::Region> rvia3 (l2n.make_polygon_layer (via1, "via3"));
|
||||
std::unique_ptr<db::Region> rmetal4 (l2n.make_polygon_layer (metal2, "metal4"));
|
||||
db::Region rpoly (db::RecursiveShapeIterator (ly, tc, poly), dss);
|
||||
db::Region rcont (db::RecursiveShapeIterator (ly, tc, cont), dss);
|
||||
db::Region rmetal1 (db::RecursiveShapeIterator (ly, tc, metal1), dss);
|
||||
db::Region rvia1 (db::RecursiveShapeIterator (ly, tc, via1), dss);
|
||||
db::Region rmetal2 (db::RecursiveShapeIterator (ly, tc, metal2), dss);
|
||||
db::Region rvia2 (db::RecursiveShapeIterator (ly, tc, via2), dss);
|
||||
db::Region rmetal3 (db::RecursiveShapeIterator (ly, tc, metal3), dss);
|
||||
db::Region rvia3 (db::RecursiveShapeIterator (ly, tc, via3), dss);
|
||||
db::Region rmetal4 (db::RecursiveShapeIterator (ly, tc, metal4), dss);
|
||||
|
||||
db::LayoutToNetlist l2n (&dss);
|
||||
|
||||
// net extraction
|
||||
|
||||
// Intra-layer
|
||||
l2n.connect (*rpoly);
|
||||
l2n.connect (*rcont);
|
||||
l2n.connect (*rmetal1);
|
||||
l2n.connect (*rvia1);
|
||||
l2n.connect (*rmetal2);
|
||||
l2n.connect (*rvia2);
|
||||
l2n.connect (*rmetal3);
|
||||
l2n.connect (*rvia3);
|
||||
l2n.connect (*rmetal4);
|
||||
l2n.connect (rpoly);
|
||||
l2n.connect (rcont);
|
||||
l2n.connect (rmetal1);
|
||||
l2n.connect (rvia1);
|
||||
l2n.connect (rmetal2);
|
||||
l2n.connect (rvia2);
|
||||
l2n.connect (rmetal3);
|
||||
l2n.connect (rvia3);
|
||||
l2n.connect (rmetal4);
|
||||
// Inter-layer
|
||||
l2n.connect (*rpoly, *rcont);
|
||||
l2n.connect (*rcont, *rmetal1);
|
||||
l2n.connect (*rmetal1, *rvia1);
|
||||
l2n.connect (*rvia1, *rmetal2);
|
||||
l2n.connect (*rmetal2, *rvia2);
|
||||
l2n.connect (*rvia2, *rmetal3);
|
||||
l2n.connect (*rmetal3, *rvia3);
|
||||
l2n.connect (*rvia3, *rmetal4);
|
||||
l2n.connect (rpoly, rcont);
|
||||
l2n.connect (rcont, rmetal1);
|
||||
l2n.connect (rmetal1, rvia1);
|
||||
l2n.connect (rvia1, rmetal2);
|
||||
l2n.connect (rmetal2, rvia2);
|
||||
l2n.connect (rvia2, rmetal3);
|
||||
l2n.connect (rmetal3, rvia3);
|
||||
l2n.connect (rvia3, rmetal4);
|
||||
|
||||
l2n.extract_netlist ();
|
||||
|
||||
// ....
|
||||
// @@@ TODO: beautify
|
||||
db::Region rmetal1_nets = rmetal1.nets (&l2n, db::NPM_NetNameAndIDOnly, tl::Variant (1));
|
||||
db::Region rmetal2_nets = rmetal2.nets (&l2n, db::NPM_NetNameAndIDOnly, tl::Variant (1));
|
||||
|
||||
db::Layout ly2;
|
||||
ly2.dbu (l2n.internal_layout ()->dbu ());
|
||||
db::Cell &top2 = ly2.cell (ly2.add_cell (ly.cell_name (tc.cell_index ())));
|
||||
db::Region res1 = rmetal1_nets.bool_and (rmetal2_nets, db::SamePropertiesConstraint);
|
||||
db::Region res2 = rmetal1_nets.bool_and (rmetal2_nets, db::DifferentPropertiesConstraint);
|
||||
db::Region res3 = rmetal1_nets.bool_and (rmetal2_nets, db::NoPropertyConstraint);
|
||||
|
||||
db::CellMapping cm = l2n.cell_mapping_into (ly2, top2, false /*without device cells*/);
|
||||
rmetal1_nets.insert_into (&ly, tc.cell_index (), ly.insert_layer (db::LayerProperties (100, 0)));
|
||||
rmetal2_nets.insert_into (&ly, tc.cell_index (), ly.insert_layer (db::LayerProperties (101, 0)));
|
||||
|
||||
std::map<unsigned int, const db::Region *> lmap_write;
|
||||
unsigned int wpoly, wcont, wmetal1, wvia1, wmetal2;
|
||||
lmap_write [wpoly = ly2.insert_layer (db::LayerProperties (7, 0))] = l2n.layer_by_name ("poly");
|
||||
lmap_write [wcont = ly2.insert_layer (db::LayerProperties (14, 0))] = l2n.layer_by_name ("cont");
|
||||
lmap_write [wmetal1 = ly2.insert_layer (db::LayerProperties (15, 0))] = l2n.layer_by_name ("metal1");
|
||||
lmap_write [wvia1 = ly2.insert_layer (db::LayerProperties (16, 0))] = l2n.layer_by_name ("via1");
|
||||
lmap_write [wmetal2 = ly2.insert_layer (db::LayerProperties (17, 0))] = l2n.layer_by_name ("metal2");
|
||||
|
||||
l2n.build_all_nets (cm, ly2, lmap_write, "NET_", db::NPM_NetNameAndIDOnly, tl::Variant (1), db::BNH_SubcircuitCells, "SC_", 0 /*don't produce devices*/);
|
||||
|
||||
unsigned int out1 = ly2.insert_layer (db::LayerProperties (1000, 0));
|
||||
unsigned int out2 = ly2.insert_layer (db::LayerProperties (1001, 0));
|
||||
unsigned int out3 = ly2.insert_layer (db::LayerProperties (1002, 0));
|
||||
|
||||
db::local_processor<db::PolygonRefWithProperties, db::PolygonRefWithProperties, db::PolygonRefWithProperties> proc (&ly2, &top2);
|
||||
{
|
||||
db::BoolAndOrNotLocalOperationWithProperties n2n (true, &ly2.properties_repository (), &ly2.properties_repository (), &ly2.properties_repository (), db::SamePropertiesConstraint);
|
||||
proc.run (&n2n, wmetal1, wmetal2, out1);
|
||||
}
|
||||
{
|
||||
db::BoolAndOrNotLocalOperationWithProperties n2n (true, &ly2.properties_repository (), &ly2.properties_repository (), &ly2.properties_repository (), db::DifferentPropertiesConstraint);
|
||||
proc.run (&n2n, wmetal1, wmetal2, out2);
|
||||
}
|
||||
{
|
||||
db::BoolAndOrNotLocalOperationWithProperties n2n (true, &ly2.properties_repository (), &ly2.properties_repository (), &ly2.properties_repository (), db::NoPropertyConstraint);
|
||||
proc.run (&n2n, wmetal1, wmetal2, out3);
|
||||
}
|
||||
res1.insert_into (&ly, tc.cell_index (), ly.insert_layer (db::LayerProperties (1000, 0)));
|
||||
res2.insert_into (&ly, tc.cell_index (), ly.insert_layer (db::LayerProperties (1001, 0)));
|
||||
res3.insert_into (&ly, tc.cell_index (), ly.insert_layer (db::LayerProperties (1002, 0)));
|
||||
|
||||
{
|
||||
db::SaveLayoutOptions options;
|
||||
|
|
@ -151,6 +132,6 @@ TEST(0_Develop)
|
|||
|
||||
tl::OutputStream stream (fn);
|
||||
db::Writer writer (options);
|
||||
writer.write (ly2, stream);
|
||||
writer.write (ly, stream);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue