WIP: device extractor now declares it's layers, passing layers by name supported now.

This commit is contained in:
Matthias Koefferlein 2018-12-28 01:53:27 +01:00
parent c665d6aceb
commit a5b9cbfe5b
3 changed files with 126 additions and 20 deletions

View File

@ -66,12 +66,13 @@ const tl::Variant &NetlistDeviceExtractor::terminal_property_name ()
void NetlistDeviceExtractor::initialize (db::Netlist *nl) void NetlistDeviceExtractor::initialize (db::Netlist *nl)
{ {
m_layer_definitions.clear ();
m_device_classes.clear (); m_device_classes.clear ();
m_device_name_index = 0; m_device_name_index = 0;
m_propname_id = 0; m_propname_id = 0;
m_netlist.reset (nl); m_netlist.reset (nl);
create_device_classes (); setup ();
} }
static void insert_into_region (const db::PolygonRef &s, const db::ICplxTrans &tr, db::Region &region) static void insert_into_region (const db::PolygonRef &s, const db::ICplxTrans &tr, db::Region &region)
@ -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 ()))); 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 (); initialize (nl);
db::Cell &cell = dss.initial_cell ();
std::vector<unsigned int> layers; 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) void NetlistDeviceExtractor::extract (db::Layout &layout, db::Cell &cell, const std::vector<unsigned int> &layers, db::Netlist *nl)
{ {
initialize (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; typedef db::PolygonRef shape_type;
db::ShapeIterator::flags_type shape_iter_flags = db::ShapeIterator::Polygons; 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 .. // .. the default implementation does nothing ..
} }
@ -199,6 +221,11 @@ void NetlistDeviceExtractor::register_device_class (DeviceClass *device_class)
m_device_classes.push_back (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) Device *NetlistDeviceExtractor::create_device (unsigned int device_class_index)
{ {
tl_assert (mp_circuit != 0); tl_assert (mp_circuit != 0);

View File

@ -145,6 +145,40 @@ private:
std::string m_category_name, m_category_description; 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 * @brief Implements the device extraction for a specific setup
* *
@ -157,6 +191,9 @@ class DB_PUBLIC NetlistDeviceExtractor
public: public:
typedef std::list<db::NetlistDeviceExtractorError> error_list; typedef std::list<db::NetlistDeviceExtractorError> error_list;
typedef error_list::const_iterator error_iterator; 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 * @brief Default constructor
@ -202,9 +239,10 @@ public:
* @brief Extracts the devices from a list of regions * @brief Extracts the devices from a list of regions
* *
* This method behaves identical to the other "extract" method, but accepts * 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 * @brief Gets the error iterator, begin
@ -230,14 +268,36 @@ public:
return ! m_errors.empty (); 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: 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 * 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 device classes you need. The first device class registered has device class index 0,
* the further ones 1, 2, etc. * 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 * @brief Gets the connectivity object used to extract the device geometry
@ -264,9 +324,20 @@ protected:
* @brief Registers a device class * @brief Registers a device class
* The device class object will become owned by the netlist and must not be deleted by * The device class object will become owned by the netlist and must not be deleted by
* the caller. * the caller.
* This method shall be used inside the implementation of "setup" to register
* the device classes.
*/ */
void register_device_class (DeviceClass *device_class); 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 * @brief Creates a device
* The device object returned can be configured by the caller, e.g. set parameters. * 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::cell_index_type m_cell_index;
db::Circuit *mp_circuit; db::Circuit *mp_circuit;
std::vector<db::DeviceClass *> m_device_classes; std::vector<db::DeviceClass *> m_device_classes;
layer_definitions m_layer_definitions;
std::vector<unsigned int> m_layers; std::vector<unsigned int> m_layers;
unsigned int m_device_name_index; unsigned int m_device_name_index;
error_list m_errors; error_list m_errors;
@ -375,6 +447,8 @@ private:
* This method will produce the device classes required for the device extraction. * This method will produce the device classes required for the device extraction.
*/ */
void initialize (db::Netlist *nl); void initialize (db::Netlist *nl);
void extract_without_initialize (db::Layout &layout, db::Cell &cell, const std::vector<unsigned int> &layers, db::Netlist *nl);
}; };
} }

View File

@ -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 (); db::DeviceClassMOS3Transistor *pmos_class = new db::DeviceClassMOS3Transistor ();
pmos_class->set_name ("PMOS"); pmos_class->set_name ("PMOS");
register_device_class (pmos_class); register_device_class (pmos_class);
@ -417,11 +422,11 @@ TEST(2_DeviceAndNetExtraction)
// 21/0 -> Gate // 21/0 -> Gate
MOSFETExtractor ex (&ly); MOSFETExtractor ex (&ly);
std::vector<db::DeepLayer> dl; db::NetlistDeviceExtractor::input_layers dl;
dl.push_back (rpdiff); dl["PD"] = &rpdiff;
dl.push_back (rndiff); dl["ND"] = &rndiff;
dl.push_back (rgate); dl["G"] = &rgate;
dl.push_back (rpoly); dl["P"] = &rpoly;
ex.extract (dss, dl, &nl); ex.extract (dss, dl, &nl);