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)
{
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 &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 ())));
}
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);

View File

@ -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);
};
}

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 ();
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);