mirror of https://github.com/KLayout/klayout.git
WIP: GSI binding of device extractor classes.
This commit is contained in:
parent
c571535e55
commit
425acda31a
|
|
@ -149,7 +149,8 @@ SOURCES = \
|
|||
dbNetlistDeviceExtractor.cc \
|
||||
dbNetlistExtractor.cc \
|
||||
gsiDeclDbNetlistDeviceClasses.cc \
|
||||
gsiDeclDbNetlistDeviceExtractor.cc
|
||||
gsiDeclDbNetlistDeviceExtractor.cc \
|
||||
gsiDeclDbHierNetworkProcessor.cc
|
||||
|
||||
HEADERS = \
|
||||
dbArray.h \
|
||||
|
|
|
|||
|
|
@ -58,6 +58,11 @@ public:
|
|||
*/
|
||||
Connectivity ();
|
||||
|
||||
/**
|
||||
* @brief Adds intra-layer connectivity for layer l
|
||||
*/
|
||||
void connect (unsigned int l);
|
||||
|
||||
/**
|
||||
* @brief Adds inter-layer connectivity
|
||||
*/
|
||||
|
|
@ -77,11 +82,6 @@ public:
|
|||
*/
|
||||
void connect (const db::DeepLayer &la, const db::DeepLayer &lb);
|
||||
|
||||
/**
|
||||
* @brief Adds intra-layer connectivity for layer l
|
||||
*/
|
||||
void connect (unsigned int l);
|
||||
|
||||
/**
|
||||
* @brief Begin iterator for the layers involved
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -218,6 +218,9 @@ void NetlistDeviceExtractor::register_device_class (DeviceClass *device_class)
|
|||
if (mp_device_class != 0) {
|
||||
throw tl::Exception (tl::to_string (tr ("Device class already set")));
|
||||
}
|
||||
if (m_name.empty ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("No device extractor/device class name set")));
|
||||
}
|
||||
|
||||
tl_assert (device_class != 0);
|
||||
mp_device_class = device_class;
|
||||
|
|
@ -286,16 +289,10 @@ void NetlistDeviceExtractor::error (const std::string &msg)
|
|||
m_errors.push_back (db::NetlistDeviceExtractorError (cell_name (), msg));
|
||||
}
|
||||
|
||||
void NetlistDeviceExtractor::error (const std::string &msg, const db::Polygon &poly)
|
||||
void NetlistDeviceExtractor::error (const std::string &msg, const db::DPolygon &poly)
|
||||
{
|
||||
error (msg);
|
||||
m_errors.back ().set_geometry (db::Region (poly));
|
||||
}
|
||||
|
||||
void NetlistDeviceExtractor::error (const std::string &msg, const db::Region ®ion)
|
||||
{
|
||||
error (msg);
|
||||
m_errors.back ().set_geometry (region);
|
||||
m_errors.back ().set_geometry (poly);
|
||||
}
|
||||
|
||||
void NetlistDeviceExtractor::error (const std::string &category_name, const std::string &category_description, const std::string &msg)
|
||||
|
|
@ -305,16 +302,10 @@ void NetlistDeviceExtractor::error (const std::string &category_name, const std:
|
|||
m_errors.back ().set_category_description (category_description);
|
||||
}
|
||||
|
||||
void NetlistDeviceExtractor::error (const std::string &category_name, const std::string &category_description, const std::string &msg, const db::Polygon &poly)
|
||||
void NetlistDeviceExtractor::error (const std::string &category_name, const std::string &category_description, const std::string &msg, const db::DPolygon &poly)
|
||||
{
|
||||
error (category_name, category_description, msg);
|
||||
m_errors.back ().set_geometry (db::Region (poly));
|
||||
}
|
||||
|
||||
void NetlistDeviceExtractor::error (const std::string &category_name, const std::string &category_description, const std::string &msg, const db::Region ®ion)
|
||||
{
|
||||
error (category_name, category_description, msg);
|
||||
m_errors.back ().set_geometry (region);
|
||||
m_errors.back ().set_geometry (poly);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,9 +91,9 @@ public:
|
|||
|
||||
/**
|
||||
* @brief Gets the geometry for this error
|
||||
* Not all errors may specify a geometry.
|
||||
* Not all errors may specify a geometry. In this case, the polygon is empty.
|
||||
*/
|
||||
const db::Region &geometry () const
|
||||
const db::DPolygon &geometry () const
|
||||
{
|
||||
return m_geometry;
|
||||
}
|
||||
|
|
@ -101,7 +101,7 @@ public:
|
|||
/**
|
||||
* @brief Sets the geometry
|
||||
*/
|
||||
void set_geometry (const db::Region &g)
|
||||
void set_geometry (const db::DPolygon &g)
|
||||
{
|
||||
m_geometry = g;
|
||||
}
|
||||
|
|
@ -141,7 +141,7 @@ public:
|
|||
private:
|
||||
std::string m_cell_name;
|
||||
std::string m_message;
|
||||
db::Region m_geometry;
|
||||
db::DPolygon m_geometry;
|
||||
std::string m_category_name, m_category_description;
|
||||
};
|
||||
|
||||
|
|
@ -293,14 +293,21 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Sets the name of the device class and the device extractor
|
||||
*/
|
||||
void set_name (const std::string &name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
* defining the device classe and setting up the device layers.
|
||||
*
|
||||
* At least one device class needs to be defined. Use "register_device_class" to register
|
||||
* the device class you need.
|
||||
* Use "register_device_class" to register the device class you need.
|
||||
*
|
||||
* The device layers need to be defined by calling "define_layer" once or several times.
|
||||
*/
|
||||
|
|
@ -340,7 +347,7 @@ protected:
|
|||
/**
|
||||
* @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
|
||||
* This method shall be used inside the implementation of "setup" to define
|
||||
* the device layers. The actual geometries are later available to "extract_devices"
|
||||
* in the order the layers are defined.
|
||||
*/
|
||||
|
|
@ -411,12 +418,15 @@ protected:
|
|||
/**
|
||||
* @brief Issues an error with the given message and error shape
|
||||
*/
|
||||
void error (const std::string &msg, const db::Polygon &poly);
|
||||
void error (const std::string &msg, const db::DPolygon &poly);
|
||||
|
||||
/**
|
||||
* @brief Issues an error with the given message and error geometry
|
||||
* @brief Issues an error with the given message and error shape
|
||||
*/
|
||||
void error (const std::string &msg, const db::Region ®ion);
|
||||
void error (const std::string &msg, const db::Polygon &poly)
|
||||
{
|
||||
error (msg, poly.transformed (db::CplxTrans (dbu ())));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Issues an error with the given category name, description and message
|
||||
|
|
@ -426,12 +436,15 @@ protected:
|
|||
/**
|
||||
* @brief Issues an error with the given category name, description and message and error shape
|
||||
*/
|
||||
void error (const std::string &category_name, const std::string &category_description, const std::string &msg, const db::Polygon &poly);
|
||||
void error (const std::string &category_name, const std::string &category_description, const std::string &msg, const db::DPolygon &poly);
|
||||
|
||||
/**
|
||||
* @brief Issues an error with the given category name, description and message and error geometry
|
||||
* @brief Issues an error with the given category name, description and message and error shape
|
||||
*/
|
||||
void error (const std::string &category_name, const std::string &category_description, const std::string &msg, const db::Region ®ion);
|
||||
void error (const std::string &category_name, const std::string &category_description, const std::string &msg, const db::Polygon &poly)
|
||||
{
|
||||
error (category_name, category_description, msg, poly.transformed (db::CplxTrans (dbu ())));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the name of the current cell
|
||||
|
|
@ -465,4 +478,16 @@ private:
|
|||
|
||||
}
|
||||
|
||||
namespace tl
|
||||
{
|
||||
|
||||
template<> struct tl::type_traits<db::NetlistDeviceExtractor> : public tl::type_traits<void>
|
||||
{
|
||||
// mark "NetlistDeviceExtractor" as not having a default ctor and no copy ctor
|
||||
typedef tl::false_tag has_copy_constructor;
|
||||
typedef tl::false_tag has_default_constructor;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2018 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
|
||||
|
||||
*/
|
||||
|
||||
#include "gsiDecl.h"
|
||||
#include "dbHierNetworkProcessor.h"
|
||||
|
||||
namespace gsi
|
||||
{
|
||||
|
||||
Class<db::Connectivity> decl_dbConnectivity ("db", "Connectivity",
|
||||
gsi::method ("connect", (void (db::Connectivity::*) (unsigned int)) &db::Connectivity::connect, gsi::arg ("layer"),
|
||||
"@brief Specifies intra-layer connectivity.\n"
|
||||
) +
|
||||
gsi::method ("connect", (void (db::Connectivity::*) (unsigned int, unsigned int)) &db::Connectivity::connect, gsi::arg ("layer_a"), gsi::arg ("layer_b"),
|
||||
"@brief Specifies inter-layer connectivity.\n"
|
||||
),
|
||||
"@brief This class specifies connections between different layers."
|
||||
"Connections are build using \\connect. There are basically two flavours of connections: intra-layer and inter-layer.\n"
|
||||
"\n"
|
||||
"Intra-layer connections make nets begin propagated along different shapes on the same net. Without the "
|
||||
"intra-layer connections, nets are not propagated over shape boundaries. As this is usually intended, intra-layer connections "
|
||||
"should always be specified for each layer.\n"
|
||||
"\n"
|
||||
"Inter-layer connections connect shapes on different layers. Shapes which touch across layers will be connected if "
|
||||
"their layers are specified as being connected through inter-layer \\connect.\n"
|
||||
"\n"
|
||||
"All layers are specified in terms of layer indexes. Layer indexes are layout layer indexes (see \\Layout class).\n"
|
||||
"\n"
|
||||
"This class has been introduced in version 0.26.\n"
|
||||
);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,371 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2018 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
|
||||
|
||||
*/
|
||||
|
||||
#include "gsiDecl.h"
|
||||
#include "dbNetlistDeviceExtractor.h"
|
||||
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* @brief A NetlistDeviceExtractor implementation that allows reimplementation of the virtual methods
|
||||
*/
|
||||
class NetlistDeviceExtractorImpl
|
||||
: public db::NetlistDeviceExtractor
|
||||
{
|
||||
public:
|
||||
NetlistDeviceExtractorImpl ()
|
||||
: db::NetlistDeviceExtractor (std::string ())
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
using db::NetlistDeviceExtractor::set_name;
|
||||
using db::NetlistDeviceExtractor::define_layer;
|
||||
using db::NetlistDeviceExtractor::define_terminal;
|
||||
using db::NetlistDeviceExtractor::create_device;
|
||||
using db::NetlistDeviceExtractor::dbu;
|
||||
using db::NetlistDeviceExtractor::layout;
|
||||
using db::NetlistDeviceExtractor::cell_index;
|
||||
using db::NetlistDeviceExtractor::cell_name;
|
||||
using db::NetlistDeviceExtractor::error;
|
||||
using db::NetlistDeviceExtractor::get_connectivity;
|
||||
using db::NetlistDeviceExtractor::extract_devices;
|
||||
|
||||
void register_device_class (db::DeviceClass *device_class)
|
||||
{
|
||||
// the class is owned by the extractor
|
||||
device_class->keep ();
|
||||
db::NetlistDeviceExtractor::register_device_class (device_class);
|
||||
}
|
||||
|
||||
void setup_fb ()
|
||||
{
|
||||
return db::NetlistDeviceExtractor::setup ();
|
||||
}
|
||||
|
||||
virtual void setup ()
|
||||
{
|
||||
if (cb_setup.can_issue ()) {
|
||||
cb_setup.issue<NetlistDeviceExtractorImpl> (&NetlistDeviceExtractorImpl::setup_fb);
|
||||
} else {
|
||||
db::NetlistDeviceExtractor::setup ();
|
||||
}
|
||||
}
|
||||
|
||||
db::Connectivity get_connectivity_fb (const db::Layout &layout, const std::vector<unsigned int> &layers) const
|
||||
{
|
||||
return db::NetlistDeviceExtractor::get_connectivity (layout, layers);
|
||||
}
|
||||
|
||||
virtual db::Connectivity get_connectivity (const db::Layout &layout, const std::vector<unsigned int> &layers) const
|
||||
{
|
||||
if (cb_get_connectivity.can_issue ()) {
|
||||
return cb_get_connectivity.issue<const NetlistDeviceExtractorImpl, db::Connectivity, const db::Layout &, const std::vector<unsigned int> &> (&NetlistDeviceExtractorImpl::get_connectivity_fb, layout, layers);
|
||||
} else {
|
||||
return db::NetlistDeviceExtractor::get_connectivity (layout, layers);
|
||||
}
|
||||
}
|
||||
|
||||
void extract_devices_fb (const std::vector<db::Region> &layer_geometry)
|
||||
{
|
||||
return db::NetlistDeviceExtractor::extract_devices (layer_geometry);
|
||||
}
|
||||
|
||||
virtual void extract_devices (const std::vector<db::Region> &layer_geometry)
|
||||
{
|
||||
if (cb_extract_devices.can_issue ()) {
|
||||
cb_extract_devices.issue<NetlistDeviceExtractorImpl, const std::vector<db::Region> &> (&NetlistDeviceExtractorImpl::extract_devices_fb, layer_geometry);
|
||||
} else {
|
||||
db::NetlistDeviceExtractor::extract_devices (layer_geometry);
|
||||
}
|
||||
}
|
||||
|
||||
gsi::Callback cb_setup;
|
||||
gsi::Callback cb_get_connectivity;
|
||||
gsi::Callback cb_extract_devices;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace tl
|
||||
{
|
||||
|
||||
template<> struct tl::type_traits<NetlistDeviceExtractorImpl> : public tl::type_traits<void>
|
||||
{
|
||||
// mark "NetlistDeviceExtractor" as not having a default ctor and no copy ctor
|
||||
typedef tl::false_tag has_copy_constructor;
|
||||
typedef tl::false_tag has_default_constructor;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace gsi
|
||||
{
|
||||
|
||||
Class<db::NetlistDeviceExtractorError> decl_dbNetlistDeviceExtractorError ("db", "NetlistDeviceExtractorError",
|
||||
gsi::method ("message", &db::NetlistDeviceExtractorError::message,
|
||||
"@brief Gets the message text.\n"
|
||||
) +
|
||||
gsi::method ("message=", &db::NetlistDeviceExtractorError::set_message, gsi::arg ("message"),
|
||||
"@brief Sets the message text.\n"
|
||||
) +
|
||||
gsi::method ("cell_name", &db::NetlistDeviceExtractorError::cell_name,
|
||||
"@brief Gets the cell name.\n"
|
||||
"See \\cell_name= for details about this attribute."
|
||||
) +
|
||||
gsi::method ("cell_name=", &db::NetlistDeviceExtractorError::set_cell_name, gsi::arg ("cell_name"),
|
||||
"@brief Sets the cell name.\n"
|
||||
"The cell name is the name of the layout cell which was treated. This is "
|
||||
"also the name of the circuit the device should have appeared in (it may be dropped because of this error). "
|
||||
"If netlist hierarchy manipulation happens however, the circuit may not exist "
|
||||
"any longer or may be renamed."
|
||||
) +
|
||||
gsi::method ("geometry", &db::NetlistDeviceExtractorError::geometry,
|
||||
"@brief Gets the geometry.\n"
|
||||
"See \\geometry= for more details."
|
||||
) +
|
||||
gsi::method ("geometry=", &db::NetlistDeviceExtractorError::set_geometry, gsi::arg ("polygon"),
|
||||
"@brief Sets the geometry.\n"
|
||||
"The geometry is optional. If given, a marker will be shown when selecting this error."
|
||||
) +
|
||||
gsi::method ("category_name", &db::NetlistDeviceExtractorError::category_name,
|
||||
"@brief Gets the category name.\n"
|
||||
"See \\category_name= for more details."
|
||||
) +
|
||||
gsi::method ("category_name=", &db::NetlistDeviceExtractorError::set_category_name, gsi::arg ("name"),
|
||||
"@brief Sets the category name.\n"
|
||||
"The category name is optional. If given, it specifies a formal category name. Errors with the same "
|
||||
"category name are shown in that category. If in addition a category description is specified "
|
||||
"(see \\category_description), this description will be displayed as the title of."
|
||||
) +
|
||||
gsi::method ("category_description", &db::NetlistDeviceExtractorError::category_description,
|
||||
"@brief Gets the category description.\n"
|
||||
"See \\category_name= for details about categories."
|
||||
) +
|
||||
gsi::method ("category_description=", &db::NetlistDeviceExtractorError::set_category_description, gsi::arg ("description"),
|
||||
"@brief Sets the category description.\n"
|
||||
"See \\category_name= for details about categories."
|
||||
),
|
||||
"@brief An error that occured during device extraction\n"
|
||||
"The device extractor will keep errors that occured during extraction of the devices. "
|
||||
"It does not by using this error class.\n"
|
||||
"\n"
|
||||
"An error is basically described by the cell/circuit it occures in and the message. "
|
||||
"In addition, a geometry may be attached forming a marker that can be shown when the error is selected. "
|
||||
"The geometry is given as a \\DPolygon object. If no geometry is specified, this polygon is empty.\n"
|
||||
"\n"
|
||||
"For categorization of the errors, a category name and description may be specified. If given, the "
|
||||
"errors will be shown in the specified category. The category description is optional.\n"
|
||||
"\n"
|
||||
"This class has been introduced in version 0.26."
|
||||
);
|
||||
|
||||
static const std::string &ld_name (const db::NetlistDeviceExtractorLayerDefinition *ld)
|
||||
{
|
||||
return ld->name;
|
||||
}
|
||||
|
||||
static const std::string &ld_description (const db::NetlistDeviceExtractorLayerDefinition *ld)
|
||||
{
|
||||
return ld->description;
|
||||
}
|
||||
|
||||
static int ld_index (const db::NetlistDeviceExtractorLayerDefinition *ld)
|
||||
{
|
||||
return ld->index;
|
||||
}
|
||||
|
||||
Class<db::NetlistDeviceExtractorLayerDefinition> decl_dbNetlistDeviceExtractorLayerDefinition ("db", "NetlistDeviceExtractorLayerDefinition",
|
||||
gsi::method_ext ("name", &ld_name,
|
||||
"@brief Gets the name of the layer.\n"
|
||||
) +
|
||||
gsi::method_ext ("description", &ld_description,
|
||||
"@brief Gets the description of the layer.\n"
|
||||
) +
|
||||
gsi::method_ext ("index", &ld_index,
|
||||
"@brief Gets the index of the layer.\n"
|
||||
),
|
||||
"@brief Describes a layer used in the device extraction\n"
|
||||
"This read-only structure is used to describe a layer in the device extraction.\n"
|
||||
"Every device has specific layers used in the device extraction process.\n"
|
||||
"Layer definitions can be retrieved using \\NetlistDeviceExtractor#each_layer.\n"
|
||||
"\n"
|
||||
"This class has been introduced in version 0.26."
|
||||
);
|
||||
|
||||
Class<NetlistDeviceExtractorImpl> decl_dbNetlistDeviceExtractor ("db", "NetlistDeviceExtractorImpl",
|
||||
gsi::method ("name", &NetlistDeviceExtractorImpl::name,
|
||||
"@brief Gets the name of the device extractor and the device class."
|
||||
) +
|
||||
gsi::method ("name=", &NetlistDeviceExtractorImpl::set_name,
|
||||
"@brief Sets the name of the device extractor and the device class."
|
||||
) +
|
||||
gsi::iterator ("each_layer_definition", &NetlistDeviceExtractorImpl::begin_layer_definitions, &NetlistDeviceExtractorImpl::end_layer_definitions,
|
||||
"@brief Iterates over all layer definitions."
|
||||
) +
|
||||
gsi::callback ("setup", &NetlistDeviceExtractorImpl::setup, &NetlistDeviceExtractorImpl::cb_setup,
|
||||
"@brief Sets up the extractor.\n"
|
||||
"This method is supposed to set up the device extractor. This involves three basic steps:\n"
|
||||
"defining the name, the device classe and setting up the device layers.\n"
|
||||
"\n"
|
||||
"Use \\name= to give the extractor and it's device class a name.\n"
|
||||
"Use \\register_device_class to register the device class you need.\n"
|
||||
"Defined the layers by calling \\define_layer once or several times.\n"
|
||||
) +
|
||||
gsi::callback ("get_connectivity", &NetlistDeviceExtractorImpl::get_connectivity, &NetlistDeviceExtractorImpl::cb_get_connectivity,
|
||||
gsi::arg ("layout"), gsi::arg ("layers"),
|
||||
"@brief Gets the connectivity object used to extract the device geometry.\n"
|
||||
"This method shall raise an error, if the input layer are not properly defined (e.g.\n"
|
||||
"too few etc.)\n"
|
||||
"\n"
|
||||
"The 'layers' argument specifies the actual layer layouts for the logical device layers (see \\define_layer). "
|
||||
"The list of layers corresponds to the number of layers defined. Use the layer indexes from this list "
|
||||
"to build the connectivity with \\Connectivity#connect."
|
||||
) +
|
||||
gsi::callback ("extract_devices", &NetlistDeviceExtractorImpl::extract_devices, &NetlistDeviceExtractorImpl::cb_extract_devices,
|
||||
gsi::arg ("layer_geometry"),
|
||||
"@brief Extracts the devices from the given shape cluster.\n"
|
||||
"\n"
|
||||
"The shape cluster is a set of geometries belonging together in terms of the\n"
|
||||
"connectivity defined by \"get_connectivity\". The cluster might cover multiple devices,\n"
|
||||
"so the implementation needs to consider this case. The geometries are already merged.\n"
|
||||
"\n"
|
||||
"The implementation of this method shall use \"create_device\" to create new\n"
|
||||
"devices based on the geometry found. It shall use \"define_terminal\" to define\n"
|
||||
"terminals by which the nets extracted in the network extraction step connect\n"
|
||||
"to the new devices.\n"
|
||||
) +
|
||||
gsi::method ("register_device_class", &NetlistDeviceExtractorImpl::register_device_class, gsi::arg ("device_class"),
|
||||
"@brief Registers a device class.\n"
|
||||
"The device class object will become owned by the netlist and must not be deleted by\n"
|
||||
"the caller. The name of the device class will be changed to the name given to\n"
|
||||
"the device extractor.\n"
|
||||
"This method shall be used inside the implementation of \\setup to register\n"
|
||||
"the device classes.\n"
|
||||
) +
|
||||
gsi::method ("define_layer", &NetlistDeviceExtractorImpl::define_layer, gsi::arg ("name"), gsi::arg ("description"),
|
||||
"@brief Defines a layer.\n"
|
||||
"Each call will define one more layer for the device extraction.\n"
|
||||
"This method shall be used inside the implementation of \\setup to define\n"
|
||||
"the device layers. The actual geometries are later available to \\extract_devices\n"
|
||||
"in the order the layers are defined.\n"
|
||||
) +
|
||||
gsi::method ("create_device", &NetlistDeviceExtractorImpl::create_device,
|
||||
"@brief Creates a device.\n"
|
||||
"The device object returned can be configured by the caller, e.g. set parameters.\n"
|
||||
"It will be owned by the netlist and must not be deleted by the caller.\n"
|
||||
) +
|
||||
gsi::method ("define_terminal", (void (NetlistDeviceExtractorImpl::*) (db::Device *, size_t, size_t, const db::Polygon &)) &NetlistDeviceExtractorImpl::define_terminal,
|
||||
gsi::arg ("device"), gsi::arg ("terminal_id"), gsi::arg ("layer_index"), gsi::arg ("shape"),
|
||||
"@brief Defines a device terminal.\n"
|
||||
"This method will define a terminal to the given device and the given terminal ID. \n"
|
||||
"The terminal will be placed on the layer given by \"layer_index\". The layer index \n"
|
||||
"is the index of the layer during layer definition. The first layer is 0, the second layer 1 etc.\n"
|
||||
"\n"
|
||||
"This version produces a terminal with a shape given by the polygon. Note that the polygon is\n"
|
||||
"specified in database units.\n"
|
||||
) +
|
||||
gsi::method ("define_terminal", (void (NetlistDeviceExtractorImpl::*) (db::Device *, size_t, size_t, const db::Box &)) &NetlistDeviceExtractorImpl::define_terminal,
|
||||
gsi::arg ("device"), gsi::arg ("terminal_id"), gsi::arg ("layer_index"), gsi::arg ("shape"),
|
||||
"@brief Defines a device terminal.\n"
|
||||
"This method will define a terminal to the given device and the given terminal ID. \n"
|
||||
"The terminal will be placed on the layer given by \"layer_index\". The layer index \n"
|
||||
"is the index of the layer during layer definition. The first layer is 0, the second layer 1 etc.\n"
|
||||
"\n"
|
||||
"This version produces a terminal with a shape given by the box. Note that the box is\n"
|
||||
"specified in database units.\n"
|
||||
) +
|
||||
gsi::method ("define_terminal", (void (NetlistDeviceExtractorImpl::*) (db::Device *, size_t, size_t, const db::Point &)) &NetlistDeviceExtractorImpl::define_terminal,
|
||||
gsi::arg ("device"), gsi::arg ("terminal_id"), gsi::arg ("layer_index"), gsi::arg ("point"),
|
||||
"@brief Defines a device terminal.\n"
|
||||
"This method will define a terminal to the given device and the given terminal ID. \n"
|
||||
"The terminal will be placed on the layer given by \"layer_index\". The layer index \n"
|
||||
"is the index of the layer during layer definition. The first layer is 0, the second layer 1 etc.\n"
|
||||
"\n"
|
||||
"This version produces a point-like terminal. Note that the point is\n"
|
||||
"specified in database units.\n"
|
||||
) +
|
||||
gsi::method ("dbu", &NetlistDeviceExtractorImpl::dbu,
|
||||
"@brief Gets the database unit\n"
|
||||
) +
|
||||
gsi::method ("error", (void (NetlistDeviceExtractorImpl::*) (const std::string &)) &NetlistDeviceExtractorImpl::error,
|
||||
gsi::arg ("message"),
|
||||
"@brief Issues an error with the given message\n"
|
||||
) +
|
||||
gsi::method ("error", (void (NetlistDeviceExtractorImpl::*) (const std::string &, const db::DPolygon &)) &NetlistDeviceExtractorImpl::error,
|
||||
gsi::arg ("message"), gsi::arg ("geometry"),
|
||||
"@brief Issues an error with the given message and micrometer-units polygon geometry\n"
|
||||
) +
|
||||
gsi::method ("error", (void (NetlistDeviceExtractorImpl::*) (const std::string &, const db::Polygon &)) &NetlistDeviceExtractorImpl::error,
|
||||
gsi::arg ("message"), gsi::arg ("geometry"),
|
||||
"@brief Issues an error with the given message and databse-unit polygon geometry\n"
|
||||
) +
|
||||
gsi::method ("error", (void (NetlistDeviceExtractorImpl::*) (const std::string &, const std::string &, const std::string &)) &NetlistDeviceExtractorImpl::error,
|
||||
gsi::arg ("category_name"), gsi::arg ("category_description"), gsi::arg ("message"),
|
||||
"@brief Issues an error with the given category name and description, message\n"
|
||||
) +
|
||||
gsi::method ("error", (void (NetlistDeviceExtractorImpl::*) (const std::string &, const std::string &, const std::string &, const db::DPolygon &)) &NetlistDeviceExtractorImpl::error,
|
||||
gsi::arg ("category_name"), gsi::arg ("category_description"), gsi::arg ("message"), gsi::arg ("geometry"),
|
||||
"@brief Issues an error with the given category name and description, message and micrometer-units polygon geometry\n"
|
||||
) +
|
||||
gsi::method ("error", (void (NetlistDeviceExtractorImpl::*) (const std::string &, const std::string &, const std::string &, const db::Polygon &)) &NetlistDeviceExtractorImpl::error,
|
||||
gsi::arg ("category_name"), gsi::arg ("category_description"), gsi::arg ("message"), gsi::arg ("geometry"),
|
||||
"@brief Issues an error with the given category name and description, message and databse-unit polygon geometry\n"
|
||||
),
|
||||
"@brief The basic class for implementing custom device extractors.\n"
|
||||
"\n"
|
||||
"This class serves as a base class for implementing customized device extractors. "
|
||||
"This class does not provide any extraction functionality, so you have to "
|
||||
"implement every detail.\n"
|
||||
"\n"
|
||||
"Device extraction requires a few definitions. The definitions are made in the reimplementation of the \\setup\n"
|
||||
"method. Required definitions to be made are:\n"
|
||||
"\n"
|
||||
"@ul\n"
|
||||
" @li The name of the extractor. This will also be the name of the device class produced by the extractor. "
|
||||
" The name is set using \\name=. @/li\n"
|
||||
" @li The device class of the devices to produce. The device class is registered using \\register_device_class. @/li\n"
|
||||
" @li The layers used for the device extraction. These are input layers for the extraction as well as "
|
||||
" output layers for defining the terminals. Terminals are the poins at which the nets connect to the devices.\n"
|
||||
" Layers are defined using \\define_layer. Initially, layers are abstract definitions with a name and a description.\n"
|
||||
" Concrete layers will be given when defining the connectivitiy. @/li\n"
|
||||
"@/ul\n"
|
||||
"\n"
|
||||
"When the device extraction is started, the device extraction algorithm will first ask the device extractor "
|
||||
"for the 'connectivity'. This is not a connectivity in a sense of electrical connections. The connectivity defines are "
|
||||
"logical compound that makes up the device. 'Connected' shapes are collected and presented to the device extractor.\n"
|
||||
"The connectivity is obtained by calling \\get_connectivity. This method must be "
|
||||
"implemented to produce the connectivity.\n"
|
||||
"\n"
|
||||
"Finally, the individual devices need to be extracted. Each cluster of connected shapes is presented to the "
|
||||
"device extractor. A cluster may include more than one device. It's the device extractor's responsibilty to "
|
||||
"extract the devices from this cluster and deliver the devices through \\create_device. In addition, terminals "
|
||||
"have to be defined, so the net extractor can connect to the devices. Terminal definitions are made through "
|
||||
"\\define_terminal. The device extraction is implemented in the \\extract_devices method.\n"
|
||||
"\n"
|
||||
"If errors occur during device extraction, the \\error method may be used to issue such errors. Errors "
|
||||
"reported this way are kept in the error log.\n"
|
||||
"\n"
|
||||
"This class has been introduced in version 0.26."
|
||||
);
|
||||
|
||||
}
|
||||
|
|
@ -37,7 +37,7 @@ TEST(1_NetlistDeviceExtractorErrorBasic)
|
|||
EXPECT_EQ (error.category_description (), "cdesc");
|
||||
error.set_cell_name ("cell");
|
||||
EXPECT_EQ (error.cell_name (), "cell");
|
||||
error.set_geometry (db::Region (db::Box (0, 1, 2, 3)));
|
||||
error.set_geometry (db::DPolygon (db::DBox (0, 1, 2, 3)));
|
||||
EXPECT_EQ (error.geometry ().to_string (), "(0,1;0,3;2,3;2,1)");
|
||||
|
||||
error = db::NetlistDeviceExtractorError ("cell2", "msg2");
|
||||
|
|
@ -45,7 +45,7 @@ TEST(1_NetlistDeviceExtractorErrorBasic)
|
|||
EXPECT_EQ (error.message (), "msg2");
|
||||
EXPECT_EQ (error.category_name (), "");
|
||||
EXPECT_EQ (error.category_description (), "");
|
||||
EXPECT_EQ (error.geometry ().to_string (), "");
|
||||
EXPECT_EQ (error.geometry ().to_string (), "()");
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
@ -57,11 +57,9 @@ namespace {
|
|||
: db::NetlistDeviceExtractor (std::string ("DUMMY"))
|
||||
{
|
||||
error ("msg1");
|
||||
error ("msg2", db::Box (0, 1, 2, 3));
|
||||
error ("msg3", db::Region (db::Box (10, 11, 12, 13)));
|
||||
error ("msg2", db::DPolygon (db::DBox (0, 1, 2, 3)));
|
||||
error ("cat1", "desc1", "msg1");
|
||||
error ("cat1", "desc1", "msg2", db::Box (0, 1, 2, 3));
|
||||
error ("cat1", "desc1", "msg3", db::Region (db::Box (10, 11, 12, 13)));
|
||||
error ("cat1", "desc1", "msg3", db::DPolygon (db::DBox (10, 11, 12, 13)));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -79,11 +77,9 @@ TEST(2_NetlistDeviceExtractorErrors)
|
|||
EXPECT_EQ (dummy_ex.has_errors (), true);
|
||||
|
||||
std::vector<db::NetlistDeviceExtractorError> errors (dummy_ex.begin_errors (), dummy_ex.end_errors ());
|
||||
EXPECT_EQ (int (errors.size ()), 6);
|
||||
EXPECT_EQ (error2string (errors [0]), "::::msg1");
|
||||
EXPECT_EQ (int (errors.size ()), 4);
|
||||
EXPECT_EQ (error2string (errors [0]), ":::():msg1");
|
||||
EXPECT_EQ (error2string (errors [1]), ":::(0,1;0,3;2,3;2,1):msg2");
|
||||
EXPECT_EQ (error2string (errors [2]), ":::(10,11;10,13;12,13;12,11):msg3");
|
||||
EXPECT_EQ (error2string (errors [3]), ":cat1:desc1::msg1");
|
||||
EXPECT_EQ (error2string (errors [4]), ":cat1:desc1:(0,1;0,3;2,3;2,1):msg2");
|
||||
EXPECT_EQ (error2string (errors [5]), ":cat1:desc1:(10,11;10,13;12,13;12,11):msg3");
|
||||
EXPECT_EQ (error2string (errors [2]), ":cat1:desc1:():msg1");
|
||||
EXPECT_EQ (error2string (errors [3]), ":cat1:desc1:(10,11;10,13;12,13;12,11):msg3");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue