mirror of https://github.com/KLayout/klayout.git
WIP: device extractor now declares it's layers, passing layers by name supported now.
This commit is contained in:
parent
c665d6aceb
commit
a5b9cbfe5b
|
|
@ -66,12 +66,13 @@ const tl::Variant &NetlistDeviceExtractor::terminal_property_name ()
|
|||
|
||||
void NetlistDeviceExtractor::initialize (db::Netlist *nl)
|
||||
{
|
||||
m_layer_definitions.clear ();
|
||||
m_device_classes.clear ();
|
||||
m_device_name_index = 0;
|
||||
m_propname_id = 0;
|
||||
m_netlist.reset (nl);
|
||||
|
||||
create_device_classes ();
|
||||
setup ();
|
||||
}
|
||||
|
||||
static void insert_into_region (const db::PolygonRef &s, const db::ICplxTrans &tr, db::Region ®ion)
|
||||
|
|
@ -79,25 +80,46 @@ static void insert_into_region (const db::PolygonRef &s, const db::ICplxTrans &t
|
|||
region.insert (s.obj ().transformed (tr * db::ICplxTrans (s.trans ())));
|
||||
}
|
||||
|
||||
void NetlistDeviceExtractor::extract (db::DeepShapeStore &dss, const std::vector<db::DeepLayer> &deep_layers, db::Netlist *nl)
|
||||
void NetlistDeviceExtractor::extract (db::DeepShapeStore &dss, const NetlistDeviceExtractor::input_layers &layer_map, db::Netlist *nl)
|
||||
{
|
||||
db::Layout &layout = dss.layout ();
|
||||
db::Cell &cell = dss.initial_cell ();
|
||||
initialize (nl);
|
||||
|
||||
std::vector<unsigned int> layers;
|
||||
layers.reserve (deep_layers.size ());
|
||||
layers.reserve (m_layer_definitions.size ());
|
||||
|
||||
for (layer_definitions::const_iterator ld = begin_layer_definitions (); ld != end_layer_definitions (); ++ld) {
|
||||
|
||||
input_layers::const_iterator l = layer_map.find (ld->name);
|
||||
if (l == layer_map.end ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Missing input layer for device extraction: ")) + ld->name);
|
||||
}
|
||||
|
||||
tl_assert (l->second != 0);
|
||||
db::DeepRegion *dr = dynamic_cast<db::DeepRegion *> (l->second->delegate ());
|
||||
if (dr == 0) {
|
||||
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Invalid region passed to input layer '%s' for device extraction: must be of deep region kind")), ld->name));
|
||||
}
|
||||
|
||||
if (&dr->deep_layer ().layout () != &dss.layout () || &dr->deep_layer ().initial_cell () != &dss.initial_cell ()) {
|
||||
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Invalid region passed to input layer '%s' for device extraction: not originating from the same source")), ld->name));
|
||||
}
|
||||
|
||||
layers.push_back (dr->deep_layer ().layer ());
|
||||
|
||||
for (std::vector<db::DeepLayer>::const_iterator dl = deep_layers.begin (); dl != deep_layers.end (); ++dl) {
|
||||
tl_assert (&dl->layout () == &layout);
|
||||
layers.push_back (dl->layer ());
|
||||
}
|
||||
|
||||
extract (layout, cell, layers, nl);
|
||||
extract_without_initialize (dss.layout (), dss.initial_cell (), layers, nl);
|
||||
}
|
||||
|
||||
void NetlistDeviceExtractor::extract (db::Layout &layout, db::Cell &cell, const std::vector<unsigned int> &layers, db::Netlist *nl)
|
||||
{
|
||||
initialize (nl);
|
||||
extract_without_initialize (layout, cell, layers, nl);
|
||||
}
|
||||
|
||||
void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db::Cell &cell, const std::vector<unsigned int> &layers, db::Netlist *nl)
|
||||
{
|
||||
tl_assert (layers.size () == m_layer_definitions.size ());
|
||||
|
||||
typedef db::PolygonRef shape_type;
|
||||
db::ShapeIterator::flags_type shape_iter_flags = db::ShapeIterator::Polygons;
|
||||
|
|
@ -176,7 +198,7 @@ void NetlistDeviceExtractor::extract (db::Layout &layout, db::Cell &cell, const
|
|||
}
|
||||
}
|
||||
|
||||
void NetlistDeviceExtractor::create_device_classes ()
|
||||
void NetlistDeviceExtractor::setup ()
|
||||
{
|
||||
// .. the default implementation does nothing ..
|
||||
}
|
||||
|
|
@ -199,6 +221,11 @@ void NetlistDeviceExtractor::register_device_class (DeviceClass *device_class)
|
|||
m_device_classes.push_back (device_class);
|
||||
}
|
||||
|
||||
void NetlistDeviceExtractor::define_layer (const std::string &name, const std::string &description)
|
||||
{
|
||||
m_layer_definitions.push_back (db::NetlistDeviceExtractorLayerDefinition (name, description, m_layer_definitions.size ()));
|
||||
}
|
||||
|
||||
Device *NetlistDeviceExtractor::create_device (unsigned int device_class_index)
|
||||
{
|
||||
tl_assert (mp_circuit != 0);
|
||||
|
|
|
|||
|
|
@ -145,6 +145,40 @@ private:
|
|||
std::string m_category_name, m_category_description;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Specifies a single layer from the device extractor
|
||||
*/
|
||||
class DB_PUBLIC NetlistDeviceExtractorLayerDefinition
|
||||
{
|
||||
public:
|
||||
NetlistDeviceExtractorLayerDefinition ()
|
||||
: index (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
NetlistDeviceExtractorLayerDefinition (const std::string &_name, const std::string &_description, size_t _index)
|
||||
: name (_name), description (_description), index (_index)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The formal name
|
||||
*/
|
||||
std::string name;
|
||||
|
||||
/**
|
||||
* @brief The human-readable description
|
||||
*/
|
||||
std::string description;
|
||||
|
||||
/**
|
||||
* @brief The index of the layer
|
||||
*/
|
||||
size_t index;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Implements the device extraction for a specific setup
|
||||
*
|
||||
|
|
@ -157,6 +191,9 @@ class DB_PUBLIC NetlistDeviceExtractor
|
|||
public:
|
||||
typedef std::list<db::NetlistDeviceExtractorError> error_list;
|
||||
typedef error_list::const_iterator error_iterator;
|
||||
typedef std::vector<db::NetlistDeviceExtractorLayerDefinition> layer_definitions;
|
||||
typedef layer_definitions::const_iterator layer_definitions_iterator;
|
||||
typedef std::map<std::string, db::Region *> input_layers;
|
||||
|
||||
/**
|
||||
* @brief Default constructor
|
||||
|
|
@ -202,9 +239,10 @@ public:
|
|||
* @brief Extracts the devices from a list of regions
|
||||
*
|
||||
* This method behaves identical to the other "extract" method, but accepts
|
||||
* DeepShape layers for input. By definition, these already have the "PolygonRef" type.
|
||||
* named regions for input. These regions need to be of deep region type and
|
||||
* originate from the same layout than the DeepShapeStore.
|
||||
*/
|
||||
void extract (DeepShapeStore &dss, const std::vector<DeepLayer> &layers, Netlist *netlist);
|
||||
void extract (DeepShapeStore &dss, const input_layers &layers, Netlist *netlist);
|
||||
|
||||
/**
|
||||
* @brief Gets the error iterator, begin
|
||||
|
|
@ -230,14 +268,36 @@ public:
|
|||
return ! m_errors.empty ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the layer definition iterator, begin
|
||||
*/
|
||||
layer_definitions_iterator begin_layer_definitions () const
|
||||
{
|
||||
return m_layer_definitions.begin ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the layer definition iterator, end
|
||||
*/
|
||||
layer_definitions_iterator end_layer_definitions () const
|
||||
{
|
||||
return m_layer_definitions.end ();
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Creates the device classes
|
||||
* @brief Sets up the extractor
|
||||
*
|
||||
* This method is supposed to set up the device extractor. This involves two basic steps:
|
||||
* defining the device classes and setting up the device layers.
|
||||
*
|
||||
* At least one device class needs to be defined. Use "register_device_class" to register
|
||||
* the device classes you need. The first device class registered has device class index 0,
|
||||
* the further ones 1, 2, etc.
|
||||
*
|
||||
* The device layers need to be defined by calling "define_layer" once or several times.
|
||||
*/
|
||||
virtual void create_device_classes ();
|
||||
virtual void setup ();
|
||||
|
||||
/**
|
||||
* @brief Gets the connectivity object used to extract the device geometry
|
||||
|
|
@ -264,9 +324,20 @@ protected:
|
|||
* @brief Registers a device class
|
||||
* The device class object will become owned by the netlist and must not be deleted by
|
||||
* the caller.
|
||||
* This method shall be used inside the implementation of "setup" to register
|
||||
* the device classes.
|
||||
*/
|
||||
void register_device_class (DeviceClass *device_class);
|
||||
|
||||
/**
|
||||
* @brief Defines a layer
|
||||
* Each call will define one more layer for the device extraction.
|
||||
* This method shall be used inside the implementation of "setip" to define
|
||||
* the device layers. The actual geometries are later available to "extract_devices"
|
||||
* in the order the layers are defined.
|
||||
*/
|
||||
void define_layer (const std::string &name, const std::string &description = std::string ());
|
||||
|
||||
/**
|
||||
* @brief Creates a device
|
||||
* The device object returned can be configured by the caller, e.g. set parameters.
|
||||
|
|
@ -366,6 +437,7 @@ private:
|
|||
db::cell_index_type m_cell_index;
|
||||
db::Circuit *mp_circuit;
|
||||
std::vector<db::DeviceClass *> m_device_classes;
|
||||
layer_definitions m_layer_definitions;
|
||||
std::vector<unsigned int> m_layers;
|
||||
unsigned int m_device_name_index;
|
||||
error_list m_errors;
|
||||
|
|
@ -375,6 +447,8 @@ private:
|
|||
* This method will produce the device classes required for the device extraction.
|
||||
*/
|
||||
void initialize (db::Netlist *nl);
|
||||
|
||||
void extract_without_initialize (db::Layout &layout, db::Cell &cell, const std::vector<unsigned int> &layers, db::Netlist *nl);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,8 +57,13 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void create_device_classes ()
|
||||
virtual void setup ()
|
||||
{
|
||||
define_layer ("PD", "P diffusion");
|
||||
define_layer ("ND", "N diffusion");
|
||||
define_layer ("G", "Gate");
|
||||
define_layer ("P", "Poly");
|
||||
|
||||
db::DeviceClassMOS3Transistor *pmos_class = new db::DeviceClassMOS3Transistor ();
|
||||
pmos_class->set_name ("PMOS");
|
||||
register_device_class (pmos_class);
|
||||
|
|
@ -417,11 +422,11 @@ TEST(2_DeviceAndNetExtraction)
|
|||
// 21/0 -> Gate
|
||||
MOSFETExtractor ex (&ly);
|
||||
|
||||
std::vector<db::DeepLayer> dl;
|
||||
dl.push_back (rpdiff);
|
||||
dl.push_back (rndiff);
|
||||
dl.push_back (rgate);
|
||||
dl.push_back (rpoly);
|
||||
db::NetlistDeviceExtractor::input_layers dl;
|
||||
dl["PD"] = &rpdiff;
|
||||
dl["ND"] = &rndiff;
|
||||
dl["G"] = &rgate;
|
||||
dl["P"] = &rpoly;
|
||||
|
||||
ex.extract (dss, dl, &nl);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue