mirror of https://github.com/KLayout/klayout.git
Fixed tests. Note that now a net with two labels carries a combined net name and does not qualify for connect_implicit if one label matches
This commit is contained in:
parent
c81388d830
commit
4d41ca6f5c
|
|
@ -247,7 +247,7 @@ void LayoutToNetlist::extract_devices (db::NetlistDeviceExtractor &extractor, co
|
|||
|
||||
// transfer errors to log entries
|
||||
for (auto e = extractor.begin_errors (); e != extractor.end_errors (); ++e) {
|
||||
m_log_entries.push_back (db::LogEntryData (db::Error, e->to_string ()));
|
||||
m_log_entries.push_back (db::LogEntryData (e->is_warning () ? db::Warning : db::Error, e->to_string ()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -369,48 +369,7 @@ void LayoutToNetlist::extract_netlist ()
|
|||
}
|
||||
ensure_netlist ();
|
||||
|
||||
const db::Layout &layout = dss ().layout (m_layout_index);
|
||||
|
||||
db::NetlistExtractor netex;
|
||||
|
||||
#if 0 // @@@ remove this plus corresponding code inside NetlistExtractor ...
|
||||
netex.set_joined_net_names (m_joined_net_names);
|
||||
|
||||
std::map<std::string, std::list<tl::GlobPattern> > jp_per_cell;
|
||||
for (std::list<std::pair<tl::GlobPattern, tl::GlobPattern> >::const_iterator j = m_joined_net_names_per_cell.begin (); j != m_joined_net_names_per_cell.end (); ++j) {
|
||||
if (j->first.is_const ()) {
|
||||
jp_per_cell [j->first.pattern ()].push_back (j->second);
|
||||
} else {
|
||||
for (db::Layout::const_iterator c = layout.begin (); c != layout.end (); ++c) {
|
||||
if (j->first.match (layout.cell_name (c->cell_index ()))) {
|
||||
jp_per_cell [layout.cell_name (c->cell_index ())].push_back (j->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (std::map<std::string, std::list<tl::GlobPattern> >::const_iterator i = jp_per_cell.begin (); i != jp_per_cell.end (); ++i) {
|
||||
netex.set_joined_net_names (i->first, i->second);
|
||||
}
|
||||
|
||||
netex.set_joined_nets (m_joined_nets);
|
||||
|
||||
std::map<std::string, std::list<std::set<std::string> > > jn_per_cell;
|
||||
for (std::list<std::pair<tl::GlobPattern, std::set<std::string> > >::const_iterator j = m_joined_nets_per_cell.begin (); j != m_joined_nets_per_cell.end (); ++j) {
|
||||
if (j->first.is_const ()) {
|
||||
jn_per_cell [j->first.pattern ()].push_back (j->second);
|
||||
} else {
|
||||
for (db::Layout::const_iterator c = layout.begin (); c != layout.end (); ++c) {
|
||||
if (j->first.match (layout.cell_name (c->cell_index ()))) {
|
||||
jn_per_cell [layout.cell_name (c->cell_index ())].push_back (j->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (std::map<std::string, std::list<std::set<std::string> > >::const_iterator i = jn_per_cell.begin (); i != jn_per_cell.end (); ++i) {
|
||||
netex.set_joined_nets (i->first, i->second);
|
||||
}
|
||||
#endif
|
||||
|
||||
netex.set_include_floating_subcircuits (m_include_floating_subcircuits);
|
||||
netex.extract_nets (dss (), m_layout_index, m_conn, *mp_netlist, m_net_clusters);
|
||||
|
||||
|
|
@ -423,8 +382,29 @@ void LayoutToNetlist::extract_netlist ()
|
|||
}
|
||||
|
||||
m_netlist_extracted = true;
|
||||
}
|
||||
|
||||
// @@@ raise error on error
|
||||
void LayoutToNetlist::check_extraction_errors ()
|
||||
{
|
||||
int num_errors = 0;
|
||||
int max_errors = 10;
|
||||
std::string errors;
|
||||
for (auto l = m_log_entries.begin (); l != m_log_entries.end (); ++l) {
|
||||
if (l->severity >= db::Error) {
|
||||
errors += "\n";
|
||||
if (++num_errors >= max_errors) {
|
||||
errors += "...\n";
|
||||
errors += tl::sprintf (tl::to_string (tr ("(list shortened after %d errrors, see log for all errors)")), max_errors);
|
||||
break;
|
||||
} else {
|
||||
errors += l->msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (num_errors > 0) {
|
||||
throw tl::Exception (tl::to_string (tr ("Errors encountered during netlist extraction:")) + errors);
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutToNetlist::join_nets_from_pattern (db::Circuit &c, const tl::GlobPattern &p)
|
||||
|
|
@ -485,7 +465,6 @@ void LayoutToNetlist::check_must_connect (const db::Circuit &c, const db::Net &a
|
|||
return;
|
||||
}
|
||||
|
||||
// @@@ raise a warning for top level cells?
|
||||
if (c.begin_refs () != c.end_refs ()) {
|
||||
if (a.begin_pins () == a.end_pins ()) {
|
||||
error (tl::sprintf (tl::to_string (tr ("Must-connect net %s from circuit %s is not connected to outside")), a.expanded_name (), c.name ()));
|
||||
|
|
@ -493,11 +472,18 @@ void LayoutToNetlist::check_must_connect (const db::Circuit &c, const db::Net &a
|
|||
if (b.begin_pins () == b.end_pins ()) {
|
||||
error (tl::sprintf (tl::to_string (tr ("Must-connect net %s from circuit %s is not connected to outside")), a.expanded_name (), c.name ()));
|
||||
}
|
||||
} else {
|
||||
if (a.expanded_name () == b.expanded_name ()) {
|
||||
warn (tl::sprintf (tl::to_string (tr ("Must-connect nets %s from circuit %s must be connected further up in the hierarchy. This is an error at the chip top level.")), a.expanded_name (), c.name ()));
|
||||
} else {
|
||||
warn (tl::sprintf (tl::to_string (tr ("Must-connect nets %s and %s from circuit %s must be connected further up in the hierarchy. This is an error at the chip top level.")), a.expanded_name (), b.expanded_name (), c.name ()));
|
||||
}
|
||||
}
|
||||
|
||||
if (a.begin_pins () != a.end_pins () && b.begin_pins () != b.end_pins ()) {
|
||||
for (auto ref = c.begin_refs (); ref != c.end_refs (); ++ref) {
|
||||
const db::SubCircuit &sc = *ref;
|
||||
// TODO: consider the case of multiple pins on a net (rare)
|
||||
const db::Net *net_a = sc.net_for_pin (a.begin_pins ()->pin_id ());
|
||||
const db::Net *net_b = sc.net_for_pin (b.begin_pins ()->pin_id ());
|
||||
if (net_a == 0) {
|
||||
|
|
@ -557,18 +543,29 @@ void LayoutToNetlist::do_join_nets ()
|
|||
|
||||
void LayoutToNetlist::error (const std::string &msg)
|
||||
{
|
||||
if (m_log_entries.empty () || m_log_entries.back ().severity != db::Error || m_log_entries.back ().msg != msg) {
|
||||
tl::error << msg;
|
||||
m_log_entries.push_back (db::LogEntryData (db::Error, msg));
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutToNetlist::warn (const std::string &msg)
|
||||
{
|
||||
if (m_log_entries.empty () || m_log_entries.back ().severity != db::Warning || m_log_entries.back ().msg != msg) {
|
||||
tl::warn << msg;
|
||||
m_log_entries.push_back (db::LogEntryData (db::Warning, msg));
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutToNetlist::info (const std::string &msg)
|
||||
{
|
||||
if (m_log_entries.empty () || m_log_entries.back ().severity != db::Info || m_log_entries.back ().msg != msg) {
|
||||
if (tl::verbosity () >= 10) {
|
||||
tl::info << msg;
|
||||
}
|
||||
m_log_entries.push_back (db::LogEntryData (db::Info, msg));
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutToNetlist::mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -194,7 +194,6 @@ public:
|
|||
|
||||
/**
|
||||
* @brief Gets the log entries
|
||||
* @@@ TODO: provide GSI interface
|
||||
*/
|
||||
const log_entries_type &log_entries () const
|
||||
{
|
||||
|
|
@ -203,7 +202,6 @@ public:
|
|||
|
||||
/**
|
||||
* @brief Clears the log entries
|
||||
* @@@ TODO: provide GSI interface
|
||||
*/
|
||||
void clear_log_entries ()
|
||||
{
|
||||
|
|
@ -212,7 +210,6 @@ public:
|
|||
|
||||
/**
|
||||
* @brief Adds a log entry
|
||||
* @@@ TODO: provide GSI interface
|
||||
*/
|
||||
void log_entry (const db::LogEntryData &log_entry)
|
||||
{
|
||||
|
|
@ -587,6 +584,8 @@ public:
|
|||
*/
|
||||
void extract_netlist ();
|
||||
|
||||
void check_extraction_errors ();
|
||||
|
||||
/**
|
||||
* @brief Marks the netlist as extracted
|
||||
* NOTE: this method is provided for special cases such as netlist readers. Don't
|
||||
|
|
|
|||
|
|
@ -36,12 +36,13 @@ namespace db
|
|||
// NetlistDeviceExtractorError implementation
|
||||
|
||||
NetlistDeviceExtractorError::NetlistDeviceExtractorError ()
|
||||
: m_warning (false)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
NetlistDeviceExtractorError::NetlistDeviceExtractorError (const std::string &cell_name, const std::string &msg)
|
||||
: m_cell_name (cell_name), m_message (msg)
|
||||
: m_warning (false), m_cell_name (cell_name), m_message (msg)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -626,4 +627,50 @@ void NetlistDeviceExtractor::error (const std::string &category_name, const std:
|
|||
}
|
||||
}
|
||||
|
||||
void NetlistDeviceExtractor::warn (const std::string &msg)
|
||||
{
|
||||
m_errors.push_back (db::NetlistDeviceExtractorError (cell_name (), msg));
|
||||
m_errors.back ().set_warning (true);
|
||||
|
||||
if (tl::verbosity () >= 20) {
|
||||
tl::warn << m_errors.back ().to_string ();
|
||||
}
|
||||
}
|
||||
|
||||
void NetlistDeviceExtractor::warn (const std::string &msg, const db::DPolygon &poly)
|
||||
{
|
||||
m_errors.push_back (db::NetlistDeviceExtractorError (cell_name (), msg));
|
||||
m_errors.back ().set_geometry (poly);
|
||||
m_errors.back ().set_warning (true);
|
||||
|
||||
if (tl::verbosity () >= 20) {
|
||||
tl::warn << m_errors.back ().to_string ();
|
||||
}
|
||||
}
|
||||
|
||||
void NetlistDeviceExtractor::warn (const std::string &category_name, const std::string &category_description, const std::string &msg)
|
||||
{
|
||||
m_errors.push_back (db::NetlistDeviceExtractorError (cell_name (), msg));
|
||||
m_errors.back ().set_category_name (category_name);
|
||||
m_errors.back ().set_category_description (category_description);
|
||||
m_errors.back ().set_warning (true);
|
||||
|
||||
if (tl::verbosity () >= 20) {
|
||||
tl::warn << m_errors.back ().to_string ();
|
||||
}
|
||||
}
|
||||
|
||||
void NetlistDeviceExtractor::warn (const std::string &category_name, const std::string &category_description, const std::string &msg, const db::DPolygon &poly)
|
||||
{
|
||||
m_errors.push_back (db::NetlistDeviceExtractorError (cell_name (), msg));
|
||||
m_errors.back ().set_category_name (category_name);
|
||||
m_errors.back ().set_category_description (category_description);
|
||||
m_errors.back ().set_geometry (poly);
|
||||
m_errors.back ().set_warning (true);
|
||||
|
||||
if (tl::verbosity () >= 20) {
|
||||
tl::warn << m_errors.back ().to_string ();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,22 @@ public:
|
|||
*/
|
||||
NetlistDeviceExtractorError (const std::string &cell_name, const std::string &msg);
|
||||
|
||||
/**
|
||||
* @brief Sets a value indicating whether the error is only a warning
|
||||
*/
|
||||
void set_warning (bool f)
|
||||
{
|
||||
m_warning = f;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether the error is only a warning
|
||||
*/
|
||||
bool is_warning () const
|
||||
{
|
||||
return m_warning;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The category name of the error
|
||||
* Specifying the category name is optional. If a category is given, it will be used for
|
||||
|
|
@ -145,6 +161,7 @@ public:
|
|||
std::string to_string () const;
|
||||
|
||||
private:
|
||||
bool m_warning;
|
||||
std::string m_cell_name;
|
||||
std::string m_message;
|
||||
db::DPolygon m_geometry;
|
||||
|
|
@ -506,6 +523,42 @@ public:
|
|||
error (category_name, category_description, msg, poly.transformed (db::CplxTrans (dbu ())));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Issues a warning with the given message
|
||||
*/
|
||||
void warn (const std::string &msg);
|
||||
|
||||
/**
|
||||
* @brief Issues a warning with the given message and warn shape
|
||||
*/
|
||||
void warn (const std::string &msg, const db::DPolygon &poly);
|
||||
|
||||
/**
|
||||
* @brief Issues a warning with the given message and warn shape
|
||||
*/
|
||||
void warn (const std::string &msg, const db::Polygon &poly)
|
||||
{
|
||||
warn (msg, poly.transformed (db::CplxTrans (dbu ())));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Issues a warning with the given category name, description and message
|
||||
*/
|
||||
void warn (const std::string &category_name, const std::string &category_description, const std::string &msg);
|
||||
|
||||
/**
|
||||
* @brief Issues a warning with the given category name, description and message and warn shape
|
||||
*/
|
||||
void warn (const std::string &category_name, const std::string &category_description, const std::string &msg, const db::DPolygon &poly);
|
||||
|
||||
/**
|
||||
* @brief Issues a warning with the given category name, description and message and warn shape
|
||||
*/
|
||||
void warn (const std::string &category_name, const std::string &category_description, const std::string &msg, const db::Polygon &poly)
|
||||
{
|
||||
warn (category_name, category_description, msg, poly.transformed (db::CplxTrans (dbu ())));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the name of the current cell
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -136,11 +136,11 @@ void NetlistDeviceExtractorMOS3Transistor::extract_devices (const std::vector<db
|
|||
rdiff2gate.set_base_verbosity (rdiff.base_verbosity ());
|
||||
|
||||
if (rdiff2gate.empty ()) {
|
||||
error (tl::to_string (tr ("Gate shape touches no diffusion - ignored")), *p);
|
||||
warn (tl::to_string (tr ("Gate shape touches no diffusion - ignored")), *p);
|
||||
} else {
|
||||
|
||||
if (rdiff2gate.count () != 2) {
|
||||
error (tl::sprintf (tl::to_string (tr ("Expected two polygons on diff interacting with one gate shape (found %d) - gate shape ignored")), int (rdiff2gate.count ())), *p);
|
||||
warn (tl::sprintf (tl::to_string (tr ("Expected two polygons on diff interacting with one gate shape (found %d) - gate shape ignored")), int (rdiff2gate.count ())), *p);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -158,7 +158,7 @@ void NetlistDeviceExtractorMOS3Transistor::extract_devices (const std::vector<db
|
|||
db::Edges edges (rgate.edges () & db::Edges (*d2g));
|
||||
db::Edges::length_type l = edges.length ();
|
||||
if (l == 0) {
|
||||
error (tl::to_string (tr ("Vanishing edges for interaction gate/diff (corner interaction) - gate shape ignored")));
|
||||
warn (tl::to_string (tr ("Vanishing edges for interaction gate/diff (corner interaction) - gate shape ignored")));
|
||||
} else {
|
||||
widths.push_back (l);
|
||||
}
|
||||
|
|
@ -237,18 +237,18 @@ void NetlistDeviceExtractorMOS3Transistor::extract_devices (const std::vector<db
|
|||
ddiff2gate.set_base_verbosity (ddiff.base_verbosity ());
|
||||
|
||||
if (sdiff2gate.empty () && ddiff2gate.empty ()) {
|
||||
error (tl::to_string (tr ("Gate shape touches no diffusion - ignored")), *p);
|
||||
warn (tl::to_string (tr ("Gate shape touches no diffusion - ignored")), *p);
|
||||
} else if (sdiff2gate.empty () || ddiff2gate.empty ()) {
|
||||
error (tl::to_string (tr ("Gate shape touches a single diffusion only - ignored")), *p);
|
||||
warn (tl::to_string (tr ("Gate shape touches a single diffusion only - ignored")), *p);
|
||||
} else {
|
||||
|
||||
if (sdiff2gate.count () != 1) {
|
||||
error (tl::sprintf (tl::to_string (tr ("Expected one polygons on source diff interacting with one gate shape (found %d) - gate shape ignored")), int (sdiff2gate.count ())), *p);
|
||||
warn (tl::sprintf (tl::to_string (tr ("Expected one polygons on source diff interacting with one gate shape (found %d) - gate shape ignored")), int (sdiff2gate.count ())), *p);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ddiff2gate.count () != 1) {
|
||||
error (tl::sprintf (tl::to_string (tr ("Expected one polygons on drain diff interacting with one gate shape (found %d) - gate shape ignored")), int (ddiff2gate.count ())), *p);
|
||||
warn (tl::sprintf (tl::to_string (tr ("Expected one polygons on drain diff interacting with one gate shape (found %d) - gate shape ignored")), int (ddiff2gate.count ())), *p);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -258,7 +258,7 @@ void NetlistDeviceExtractorMOS3Transistor::extract_devices (const std::vector<db
|
|||
db::Edges edges (rgate.edges () & sdiff2gate.edges ());
|
||||
sdwidth = edges.length ();
|
||||
if (sdwidth == 0) {
|
||||
error (tl::to_string (tr ("Vanishing edges for interaction gate/source diff (corner interaction) - gate shape ignored")));
|
||||
warn (tl::to_string (tr ("Vanishing edges for interaction gate/source diff (corner interaction) - gate shape ignored")));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -267,7 +267,7 @@ void NetlistDeviceExtractorMOS3Transistor::extract_devices (const std::vector<db
|
|||
db::Edges edges (rgate.edges () & ddiff2gate.edges ());
|
||||
ddwidth = edges.length ();
|
||||
if (ddwidth == 0) {
|
||||
error (tl::to_string (tr ("Vanishing edges for interaction gate/drain diff (corner interaction) - gate shape ignored")));
|
||||
warn (tl::to_string (tr ("Vanishing edges for interaction gate/drain diff (corner interaction) - gate shape ignored")));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -438,7 +438,7 @@ void NetlistDeviceExtractorResistor::extract_devices (const std::vector<db::Regi
|
|||
db::Region contacts_per_res = contact_wo_res.selected_interacting (rres);
|
||||
|
||||
if (contacts_per_res.count () != 2) {
|
||||
error (tl::sprintf (tl::to_string (tr ("Expected two polygons on contacts interacting with one resistor shape (found %d) - resistor shape ignored")), int (contacts_per_res.count ())), *p);
|
||||
warn (tl::sprintf (tl::to_string (tr ("Expected two polygons on contacts interacting with one resistor shape (found %d) - resistor shape ignored")), int (contacts_per_res.count ())), *p);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -458,7 +458,7 @@ void NetlistDeviceExtractorResistor::extract_devices (const std::vector<db::Regi
|
|||
db::Coord width2 = eperp.length ();
|
||||
|
||||
if (width2 < 1) {
|
||||
error (tl::to_string (tr ("Invalid contact geometry - resistor shape ignored")), *p);
|
||||
warn (tl::to_string (tr ("Invalid contact geometry - resistor shape ignored")), *p);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -681,7 +681,7 @@ void NetlistDeviceExtractorBJT3Transistor::extract_devices (const std::vector<db
|
|||
db::Region remitter2base = rbase & remitters;
|
||||
|
||||
if (remitter2base.empty ()) {
|
||||
error (tl::to_string (tr ("Base shape without emitters - ignored")), *p);
|
||||
warn (tl::to_string (tr ("Base shape without emitters - ignored")), *p);
|
||||
} else {
|
||||
|
||||
// collectors inside base
|
||||
|
|
|
|||
|
|
@ -178,6 +178,8 @@ NetlistExtractor::extract_nets (const db::DeepShapeStore &dss, unsigned int layo
|
|||
m_device_annot_name_id = mp_layout->properties_repository ().get_id_of_name (db::NetlistDeviceExtractor::device_id_property_name ());
|
||||
|
||||
// build an attribute equivalence map which lists the "attribute IDs" which are identical in terms of net names
|
||||
// TODO: this feature is not really used as must-connect nets now are handled in the LayoutToNetlist class on netlist level.
|
||||
// Remove this later.
|
||||
|
||||
std::map<db::cell_index_type, tl::equivalence_clusters<size_t> > net_name_equivalence;
|
||||
if (m_text_annot_name_id.first) {
|
||||
|
|
|
|||
|
|
@ -106,6 +106,8 @@ public:
|
|||
* This is a glob expression rendering net names where partial nets with the
|
||||
* same name are joined even without explicit connection.
|
||||
* The cell-less version applies to top level cells only.
|
||||
* NOTE: this feature is not really used as must-connect nets are handled now in the LayoutToNetlist extractor.
|
||||
* Remove this function later.
|
||||
*/
|
||||
void set_joined_net_names (const std::list<tl::GlobPattern> &jnn);
|
||||
|
||||
|
|
@ -113,6 +115,8 @@ public:
|
|||
* @brief Sets the joined net names attribute for a given cell name
|
||||
* While the single-parameter set_joined_net_names only acts on the top cell, this
|
||||
* version will act on the cell with the given name.
|
||||
* NOTE: this feature is not really used as must-connect nets are handled now in the LayoutToNetlist extractor.
|
||||
* Remove this function later.
|
||||
*/
|
||||
void set_joined_net_names (const std::string &cell_name, const std::list<tl::GlobPattern> &jnn);
|
||||
|
||||
|
|
@ -122,11 +126,15 @@ public:
|
|||
* names that are to be connected. Multiple such groups can be specified. Each net name listed in a
|
||||
* group implies implicit joining of the corresponding labels into one net.
|
||||
* The cell-less version applies to top level cells only.
|
||||
* NOTE: this feature is not really used as must-connect nets are handled now in the LayoutToNetlist extractor.
|
||||
* Remove this function later.
|
||||
*/
|
||||
void set_joined_nets (const std::list<std::set<std::string> > &jnn);
|
||||
|
||||
/**
|
||||
* @brief Sets the joined nets attribute per cell
|
||||
* NOTE: this feature is not really used as must-connect nets are handled now in the LayoutToNetlist extractor.
|
||||
* Remove this function later.
|
||||
*/
|
||||
void set_joined_nets (const std::string &cell_name, const std::list<std::set<std::string> > &jnn);
|
||||
|
||||
|
|
|
|||
|
|
@ -530,6 +530,11 @@ Class<db::LayoutToNetlist> decl_dbLayoutToNetlist ("db", "LayoutToNetlist",
|
|||
"\n"
|
||||
"This method has been made parameter-less in version 0.27. Use \\include_floating_subcircuits= and \\join_net_names as substitutes for the arguments of previous versions."
|
||||
) +
|
||||
gsi::method ("check_extraction_errors", &db::LayoutToNetlist::check_extraction_errors,
|
||||
"@brief Raises an exception if extraction errors are present\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.28.13."
|
||||
) +
|
||||
gsi::method_ext ("internal_layout", &l2n_internal_layout,
|
||||
"@brief Gets the internal layout\n"
|
||||
"Usually it should not be required to obtain the internal layout. If you need to do so, make sure not to modify the layout as\n"
|
||||
|
|
|
|||
|
|
@ -157,6 +157,14 @@ Class<DeviceClassFactoryImpl> decl_dbDeviceClassFactoryBase ("db", "DeviceClassF
|
|||
);
|
||||
|
||||
Class<db::NetlistDeviceExtractorError> decl_dbNetlistDeviceExtractorError ("db", "NetlistDeviceExtractorError",
|
||||
gsi::method ("is_warning?|is_warning", &db::NetlistDeviceExtractorError::is_warning,
|
||||
"@brief Gets a value indicating whether the error is a warning.\n"
|
||||
"This predicate has been introduced in version 0.28.13."
|
||||
) +
|
||||
gsi::method ("warning=", &db::NetlistDeviceExtractorError::set_warning, gsi::arg ("flag"),
|
||||
"@brief Sets a value indicating whether the error is a warning.\n"
|
||||
"This predicate has been introduced in version 0.28.13."
|
||||
) +
|
||||
gsi::method ("message", &db::NetlistDeviceExtractorError::message,
|
||||
"@brief Gets the message text.\n"
|
||||
) +
|
||||
|
|
@ -199,8 +207,12 @@ Class<db::NetlistDeviceExtractorError> decl_dbNetlistDeviceExtractorError ("db",
|
|||
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."
|
||||
) +
|
||||
gsi::method ("to_s", &db::NetlistDeviceExtractorError::to_string,
|
||||
"@brief Gets the string representation of this error or warning.\n"
|
||||
"This method has been introduced in version 0.28.13."
|
||||
),
|
||||
"@brief An error that occurred during device extraction\n"
|
||||
"@brief An error or a warning that occurred during device extraction\n"
|
||||
"The device extractor will keep errors that occurred during extraction of the devices. "
|
||||
"It does not by using this error class.\n"
|
||||
"\n"
|
||||
|
|
@ -211,7 +223,7 @@ Class<db::NetlistDeviceExtractorError> decl_dbNetlistDeviceExtractorError ("db",
|
|||
"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."
|
||||
"This class has been introduced in version 0.26. Warning mode has been added in version 0.28.13."
|
||||
);
|
||||
|
||||
static const std::string &ld_name (const db::NetlistDeviceExtractorLayerDefinition *ld)
|
||||
|
|
@ -468,6 +480,36 @@ Class<GenericDeviceExtractor> decl_GenericDeviceExtractor (decl_dbNetlistDeviceE
|
|||
gsi::method ("error", (void (GenericDeviceExtractor::*) (const std::string &, const std::string &, const std::string &, const db::Polygon &)) &GenericDeviceExtractor::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 database-unit polygon geometry\n"
|
||||
) +
|
||||
gsi::method ("warn", (void (GenericDeviceExtractor::*) (const std::string &)) &GenericDeviceExtractor::warn,
|
||||
gsi::arg ("message"),
|
||||
"@brief Issues a warning with the given message\n"
|
||||
"Warnings have been introduced in version 0.28.13."
|
||||
) +
|
||||
gsi::method ("warn", (void (GenericDeviceExtractor::*) (const std::string &, const db::DPolygon &)) &GenericDeviceExtractor::warn,
|
||||
gsi::arg ("message"), gsi::arg ("geometry"),
|
||||
"@brief Issues a warning with the given message and micrometer-units polygon geometry\n"
|
||||
"Warnings have been introduced in version 0.28.13."
|
||||
) +
|
||||
gsi::method ("warn", (void (GenericDeviceExtractor::*) (const std::string &, const db::Polygon &)) &GenericDeviceExtractor::warn,
|
||||
gsi::arg ("message"), gsi::arg ("geometry"),
|
||||
"@brief Issues a warning with the given message and database-unit polygon geometry\n"
|
||||
"Warnings have been introduced in version 0.28.13."
|
||||
) +
|
||||
gsi::method ("warn", (void (GenericDeviceExtractor::*) (const std::string &, const std::string &, const std::string &)) &GenericDeviceExtractor::warn,
|
||||
gsi::arg ("category_name"), gsi::arg ("category_description"), gsi::arg ("message"),
|
||||
"@brief Issues a warning with the given category name and description, message\n"
|
||||
"Warnings have been introduced in version 0.28.13."
|
||||
) +
|
||||
gsi::method ("warn", (void (GenericDeviceExtractor::*) (const std::string &, const std::string &, const std::string &, const db::DPolygon &)) &GenericDeviceExtractor::warn,
|
||||
gsi::arg ("category_name"), gsi::arg ("category_description"), gsi::arg ("message"), gsi::arg ("geometry"),
|
||||
"@brief Issues a warning with the given category name and description, message and micrometer-units polygon geometry\n"
|
||||
"Warnings have been introduced in version 0.28.13."
|
||||
) +
|
||||
gsi::method ("warn", (void (GenericDeviceExtractor::*) (const std::string &, const std::string &, const std::string &, const db::Polygon &)) &GenericDeviceExtractor::warn,
|
||||
gsi::arg ("category_name"), gsi::arg ("category_description"), gsi::arg ("message"), gsi::arg ("geometry"),
|
||||
"@brief Issues a warning with the given category name and description, message and database-unit polygon geometry\n"
|
||||
"Warnings have been introduced in version 0.28.13."
|
||||
),
|
||||
"@brief The basic class for implementing custom device extractors.\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -2277,6 +2277,12 @@ CODE
|
|||
# @synopsis device_scaling(factor)
|
||||
# See \Netter#device_scaling for a description of that function.
|
||||
|
||||
# %DRC%
|
||||
# @name ignore_extraction_errors
|
||||
# @brief Specifies whether to ignore extraction errors
|
||||
# @synopsis ignore_extraction_errors(value)
|
||||
# See \Netter#ignore_extraction_errors for a description of that function.
|
||||
|
||||
# %DRC%
|
||||
# @name extract_devices
|
||||
# @brief Extracts devices for a given device extractor and device layer selection
|
||||
|
|
@ -2299,6 +2305,7 @@ CODE
|
|||
connect_implicit
|
||||
connect_explicit
|
||||
device_scaling
|
||||
ignore_extraction_errors
|
||||
extract_devices
|
||||
l2n_data
|
||||
netlist
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ module DRC
|
|||
@l2n = nil
|
||||
@lnum = 0
|
||||
@device_scaling = 1.0
|
||||
@ignore_extraction_errors = false
|
||||
end
|
||||
|
||||
# %DRC%
|
||||
|
|
@ -235,6 +236,18 @@ module DRC
|
|||
end
|
||||
end
|
||||
|
||||
# %DRC%
|
||||
# @name ignore_extraction_errors
|
||||
# @brief Specifies whether to ignore extraction errors
|
||||
# @synopsis ignore_extraction_errors(value)
|
||||
# With this value set to false (the default), "extract_netlist" will raise
|
||||
# an exception upon extraction errors. Otherwise, extraction errors will be logged
|
||||
# but no error is raised.
|
||||
|
||||
def ignore_extraction_errors(value)
|
||||
@ignore_extraction_errors = value
|
||||
end
|
||||
|
||||
# %DRC%
|
||||
# @name clear_connections
|
||||
# @brief Clears all connections stored so far
|
||||
|
|
@ -602,6 +615,11 @@ module DRC
|
|||
cfg.call(@l2n)
|
||||
end
|
||||
|
||||
# checks for errors if needed
|
||||
if !@ignore_extraction_errors
|
||||
@l2n.check_extraction_errors
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@l2n
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ metal2_lbl = input(8, 1)
|
|||
# Computed layers
|
||||
|
||||
pactive = active & nwell
|
||||
pgate = active & poly
|
||||
psd = active - pgate
|
||||
pgate = pactive & poly
|
||||
psd = pactive - pgate
|
||||
|
||||
nactive = active - nwell
|
||||
ngate = nactive & poly
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@
|
|||
* net 1 FB
|
||||
* net 2 OSC
|
||||
* net 3 NEXT
|
||||
* net 4 VSSZ,VSS
|
||||
* net 5 VDDZ,VDD
|
||||
* cell instance $1 r180 *1 -0.24,9.18
|
||||
X$1 16 1 2 4 5 INV2
|
||||
* cell instance $2 r0 *1 0,0
|
||||
X$2 1 14 15 4 5 INV2
|
||||
* net 4 VSSZ
|
||||
* net 5 VDDZ
|
||||
* cell instance $1 r0 *1 0,0
|
||||
X$1 1 14 15 4 5 INV2
|
||||
* cell instance $2 r180 *1 -0.24,9.18
|
||||
X$2 16 1 2 4 5 INV2
|
||||
* cell instance $3 r180 *1 10.32,9.18
|
||||
X$3 3 9 19 4 5 INV2
|
||||
* cell instance $4 r0 *1 10.56,0
|
||||
|
|
@ -46,18 +46,14 @@ X$2 2 5 1 TRANS
|
|||
X$3 5 3 2 TRANS
|
||||
* cell instance $4 m0 *1 0.4,0
|
||||
X$4 4 3 2 TRANS
|
||||
* device instance $1 -0.4,0 PMOS
|
||||
M$1 2 1 4 2 PMOS L=0.25U W=0.95U AS=0.49875P AD=0.26125P PS=2.95U PD=1.5U
|
||||
* device instance $2 0.4,0 PMOS
|
||||
M$2 4 2 3 4 PMOS L=0.25U W=0.95U AS=0.26125P AD=0.49875P PS=1.5U PD=2.95U
|
||||
* device instance $3 -0.4,2.8 PMOS
|
||||
M$3 2 1 5 2 PMOS L=0.25U W=0.95U AS=0.49875P AD=0.26125P PS=2.95U PD=1.5U
|
||||
* device instance $4 0.4,2.8 PMOS
|
||||
M$4 5 2 3 5 PMOS L=0.25U W=0.95U AS=0.26125P AD=0.49875P PS=1.5U PD=2.95U
|
||||
* device instance $5 -0.4,0 NMOS
|
||||
M$5 2 1 4 2 NMOS L=0.25U W=0.95U AS=0.49875P AD=0.26125P PS=2.95U PD=1.5U
|
||||
* device instance $6 0.4,0 NMOS
|
||||
M$6 4 2 3 4 NMOS L=0.25U W=0.95U AS=0.26125P AD=0.49875P PS=1.5U PD=2.95U
|
||||
* device instance $1 r0 *1 -0.4,2.8 PMOS
|
||||
M$1 5 1 2 2 PMOS L=0.25U W=0.95U AS=0.49875P AD=0.26125P PS=2.95U PD=1.5U
|
||||
* device instance $2 r0 *1 0.4,2.8 PMOS
|
||||
M$2 3 2 5 5 PMOS L=0.25U W=0.95U AS=0.26125P AD=0.49875P PS=1.5U PD=2.95U
|
||||
* device instance $3 r0 *1 -0.4,0 NMOS
|
||||
M$3 4 1 2 2 NMOS L=0.25U W=0.95U AS=0.49875P AD=0.26125P PS=2.95U PD=1.5U
|
||||
* device instance $4 r0 *1 0.4,0 NMOS
|
||||
M$4 3 2 4 4 NMOS L=0.25U W=0.95U AS=0.26125P AD=0.49875P PS=1.5U PD=2.95U
|
||||
.ENDS INV2
|
||||
|
||||
* cell TRANS
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -3,6 +3,8 @@ source($lvs_test_source)
|
|||
|
||||
report_lvs($lvs_test_target_lvsdb)
|
||||
|
||||
ignore_extraction_errors(true)
|
||||
|
||||
writer = write_spice(true, false)
|
||||
target_netlist($lvs_test_target_cir, writer, "Extracted by KLayout")
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ J(
|
|||
C(l2 l6 l2)
|
||||
C(l5 l6 l5)
|
||||
G(l14 SUBSTRATE)
|
||||
H(W B('Must-connect nets GND from circuit INVCHAIN must be connected further up in the hierarchy. This is an error at the chip top level.'))
|
||||
H(W B('Must-connect nets R from circuit INVCHAIN must be connected further up in the hierarchy. This is an error at the chip top level.'))
|
||||
H(E B('Must-connect nets R from circuit INV2 are not connected in INVCHAIN'))
|
||||
K(PMOS MOS3)
|
||||
K(NMOS MOS3)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ source($lvs_test_source)
|
|||
|
||||
report_lvs($lvs_test_target_lvsdb)
|
||||
|
||||
ignore_extraction_errors(true)
|
||||
|
||||
writer = write_spice(true, false)
|
||||
target_netlist($lvs_test_target_cir, writer, "Extracted by KLayout")
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ J(
|
|||
C(l2 l6 l2)
|
||||
C(l5 l6 l5)
|
||||
G(l14 SUBSTRATE)
|
||||
H(W B('Must-connect nets GND from circuit INVCHAIN must be connected further up in the hierarchy. This is an error at the chip top level.'))
|
||||
H(W B('Must-connect nets R from circuit INVCHAIN must be connected further up in the hierarchy. This is an error at the chip top level.'))
|
||||
H(E B('Must-connect nets R from circuit INV2 are not connected in INVCHAIN'))
|
||||
K(PMOS MOS3)
|
||||
K(NMOS MOS3)
|
||||
|
|
|
|||
|
|
@ -38,6 +38,9 @@ layout(
|
|||
global(l7 SUBSTRATE)
|
||||
global(l10 SUBSTRATE)
|
||||
|
||||
# Log entries
|
||||
message(warning description('Must-connect nets VDD from circuit RINGO must be connected further up in the hierarchy. This is an error at the chip top level.'))
|
||||
|
||||
# Device class section
|
||||
class(PMOS MOS4)
|
||||
class(NMOS MOS4)
|
||||
|
|
|
|||
|
|
@ -70,6 +70,9 @@ layout(
|
|||
global(l1 vss)
|
||||
global(l6 vss)
|
||||
|
||||
# Log entries
|
||||
message(warning description('Must-connect nets vdd from circuit SP6TArray_2X4 must be connected further up in the hierarchy. This is an error at the chip top level.'))
|
||||
|
||||
# Device class section
|
||||
class(active_res RES)
|
||||
class(poly_res RES)
|
||||
|
|
|
|||
|
|
@ -70,6 +70,9 @@ layout(
|
|||
global(l1 vss)
|
||||
global(l6 vss)
|
||||
|
||||
# Log entries
|
||||
message(warning description('Must-connect nets vdd from circuit SP6TArray_2X4 must be connected further up in the hierarchy. This is an error at the chip top level.'))
|
||||
|
||||
# Device class section
|
||||
class(active_res RES)
|
||||
class(poly_res RES)
|
||||
|
|
|
|||
|
|
@ -70,6 +70,9 @@ layout(
|
|||
global(l1 vss)
|
||||
global(l6 vss)
|
||||
|
||||
# Log entries
|
||||
message(warning description('Must-connect nets vdd from circuit SP6TArray_2X4 must be connected further up in the hierarchy. This is an error at the chip top level.'))
|
||||
|
||||
# Device class section
|
||||
class(active_res RES)
|
||||
class(poly_res RES)
|
||||
|
|
|
|||
|
|
@ -70,6 +70,9 @@ layout(
|
|||
global(l1 vss)
|
||||
global(l6 vss)
|
||||
|
||||
# Log entries
|
||||
message(warning description('Must-connect nets vdd from circuit SP6TArray_2X4 must be connected further up in the hierarchy. This is an error at the chip top level.'))
|
||||
|
||||
# Device class section
|
||||
class(active_res RES)
|
||||
class(poly_res RES)
|
||||
|
|
|
|||
|
|
@ -70,6 +70,9 @@ layout(
|
|||
global(l6 vss)
|
||||
global(l1 vss)
|
||||
|
||||
# Log entries
|
||||
message(warning description('Must-connect nets vdd from circuit SP6TArray_2X4 must be connected further up in the hierarchy. This is an error at the chip top level.'))
|
||||
|
||||
# Device class section
|
||||
class(active_res RES)
|
||||
class(poly_res RES)
|
||||
|
|
|
|||
|
|
@ -70,6 +70,9 @@ layout(
|
|||
global(l6 vss)
|
||||
global(l1 vss)
|
||||
|
||||
# Log entries
|
||||
message(warning description('Must-connect nets vdd from circuit SP6TArray_2X4 must be connected further up in the hierarchy. This is an error at the chip top level.'))
|
||||
|
||||
# Device class section
|
||||
class(active_res RES)
|
||||
class(poly_res RES)
|
||||
|
|
|
|||
|
|
@ -70,6 +70,9 @@ layout(
|
|||
global(l6 vss)
|
||||
global(l1 vss)
|
||||
|
||||
# Log entries
|
||||
message(warning description('Must-connect nets vdd from circuit SP6TArray_2X4 must be connected further up in the hierarchy. This is an error at the chip top level.'))
|
||||
|
||||
# Device class section
|
||||
class(active_res RES)
|
||||
class(poly_res RES)
|
||||
|
|
|
|||
|
|
@ -70,6 +70,9 @@ layout(
|
|||
global(l6 vss)
|
||||
global(l1 vss)
|
||||
|
||||
# Log entries
|
||||
message(warning description('Must-connect nets vdd from circuit SP6TArray_2X4 must be connected further up in the hierarchy. This is an error at the chip top level.'))
|
||||
|
||||
# Device class section
|
||||
class(active_res RES)
|
||||
class(poly_res RES)
|
||||
|
|
|
|||
|
|
@ -70,6 +70,9 @@ layout(
|
|||
global(l6 vss)
|
||||
global(l1 vss)
|
||||
|
||||
# Log entries
|
||||
message(warning description('Must-connect nets vdd from circuit SP6TArray_2X4 must be connected further up in the hierarchy. This is an error at the chip top level.'))
|
||||
|
||||
# Device class section
|
||||
class(active_res RES)
|
||||
class(poly_res RES)
|
||||
|
|
|
|||
|
|
@ -70,6 +70,9 @@ layout(
|
|||
global(l6 vss)
|
||||
global(l1 vss)
|
||||
|
||||
# Log entries
|
||||
message(warning description('Must-connect nets vdd from circuit SP6TArray_2X4 must be connected further up in the hierarchy. This is an error at the chip top level.'))
|
||||
|
||||
# Device class section
|
||||
class(active_res RES)
|
||||
class(poly_res RES)
|
||||
|
|
|
|||
Loading…
Reference in New Issue