mirror of https://github.com/KLayout/klayout.git
More control over primary/secondary flag of parameters in device extraction
- Spice reader will set primary flag for all (known) parameters read from a Spice netlist - "extract_devices" will return the device class object - primary/secondary flag can be set on device class objects through "enable_devices"
This commit is contained in:
parent
1a0b05e663
commit
ce61145f1c
|
|
@ -179,6 +179,15 @@ const DeviceParameterDefinition *DeviceClass::parameter_definition (size_t id) c
|
|||
}
|
||||
}
|
||||
|
||||
DeviceParameterDefinition *DeviceClass::parameter_definition_non_const (size_t id)
|
||||
{
|
||||
if (id < m_parameter_definitions.size ()) {
|
||||
return & m_parameter_definitions [id];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool DeviceClass::has_parameter_with_name (const std::string &name) const
|
||||
{
|
||||
const std::vector<db::DeviceParameterDefinition> &pd = parameter_definitions ();
|
||||
|
|
|
|||
|
|
@ -508,6 +508,11 @@ public:
|
|||
*/
|
||||
const DeviceParameterDefinition *parameter_definition (size_t id) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the parameter definition from the ID (non-const version)
|
||||
*/
|
||||
DeviceParameterDefinition *parameter_definition_non_const (size_t id);
|
||||
|
||||
/**
|
||||
* @brief Returns true, if the device has a parameter with the given name
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -391,7 +391,7 @@ void NetlistDeviceExtractor::push_new_devices (const db::Vector &disp_cache)
|
|||
std::string cell_name = "D$" + mp_device_class->name ();
|
||||
db::Cell &device_cell = mp_layout->cell (mp_layout->add_cell (cell_name.c_str ()));
|
||||
|
||||
db::DeviceAbstract *dm = new db::DeviceAbstract (mp_device_class, mp_layout->cell_name (device_cell.cell_index ()));
|
||||
db::DeviceAbstract *dm = new db::DeviceAbstract (mp_device_class.get (), mp_layout->cell_name (device_cell.cell_index ()));
|
||||
m_netlist->add_device_abstract (dm);
|
||||
dm->set_cell_index (device_cell.cell_index ());
|
||||
|
||||
|
|
@ -487,7 +487,7 @@ void NetlistDeviceExtractor::register_device_class (DeviceClass *device_class)
|
|||
tl_assert (device_class != 0);
|
||||
tl_assert (m_netlist.get () != 0);
|
||||
|
||||
if (mp_device_class != 0) {
|
||||
if (mp_device_class.get () != 0) {
|
||||
throw tl::Exception (tl::to_string (tr ("Device class already set")));
|
||||
}
|
||||
if (m_name.empty ()) {
|
||||
|
|
@ -526,12 +526,12 @@ const db::NetlistDeviceExtractorLayerDefinition &NetlistDeviceExtractor::define_
|
|||
|
||||
Device *NetlistDeviceExtractor::create_device ()
|
||||
{
|
||||
if (mp_device_class == 0) {
|
||||
if (mp_device_class.get () == 0) {
|
||||
throw tl::Exception (tl::to_string (tr ("No device class registered")));
|
||||
}
|
||||
|
||||
tl_assert (mp_circuit != 0);
|
||||
Device *device = new Device (mp_device_class);
|
||||
Device *device = new Device (mp_device_class.get ());
|
||||
mp_circuit->add_device (device);
|
||||
return device;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -387,6 +387,16 @@ public:
|
|||
*/
|
||||
Device *create_device ();
|
||||
|
||||
/**
|
||||
* @brief Gets the device class used during extraction
|
||||
*
|
||||
* This member is set in 'extract_devices' and holds the device class object used during extraction.
|
||||
*/
|
||||
DeviceClass *device_class ()
|
||||
{
|
||||
return mp_device_class.get ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Defines a device terminal in the layout (a region)
|
||||
*/
|
||||
|
|
@ -535,7 +545,7 @@ private:
|
|||
const std::set<db::cell_index_type> *mp_breakout_cells;
|
||||
double m_device_scaling;
|
||||
db::Circuit *mp_circuit;
|
||||
db::DeviceClass *mp_device_class;
|
||||
tl::weak_ptr<db::DeviceClass> mp_device_class;
|
||||
std::string m_name;
|
||||
layer_definitions m_layer_definitions;
|
||||
std::vector<unsigned int> m_layers;
|
||||
|
|
|
|||
|
|
@ -625,6 +625,8 @@ bool NetlistSpiceReaderDelegate::element (db::Circuit *circuit, const std::strin
|
|||
std::map<std::string, double>::const_iterator v = params.find (i->name ());
|
||||
if (v != params.end ()) {
|
||||
device->set_parameter_value (i->id (), v->second / i->si_scaling ());
|
||||
// parameters read from the netlist are made primary so they are shown in the netlist browser
|
||||
cls->parameter_definition_non_const (i->id ())->set_is_primary (true);
|
||||
} else if (i->id () == defp) {
|
||||
device->set_parameter_value (i->id (), value / i->si_scaling ());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -927,6 +927,36 @@ static db::EqualDeviceParameters *get_equal_parameters (db::DeviceClass *cls)
|
|||
return dynamic_cast<db::EqualDeviceParameters *> (cls->parameter_compare_delegate ());
|
||||
}
|
||||
|
||||
static void enable_parameter (db::DeviceClass *cls, size_t id, bool en)
|
||||
{
|
||||
db::DeviceParameterDefinition *pd = cls->parameter_definition_non_const (id);
|
||||
if (pd) {
|
||||
pd->set_is_primary (en);
|
||||
}
|
||||
}
|
||||
|
||||
static void enable_parameter2 (db::DeviceClass *cls, const std::string &name, bool en)
|
||||
{
|
||||
if (! cls->has_parameter_with_name (name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t id = cls->parameter_id_for_name (name);
|
||||
db::DeviceParameterDefinition *pd = cls->parameter_definition_non_const (id);
|
||||
if (pd) {
|
||||
pd->set_is_primary (en);
|
||||
}
|
||||
}
|
||||
|
||||
static const db::DeviceParameterDefinition *parameter_definition2 (const db::DeviceClass *cls, const std::string &name)
|
||||
{
|
||||
if (! cls->has_parameter_with_name (name)) {
|
||||
return 0;
|
||||
} else {
|
||||
return cls->parameter_definition (cls->parameter_id_for_name (name));
|
||||
}
|
||||
}
|
||||
|
||||
Class<db::DeviceClass> decl_dbDeviceClass ("db", "DeviceClass",
|
||||
gsi::method ("name", &db::DeviceClass::name,
|
||||
"@brief Gets the name of the device class."
|
||||
|
|
@ -981,6 +1011,33 @@ Class<db::DeviceClass> decl_dbDeviceClass ("db", "DeviceClass",
|
|||
"Parameter definition IDs are used in some places to reference a specific parameter of a device. "
|
||||
"This method obtains the corresponding definition object."
|
||||
) +
|
||||
gsi::method_ext ("parameter_definition", ¶meter_definition2, gsi::arg ("parameter_name"),
|
||||
"@brief Gets the parameter definition object for a given ID.\n"
|
||||
"Parameter definition IDs are used in some places to reference a specific parameter of a device. "
|
||||
"This method obtains the corresponding definition object."
|
||||
"\n"
|
||||
"This version accepts a parameter name.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.27.3.\n"
|
||||
) +
|
||||
gsi::method_ext ("enable_parameter", &enable_parameter, gsi::arg ("parameter_id"), gsi::arg ("enable"),
|
||||
"@brief Enables or disables a parameter.\n"
|
||||
"Some parameters are 'secondary' parameters which are extracted but not handled in device compare and are not shown in the netlist browser. "
|
||||
"For example, the 'W' parameter of the resistor is such a secondary parameter. This method allows turning a parameter in a primary one ('enable') or "
|
||||
"into a secondary one ('disable').\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.27.3.\n"
|
||||
) +
|
||||
gsi::method_ext ("enable_parameter", &enable_parameter2, gsi::arg ("parameter_name"), gsi::arg ("enable"),
|
||||
"@brief Enables or disables a parameter.\n"
|
||||
"Some parameters are 'secondary' parameters which are extracted but not handled in device compare and are not shown in the netlist browser. "
|
||||
"For example, the 'W' parameter of the resistor is such a secondary parameter. This method allows turning a parameter in a primary one ('enable') or "
|
||||
"into a secondary one ('disable').\n"
|
||||
"\n"
|
||||
"This version accepts a parameter name.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.27.3.\n"
|
||||
) +
|
||||
gsi::method ("has_parameter?", &db::DeviceClass::has_parameter_with_name, gsi::arg ("name"),
|
||||
"@brief Returns true, if the device class has a parameter with the given name.\n"
|
||||
) +
|
||||
|
|
|
|||
|
|
@ -214,6 +214,13 @@ Class<db::NetlistDeviceExtractor> decl_dbNetlistDeviceExtractor ("db", "DeviceEx
|
|||
gsi::method ("name", &db::NetlistDeviceExtractor::name,
|
||||
"@brief Gets the name of the device extractor and the device class."
|
||||
) +
|
||||
gsi::method ("device_class", &db::NetlistDeviceExtractor::device_class,
|
||||
"@brief Gets the device class used during extraction\n"
|
||||
"The attribute will hold the actual device class used in the device extraction. It "
|
||||
"is valid only after 'extract_devices'.\n"
|
||||
"\n"
|
||||
"This method has been added in version 0.27.3.\n"
|
||||
) +
|
||||
gsi::iterator ("each_layer_definition", &db::NetlistDeviceExtractor::begin_layer_definitions, &db::NetlistDeviceExtractor::end_layer_definitions,
|
||||
"@brief Iterates over all layer definitions."
|
||||
) +
|
||||
|
|
@ -251,9 +258,13 @@ Class<GenericDeviceExtractor> decl_GenericDeviceExtractor (decl_dbNetlistDeviceE
|
|||
"This method shall raise an error, if the input layer are not properly defined (e.g.\n"
|
||||
"too few etc.)\n"
|
||||
"\n"
|
||||
"This is not a connectivity definition in the electrical sense, but defines the cluster of shapes "
|
||||
"which generates a specific device. In this case, 'connectivity' means 'definition of shapes that need to touch to form the device'.\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."
|
||||
"to build the connectivity with \\Connectivity#connect. Note, that in order to capture a connected cluster of shapes on the "
|
||||
"same layer you'll need to include a self-connection like 'connectivity.connect(layers[0], layers[0])'."
|
||||
) +
|
||||
gsi::callback ("extract_devices", &GenericDeviceExtractor::extract_devices, &GenericDeviceExtractor::cb_extract_devices,
|
||||
gsi::arg ("layer_geometry"),
|
||||
|
|
|
|||
|
|
@ -192,6 +192,9 @@ module DRC
|
|||
#
|
||||
# extract_devices(mos4("NMOS4"), { :SD => nsd, :G => gate, :P => poly, :W => bulk })
|
||||
# @/code
|
||||
#
|
||||
# The return value of this method will be the device class of the devices
|
||||
# generated in the extraction step (see \DeviceClass).
|
||||
|
||||
def extract_devices(devex, layer_selection)
|
||||
|
||||
|
|
@ -215,6 +218,8 @@ module DRC
|
|||
|
||||
end
|
||||
|
||||
devex.device_class
|
||||
|
||||
end
|
||||
|
||||
# %DRC%
|
||||
|
|
|
|||
Loading…
Reference in New Issue