WIP: GSI binding for LayoutVsSchematic and NetlistCrossReference.

This commit is contained in:
Matthias Koefferlein 2019-05-25 22:33:35 +02:00
parent 01f7939918
commit 09fe41294b
3 changed files with 631 additions and 1 deletions

View File

@ -181,7 +181,9 @@ SOURCES = \
dbLayoutVsSchematicWriter.cc \
dbLayoutVsSchematicReader.cc \
dbLayoutVsSchematicFormatDefs.cc \
dbLayoutVsSchematic.cc
dbLayoutVsSchematic.cc \
gsiDeclDbNetlistCrossReference.cc \
gsiDeclDbLayoutVsSchematic.cc
HEADERS = \
dbArray.h \

View File

@ -0,0 +1,155 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2019 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 "dbLayoutVsSchematic.h"
#include "tlStream.h"
#include "tlVariant.h"
namespace gsi
{
extern Class<db::LayoutToNetlist> decl_dbLayoutToNetlist;
static db::LayoutVsSchematic *make_lvs (const db::RecursiveShapeIterator &iter)
{
return new db::LayoutVsSchematic (iter);
}
static db::LayoutVsSchematic *make_lvs_default ()
{
return new db::LayoutVsSchematic ();
}
static db::LayoutVsSchematic *make_lvs_from_existing_dss_with_layout (db::DeepShapeStore *dss, unsigned int layout_index)
{
return new db::LayoutVsSchematic (dss, layout_index);
}
static db::LayoutVsSchematic *make_lvs_from_existing_dss (db::DeepShapeStore *dss)
{
return new db::LayoutVsSchematic (dss);
}
static db::LayoutVsSchematic *make_lvs_flat (const std::string &topcell_name, double dbu)
{
return new db::LayoutVsSchematic (topcell_name, dbu);
}
static db::LayoutToNetlist *l2n_from_lvs (db::LayoutVsSchematic *lvs)
{
return lvs;
}
Class<db::LayoutVsSchematic> decl_dbLayoutVsSchematic ("db", "LayoutVsSchematic",
gsi::constructor ("new", &make_lvs, gsi::arg ("iter"),
"@brief Creates a new LVS object with the extractor connected to an original layout\n"
"This constructor will attach the extractor of the LVS object to an original layout through the "
"shape iterator.\n"
) +
gsi::constructor ("new", &make_lvs_default,
"@brief Creates a new LVS object\n"
"The main objective for this constructor is to create an object suitable for reading and writing LVS database files.\n"
) +
gsi::constructor ("new", &make_lvs_from_existing_dss, gsi::arg ("dss"),
"@brief Creates a new LVS object with the extractor object reusing an existing \\DeepShapeStore object\n"
"See the corresponding constructor of the \\LayoutToNetlist object for more details."
) +
gsi::constructor ("new", &make_lvs_from_existing_dss_with_layout, gsi::arg ("dss"), gsi::arg ("layout_index"),
"@brief Creates a new LVS object with the extractor object reusing an existing \\DeepShapeStore object\n"
"See the corresponding constructor of the \\LayoutToNetlist object for more details."
) +
gsi::constructor ("new", &make_lvs_flat, gsi::arg ("topcell_name"), gsi::arg ("dbu"),
"@brief Creates a new LVS object with the extractor object taking a flat DSS\n"
"See the corresponding constructor of the \\LayoutToNetlist object for more details."
) +
gsi::method ("reference=", &db::LayoutVsSchematic::set_reference_netlist, gsi::arg ("reference_netlist"),
"@brief Sets the reference netlist.\n"
"This will set the reference netlist used inside \\compare as the second netlist to compare against "
"the layout-extracted netlist.\n"
"\n"
"The LVS object will take ownership over the netlist - i.e. if it goes out of scope, the "
"reference netlist is deleted.\n"
) +
gsi::method ("reference", (db::Netlist *(db::LayoutVsSchematic::*) ()) &db::LayoutVsSchematic::reference_netlist,
"@brief Gets the reference netlist.\n"
) +
gsi::method ("compare", &db::LayoutVsSchematic::compare_netlists, gsi::arg ("comparer"),
"@brief Compare the layout-extracted netlist against the reference netlist using the given netlist comparer.\n"
) +
gsi::method ("xref", (db::NetlistCrossReference *(db::LayoutVsSchematic::*) ()) &db::LayoutVsSchematic::cross_ref,
"@brief Gets the cross-reference object\n"
"The cross-reference object is created while comparing the layout-extracted netlist against the "
"reference netlist - i.e. during \\compare. Before \\compare is called, this object is nil.\n"
"It holds the results of the comparison - a cross-reference between the nets and other objects "
"in the match case and a listing of non-matching nets and other objects for the non-matching cases."
"\n"
"See \\NetlistCrossReference for more details.\n"
) +
gsi::method_ext ("l2n", &l2n_from_lvs,
"@brief Gets the \\LayoutToNetlist interface of this object.\n"
"This method renders the \\LayoutToNetlist part of self. It is useful to access \\read and \\write from this "
"object instead of the \\LayoutVsSchematic interface:\n"
"\n"
"@code\n"
"lvs = ... # an LVS object\n"
"# writes the LayoutToNetlist data:\n"
"lvs.l2n.write(\"data.l2n\")\n"
"# writes the LayoutVsSchematic data:\n"
"lvs.lvs.write(\"data.l2n\")\n"
"@/code\n"
) +
gsi::method ("write", &db::LayoutVsSchematic::save, gsi::arg ("path"), gsi::arg ("short_format", false),
"@brief Writes the LVS object to a file.\n"
"This method employs the native format of KLayout.\n"
) +
gsi::method ("read", &db::LayoutVsSchematic::load, gsi::arg ("path"),
"@brief Reads the LVS object from the file.\n"
"This method employs the native format of KLayout.\n"
),
"@brief A generic framework for doing LVS (layout vs. schematic)\n"
"\n"
"This class extends the concept of the netlist extraction from a layout to LVS verification. "
"It does so by adding these concepts to the \\LayoutToNetlist class:\n"
"\n"
"@ul\n"
"@li A reference netlist. This will be the netlist against which the layout-derived netlist is "
"compared against. See \\reference and \\reference=.\n"
"@/li\n"
"@li A compare step. During the compare the layout-derived netlist and the reference netlists "
"are compared. The compare results are captured in the cross-reference object. "
"See \\compare and \\NetlistCompare for the comparer object.\n"
"@/li\n"
"@li A cross-reference. This object (of class \\NetlistCrossReference) will keep the relations "
"between the objects of the two netlists. It also lists the differences between the netlists. "
"See \\xref about how to access this object."
"@/li\n"
"\n"
"The LVS object can be persisted to and from a file in a specific format, so it is sometimes "
"referred to as the \"LVS database\".\n"
"\n"
"LVS objects can be attached to layout views with \\LayoutView#add_lvsdb.\n"
"\n"
"This class has been introduced in version 0.26."
);
}

View File

@ -0,0 +1,473 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2019 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 "gsiEnums.h"
#include "dbNetlistCrossReference.h"
namespace gsi
{
namespace
{
struct CircuitPairData
{
typedef db::Circuit object_type;
CircuitPairData (const db::Circuit *a, const db::Circuit *b, db::NetlistCrossReference::Status s) : pair (a, b), status (s) { }
CircuitPairData () : pair (0, 0), status (db::NetlistCrossReference::None) { }
std::pair<const db::Circuit *, const db::Circuit *> pair;
db::NetlistCrossReference::Status status;
};
template <class PairData>
static const typename PairData::object_type *first (const PairData *data)
{
return data->pair.first;
}
template <class PairData>
static const typename PairData::object_type *second (const PairData *data)
{
return data->pair.second;
}
template <class PairData>
static db::NetlistCrossReference::Status status (const PairData *data)
{
return data->status;
}
template <class PairData>
class PairDataClass
: public ChildClass<db::NetlistCrossReference, PairData>
{
public:
PairDataClass (const std::string &module, const std::string &name, const std::string &doc)
: gsi::ChildClass<db::NetlistCrossReference, PairData> (module, name,
gsi::method_ext ("first", &first<PairData>,
"@brief Gets the first object of the relation pair.\n"
"The first object is usually the one obtained from the layout-derived netlist. "
"This member can be nil if the pair is describing a non-matching reference object. "
"In this case, the \\second member is the reference object for which no match was found."
) +
gsi::method_ext ("second", &second<PairData>,
"@brief Gets the second object of the relation pair.\n"
"The first object is usually the one obtained from the reference netlist. "
"This member can be nil if the pair is describing a non-matching layout object. "
"In this case, the \\first member is the layout-derived object for which no match was found."
) +
gsi::method_ext ("status", &status<PairData>,
"@brief Gets the status of the relation.\n"
"This enum described the match status of the relation pair. "
),
doc +
"\n"
"Upon successful match, the \\first and \\second members are the matching objects and \\status is 'Match'."
"\n"
"This object is also used to describe non-matches or match errors. In this case, \\first or \\second may be nil and "
"\\status further describes the case."
)
{ }
};
template <class Obj>
static const Obj *first_of_pair (const std::pair<const Obj *, const Obj *> *pair)
{
return pair->first;
}
template <class Obj>
static const Obj *second_of_pair (const std::pair<const Obj *, const Obj *> *pair)
{
return pair->second;
}
template <class Obj>
class NetObjectPairClass
: public ChildClass<db::NetlistCrossReference, std::pair<const Obj *, const Obj *> >
{
public:
NetObjectPairClass (const std::string &module, const std::string &name, const std::string &doc)
: gsi::ChildClass<db::NetlistCrossReference, std::pair<const Obj *, const Obj *> > (module, name,
gsi::method_ext ("first", &first_of_pair<Obj>,
"@brief Gets the first object of the relation pair.\n"
"The first object is usually the one obtained from the layout-derived netlist. "
"This member can be nil if the pair is describing a non-matching reference object. "
"In this case, the \\second member is the reference object for which no match was found."
) +
gsi::method_ext ("second", &second_of_pair<Obj>,
"@brief Gets the second object of the relation pair.\n"
"The first object is usually the one obtained from the reference netlist. "
"This member can be nil if the pair is describing a non-matching layout object. "
"In this case, the \\first member is the layout-derived object for which no match was found."
),
doc +
"\n"
"Upon successful match, the \\first and \\second members are the matching net objects."
"Otherwise, either \\first or \\second is nil and the other member is the object for "
"which no match was found."
)
{ }
};
}
PairDataClass<db::NetlistCrossReference::NetPairData> decl_dbNetlistCrossReference_NetPairData ("db", "NetPairData",
"@brief A net match entry.\n"
"This object is used to describe the relationship of two nets in a netlist match.\n"
);
PairDataClass<db::NetlistCrossReference::DevicePairData> decl_dbNetlistCrossReference_DevicePairData ("db", "DevicePairData",
"@brief A device match entry.\n"
"This object is used to describe the relationship of two devices in a netlist match.\n"
);
PairDataClass<db::NetlistCrossReference::PinPairData> decl_dbNetlistCrossReference_PinPairData ("db", "PinPairData",
"@brief A pin match entry.\n"
"This object is used to describe the relationship of two circuit pins in a netlist match.\n"
);
PairDataClass<db::NetlistCrossReference::SubCircuitPairData> decl_dbNetlistCrossReference_SubCircuitPairData ("db", "SubCircuitPairData",
"@brief A subcircuit match entry.\n"
"This object is used to describe the relationship of two subcircuits in a netlist match.\n"
);
PairDataClass<CircuitPairData> decl_dbNetlistCrossReference_CircuitPairData ("db", "CircuitPairData",
"@brief A circuit match entry.\n"
"This object is used to describe the relationship of two circuits in a netlist match.\n"
);
NetObjectPairClass<db::NetTerminalRef> decl_dbNetlistCrossReference_NetTerminalRefPair ("db", "NetTerminalRefPair",
"@brief A match entry for a net terminal pair.\n"
"This object is used to describe the matching terminal pairs or non-matching terminals on a net.\n"
);
NetObjectPairClass<db::NetPinRef> decl_dbNetlistCrossReference_NetPinRefPair ("db", "NetPinRefPair",
"@brief A match entry for a net pin pair.\n"
"This object is used to describe the matching pin pairs or non-matching pins on a net.\n"
);
NetObjectPairClass<db::NetSubcircuitPinRef> decl_dbNetlistCrossReference_NetSubcircuitPinRefPair ("db", "NetSubcircuitPinRefPair",
"@brief A match entry for a net subcircuit pin pair.\n"
"This object is used to describe the matching subcircuit pin pairs or non-matching subcircuit pins on a net.\n"
);
extern Class<db::NetlistCompareLogger> decl_dbNetlistCompareLogger;
namespace {
class CircuitPairIterator
{
public:
// makes STL happy:
typedef std::forward_iterator_tag iterator_category;
typedef CircuitPairData value_type;
typedef size_t difference_type;
typedef const CircuitPairData *pointer;
typedef const CircuitPairData &reference;
CircuitPairIterator (db::NetlistCrossReference *xref)
: m_xref (xref), m_iter (xref->begin_circuits ()), m_end_iter (xref->end_circuits ())
{ }
bool at_end () const
{
return m_xref.get () == 0 || m_iter == m_end_iter;
}
CircuitPairIterator &operator++ ()
{
++m_iter;
return *this;
}
pointer operator-> () const
{
m_data.pair = *m_iter;
const db::NetlistCrossReference::PerCircuitData *data = m_xref->per_circuit_data_for (*m_iter);
tl_assert (data != 0);
m_data.status = data->status;
return &m_data;
}
reference operator* () const
{
return *operator-> ();
}
tl::weak_ptr<db::NetlistCrossReference> m_xref;
mutable CircuitPairData m_data;
db::NetlistCrossReference::circuits_iterator m_iter, m_end_iter;
};
template <class PairData, class PairDataIter>
class pair_data_iterator
{
public:
// makes STL happy:
typedef std::forward_iterator_tag iterator_category;
typedef PairData value_type;
typedef size_t difference_type;
typedef const PairData *pointer;
typedef const PairData &reference;
pair_data_iterator ()
: m_xref (), m_iter (), m_end_iter ()
{ }
pair_data_iterator (db::NetlistCrossReference *xref, const PairDataIter &iter, const PairDataIter &end_iter)
: m_xref (xref), m_iter (iter), m_end_iter (end_iter)
{ }
bool at_end () const
{
return m_xref.get () == 0 || m_iter == m_end_iter;
}
pair_data_iterator &operator++ ()
{
++m_iter;
return *this;
}
pointer operator-> () const
{
return m_iter.operator-> ();
}
reference operator* () const
{
return *operator-> ();
}
tl::weak_ptr<db::NetlistCrossReference> m_xref;
PairDataIter m_iter, m_end_iter;
};
}
static CircuitPairIterator each_circuit_pair (db::NetlistCrossReference *xref)
{
return CircuitPairIterator (xref);
}
static pair_data_iterator<db::NetlistCrossReference::NetPairData, db::NetlistCrossReference::PerCircuitData::net_pairs_const_iterator> each_net_pair (db::NetlistCrossReference *xref, const CircuitPairData &circuit_pair)
{
typedef pair_data_iterator<db::NetlistCrossReference::NetPairData, db::NetlistCrossReference::PerCircuitData::net_pairs_const_iterator> iter_type;
const db::NetlistCrossReference::PerCircuitData *data = xref->per_circuit_data_for (circuit_pair.pair);
if (! data) {
return iter_type ();
} else {
return iter_type (xref, data->nets.begin (), data->nets.end ());
}
}
static pair_data_iterator<db::NetlistCrossReference::DevicePairData, db::NetlistCrossReference::PerCircuitData::device_pairs_const_iterator> each_device_pair (db::NetlistCrossReference *xref, const CircuitPairData &circuit_pair)
{
typedef pair_data_iterator<db::NetlistCrossReference::DevicePairData, db::NetlistCrossReference::PerCircuitData::device_pairs_const_iterator> iter_type;
const db::NetlistCrossReference::PerCircuitData *data = xref->per_circuit_data_for (circuit_pair.pair);
if (! data) {
return iter_type ();
} else {
return iter_type (xref, data->devices.begin (), data->devices.end ());
}
}
static pair_data_iterator<db::NetlistCrossReference::PinPairData, db::NetlistCrossReference::PerCircuitData::pin_pairs_const_iterator> each_pin_pair (db::NetlistCrossReference *xref, const CircuitPairData &circuit_pair)
{
typedef pair_data_iterator<db::NetlistCrossReference::PinPairData, db::NetlistCrossReference::PerCircuitData::pin_pairs_const_iterator> iter_type;
const db::NetlistCrossReference::PerCircuitData *data = xref->per_circuit_data_for (circuit_pair.pair);
if (! data) {
return iter_type ();
} else {
return iter_type (xref, data->pins.begin (), data->pins.end ());
}
}
static pair_data_iterator<db::NetlistCrossReference::SubCircuitPairData, db::NetlistCrossReference::PerCircuitData::subcircuit_pairs_const_iterator> each_subcircuit_pair (db::NetlistCrossReference *xref, const CircuitPairData &circuit_pair)
{
typedef pair_data_iterator<db::NetlistCrossReference::SubCircuitPairData, db::NetlistCrossReference::PerCircuitData::subcircuit_pairs_const_iterator> iter_type;
const db::NetlistCrossReference::PerCircuitData *data = xref->per_circuit_data_for (circuit_pair.pair);
if (! data) {
return iter_type ();
} else {
return iter_type (xref, data->subcircuits.begin (), data->subcircuits.end ());
}
}
static pair_data_iterator<std::pair<const db::NetTerminalRef *, const db::NetTerminalRef *>, db::NetlistCrossReference::PerNetData::terminal_pairs_const_iterator> each_net_terminal_pair (db::NetlistCrossReference *xref, const db::NetlistCrossReference::NetPairData &net_pair)
{
typedef pair_data_iterator<std::pair<const db::NetTerminalRef *, const db::NetTerminalRef *>, db::NetlistCrossReference::PerNetData::terminal_pairs_const_iterator> iter_type;
const db::NetlistCrossReference::PerNetData *data = xref->per_net_data_for (net_pair.pair);
if (! data) {
return iter_type ();
} else {
return iter_type (xref, data->terminals.begin (), data->terminals.end ());
}
}
static pair_data_iterator<std::pair<const db::NetPinRef *, const db::NetPinRef *>, db::NetlistCrossReference::PerNetData::pin_pairs_const_iterator> each_net_pin_pair (db::NetlistCrossReference *xref, const db::NetlistCrossReference::NetPairData &net_pair)
{
typedef pair_data_iterator<std::pair<const db::NetPinRef *, const db::NetPinRef *>, db::NetlistCrossReference::PerNetData::pin_pairs_const_iterator> iter_type;
const db::NetlistCrossReference::PerNetData *data = xref->per_net_data_for (net_pair.pair);
if (! data) {
return iter_type ();
} else {
return iter_type (xref, data->pins.begin (), data->pins.end ());
}
}
static pair_data_iterator<std::pair<const db::NetSubcircuitPinRef *, const db::NetSubcircuitPinRef *>, db::NetlistCrossReference::PerNetData::subcircuit_pin_pairs_const_iterator> each_net_subcircuit_pin_pair (db::NetlistCrossReference *xref, const db::NetlistCrossReference::NetPairData &net_pair)
{
typedef pair_data_iterator<std::pair<const db::NetSubcircuitPinRef *, const db::NetSubcircuitPinRef *>, db::NetlistCrossReference::PerNetData::subcircuit_pin_pairs_const_iterator> iter_type;
const db::NetlistCrossReference::PerNetData *data = xref->per_net_data_for (net_pair.pair);
if (! data) {
return iter_type ();
} else {
return iter_type (xref, data->subcircuit_pins.begin (), data->subcircuit_pins.end ());
}
}
Class<db::NetlistCrossReference> decl_dbNetlistCrossReference (decl_dbNetlistCompareLogger, "db", "NetlistCrossReference",
gsi::iterator_ext ("each_circuit_pair", &each_circuit_pair,
"@brief Delivers the circuit pairs and their status.\n"
"See the class description for details."
) +
gsi::iterator_ext ("each_net_pair", &each_net_pair, gsi::arg ("circuit_pair"),
"@brief Delivers the nets pairs and their status for the given circuit pair.\n"
"See the class description for details."
) +
gsi::iterator_ext ("each_device_pair", &each_device_pair, gsi::arg ("circuit_pair"),
"@brief Delivers the device pairs and their status for the given circuit pair.\n"
"See the class description for details."
) +
gsi::iterator_ext ("each_pin_pair", &each_pin_pair, gsi::arg ("circuit_pair"),
"@brief Delivers the pin pairs and their status for the given circuit pair.\n"
"See the class description for details."
) +
gsi::iterator_ext ("each_subcircuit_pair", &each_subcircuit_pair, gsi::arg ("circuit_pair"),
"@brief Delivers the subcircuit pairs and their status for the given circuit pair.\n"
"See the class description for details."
) +
gsi::iterator_ext ("each_net_terminal_pair", &each_net_terminal_pair, gsi::arg ("net_pair"),
"@brief Delivers the device terminal pairs for the given net.\n"
"For a given net pair, lists the device terminal pairs identified on this net."
) +
gsi::iterator_ext ("each_net_pin_pair", &each_net_pin_pair, gsi::arg ("net_pair"),
"@brief Delivers the pin pairs for the given net.\n"
"For a given net pair, lists the pin pairs identified on this net."
) +
gsi::iterator_ext ("each_net_subcircuit_pin_pair", &each_net_subcircuit_pin_pair, gsi::arg ("net_pair"),
"@brief Delivers the subcircuit pin pairs for the given net.\n"
"For a given net pair, lists the subcircuit pin pairs identified on this net."
) +
gsi::method ("other_net_for", &db::NetlistCrossReference::other_net_for, gsi::arg ("net"),
"@brief Gets the matching net for a given net.\n"
"The return value will be nil if no match is found."
) +
gsi::method ("clear", &db::NetlistCrossReference::clear,
"@hide\n"
) +
gsi::method ("circuit_count", &db::NetlistCrossReference::circuit_count,
"@brief Gets the number of circuit pairs in the cross-reference object."
) +
gsi::method ("netlist_a", &db::NetlistCrossReference::netlist_a,
"@brief Gets the first netlist in the compare.\n"
) +
gsi::method ("netlist_b", &db::NetlistCrossReference::netlist_b,
"@brief Gets the second netlist in the compare.\n"
),
"@brief Represents the identity mapping between the objects of two netlists.\n"
"\n"
"The NetlistCrossReference object is a container for the results of a netlist comparison. "
"It implemented the \\NetlistCompareLogger interface, hence can be used as output for "
"a netlist compare operation (\\NetlistComparer#compare). It's purpose is to store the "
"results of the compare. It is used in this sense inside the \\LayoutVsSchematic framework.\n"
"\n"
"The basic idea of the cross reference object is pairing: the netlist comparer will try "
"to identify matching items and store them as pairs inside the cross reference object. "
"If no match is found, a single-sided pair is generated: one item is nil in this case.\n"
"Beside the items, a status is kept which gives more details about success or failure of the "
"match operation.\n"
"\n"
"Item pairing happens on different levels, reflecting the hierarchy of the netlists. "
"On the top level there are circuits. Inside circuits nets, devices, subcircuits and pins "
"are paired. Nets further contribute their connected items through terminals (for devices), "
"pins (outgoing) and subcircuit pins.\n"
"\n"
"This class has been introduced in version 0.26."
);
// TODO: there is no "enum as child class" currently, so we have to define that on top level too
static gsi::Enum<db::NetlistCrossReference::Status> decl_NetlistCrossReference_Status ("db", "NetlistCrossReference_Status",
gsi::enum_const ("None", db::NetlistCrossReference::None,
"@brief Enum constant NetlistCrossReference::None\n"
"No specific status is stored if this code is present."
) +
gsi::enum_const ("Match", db::NetlistCrossReference::Match,
"@brief Enum constant NetlistCrossReference::Match\n"
"If this code is present, an exact match is present.\n"
) +
gsi::enum_const ("NoMatch", db::NetlistCrossReference::NoMatch,
"@brief Enum constant NetlistCrossReference::NoMatch\n"
"If this code is present, no match could be found.\n"
"There is also 'Mismatch' which means there is a candidate, but exact "
"identity could not be confirmed."
) +
gsi::enum_const ("Skipped", db::NetlistCrossReference::Skipped,
"@brief Enum constant NetlistCrossReference::Skipped\n"
"This code on circuits means that a match has not been attempted because "
"subcircuits of this circuits were not matched. As circuit matching happens "
"bottom-up, all subcircuits must match at least with respect to their pins "
"to allow any parent circuit to be matched."
) +
gsi::enum_const ("MatchWithWarning", db::NetlistCrossReference::MatchWithWarning,
"@brief Enum constant NetlistCrossReference::MatchWithWarning\n"
"If this code is present, a match was found but a warning is issued. For nets this "
"means that the choice of matches is ambiguous and an unspecific candidate has been chosen. "
"For devices, this means a device match was established, but parameters or the device class "
"are not matching exactly."
) +
gsi::enum_const ("Mismatch", db::NetlistCrossReference::Mismatch,
"@brief Enum constant NetlistCrossReference::Mismatch\n"
"There code means there is a match candidate, but exact identity could not be confirmed."
),
"@brief This class represents the NetlistCrossReference::Status enum"
);
// Inject the NetlistCrossReference::Status declarations into NetlistCrossReference:
// Inject constants:
static gsi::ClassExt<db::NetlistCrossReference> inject_NetlistCrossReference_Status_in_parent (decl_NetlistCrossReference_Status.defs ());
// Inject class:
static gsi::ClassExt<db::NetlistCrossReference> decl_NetlistCrossReference_Status_as_child (decl_dbNetlistCrossReference, "Status");
}