diff --git a/src/db/db/db.pro b/src/db/db/db.pro index cd4242493..770575fd7 100644 --- a/src/db/db/db.pro +++ b/src/db/db/db.pro @@ -181,7 +181,9 @@ SOURCES = \ dbLayoutVsSchematicWriter.cc \ dbLayoutVsSchematicReader.cc \ dbLayoutVsSchematicFormatDefs.cc \ - dbLayoutVsSchematic.cc + dbLayoutVsSchematic.cc \ + gsiDeclDbNetlistCrossReference.cc \ + gsiDeclDbLayoutVsSchematic.cc HEADERS = \ dbArray.h \ diff --git a/src/db/db/gsiDeclDbLayoutVsSchematic.cc b/src/db/db/gsiDeclDbLayoutVsSchematic.cc new file mode 100644 index 000000000..b3d9396c2 --- /dev/null +++ b/src/db/db/gsiDeclDbLayoutVsSchematic.cc @@ -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 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 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." +); + +} diff --git a/src/db/db/gsiDeclDbNetlistCrossReference.cc b/src/db/db/gsiDeclDbNetlistCrossReference.cc new file mode 100644 index 000000000..51534ee3d --- /dev/null +++ b/src/db/db/gsiDeclDbNetlistCrossReference.cc @@ -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 pair; + db::NetlistCrossReference::Status status; +}; + +template +static const typename PairData::object_type *first (const PairData *data) +{ + return data->pair.first; +} + +template +static const typename PairData::object_type *second (const PairData *data) +{ + return data->pair.second; +} + +template +static db::NetlistCrossReference::Status status (const PairData *data) +{ + return data->status; +} + +template +class PairDataClass + : public ChildClass +{ +public: + PairDataClass (const std::string &module, const std::string &name, const std::string &doc) + : gsi::ChildClass (module, name, + gsi::method_ext ("first", &first, + "@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, + "@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, + "@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 +static const Obj *first_of_pair (const std::pair *pair) +{ + return pair->first; +} + +template +static const Obj *second_of_pair (const std::pair *pair) +{ + return pair->second; +} + +template +class NetObjectPairClass + : public ChildClass > +{ +public: + NetObjectPairClass (const std::string &module, const std::string &name, const std::string &doc) + : gsi::ChildClass > (module, name, + gsi::method_ext ("first", &first_of_pair, + "@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, + "@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 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 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 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 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 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 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 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 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 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 m_xref; + mutable CircuitPairData m_data; + db::NetlistCrossReference::circuits_iterator m_iter, m_end_iter; +}; + +template +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 m_xref; + PairDataIter m_iter, m_end_iter; +}; + +} + +static CircuitPairIterator each_circuit_pair (db::NetlistCrossReference *xref) +{ + return CircuitPairIterator (xref); +} + +static pair_data_iterator each_net_pair (db::NetlistCrossReference *xref, const CircuitPairData &circuit_pair) +{ + typedef pair_data_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 each_device_pair (db::NetlistCrossReference *xref, const CircuitPairData &circuit_pair) +{ + typedef pair_data_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 each_pin_pair (db::NetlistCrossReference *xref, const CircuitPairData &circuit_pair) +{ + typedef pair_data_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 each_subcircuit_pair (db::NetlistCrossReference *xref, const CircuitPairData &circuit_pair) +{ + typedef pair_data_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, db::NetlistCrossReference::PerNetData::terminal_pairs_const_iterator> each_net_terminal_pair (db::NetlistCrossReference *xref, const db::NetlistCrossReference::NetPairData &net_pair) +{ + typedef pair_data_iterator, 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, db::NetlistCrossReference::PerNetData::pin_pairs_const_iterator> each_net_pin_pair (db::NetlistCrossReference *xref, const db::NetlistCrossReference::NetPairData &net_pair) +{ + typedef pair_data_iterator, 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, 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, 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 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 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 inject_NetlistCrossReference_Status_in_parent (decl_NetlistCrossReference_Status.defs ()); +// Inject class: +static gsi::ClassExt decl_NetlistCrossReference_Status_as_child (decl_dbNetlistCrossReference, "Status"); + +}