This commit is contained in:
Matthias Koefferlein 2023-09-17 19:26:18 +02:00
parent c86a3aefe6
commit 7126375646
24 changed files with 347 additions and 153 deletions

View File

@ -50,6 +50,7 @@ SOURCES = \
dbLibraryManager.cc \
dbLibraryProxy.cc \
dbLoadLayoutOptions.cc \
dbLog.cc \
dbManager.cc \
dbMatrix.cc \
dbMemStatistics.cc \
@ -271,6 +272,7 @@ HEADERS = \
dbLibraryManager.h \
dbLibraryProxy.h \
dbLoadLayoutOptions.h \
dbLog.h \
dbManager.h \
dbMatrix.h \
dbMemStatistics.h \

View File

@ -33,6 +33,7 @@
#include "dbLayoutToNetlistFormatDefs.h"
#include "dbLayoutVsSchematicFormatDefs.h"
#include "dbShapeProcessor.h"
#include "dbLog.h"
#include "tlGlobPattern.h"
namespace db
@ -238,8 +239,16 @@ void LayoutToNetlist::extract_devices (db::NetlistDeviceExtractor &extractor, co
if (m_netlist_extracted) {
throw tl::Exception (tl::to_string (tr ("The netlist has already been extracted")));
}
ensure_netlist ();
extractor.clear_errors ();
extractor.extract (dss (), m_layout_index, layers, *mp_netlist, m_net_clusters, m_device_scaling);
// 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 ()));
}
}
void LayoutToNetlist::reset_extracted ()
@ -249,6 +258,8 @@ void LayoutToNetlist::reset_extracted ()
m_net_clusters.clear ();
mp_netlist.reset (0);
m_log_entries.clear ();
m_netlist_extracted = false;
}
@ -362,6 +373,7 @@ void LayoutToNetlist::extract_netlist ()
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;
@ -397,10 +409,13 @@ void LayoutToNetlist::extract_netlist ()
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);
// @@@ join_nets ();
if (tl::verbosity () >= 41) {
MemStatisticsCollector m (false);
mem_stat (&m, db::MemStatistics::None, 0);

View File

@ -28,6 +28,7 @@
#include "dbNetlistExtractor.h"
#include "dbNetlistDeviceExtractor.h"
#include "dbLayoutToNetlistEnums.h"
#include "dbLog.h"
#include "tlGlobPattern.h"
namespace db
@ -78,6 +79,7 @@ class DB_PUBLIC LayoutToNetlist
{
public:
typedef std::map<unsigned int, std::string>::const_iterator layer_iterator;
typedef std::vector<db::LogEntryData> log_entries_type;
/**
* @brief The constructor
@ -190,6 +192,33 @@ public:
m_filename = filename;
}
/**
* @brief Gets the log entries
* @@@ TODO: provide GSI interface
*/
const log_entries_type &log_entries () const
{
return m_log_entries;
}
/**
* @brief Clears the log entries
* @@@ TODO: provide GSI interface
*/
void clear_log_entries ()
{
m_log_entries.clear ();
}
/**
* @brief Adds a log entry
* @@@ TODO: provide GSI interface
*/
void log_entry (const db::LogEntryData &log_entry)
{
m_log_entries.push_back (log_entry);
}
/**
* @brief Sets the number of threads to use for operations which support multiple threads
*/
@ -388,7 +417,7 @@ public:
* @brief Resets the extracted netlist
*
* This method will invalidate the netlist and extraction. It is called automatically when
* cone of the connect methods is called.
* one of the connect methods is called.
*/
void reset_extracted ();
@ -930,6 +959,7 @@ private:
std::string m_name;
std::string m_original_file;
std::string m_filename;
log_entries_type m_log_entries;
db::RecursiveShapeIterator m_iter;
std::unique_ptr<db::DeepShapeStore> mp_internal_dss;
tl::weak_ptr<db::DeepShapeStore> mp_dss;

View File

@ -56,8 +56,13 @@ namespace l2n_std_format
DB_PUBLIC std::string LongKeys::mirror_key ("mirror");
DB_PUBLIC std::string LongKeys::scale_key ("scale");
DB_PUBLIC std::string LongKeys::pin_key ("pin");
DB_PUBLIC std::string LongKeys::message_key ("message");
// A, B, C, D, E, F, G, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y
DB_PUBLIC std::string LongKeys::info_severity_key ("info");
DB_PUBLIC std::string LongKeys::warning_severity_key ("warning");
DB_PUBLIC std::string LongKeys::error_severity_key ("error");
// A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y
DB_PUBLIC std::string ShortKeys::version_key ("V");
DB_PUBLIC std::string ShortKeys::description_key ("B");
DB_PUBLIC std::string ShortKeys::top_key ("W");
@ -82,6 +87,13 @@ namespace l2n_std_format
DB_PUBLIC std::string ShortKeys::mirror_key ("M");
DB_PUBLIC std::string ShortKeys::scale_key ("S");
DB_PUBLIC std::string ShortKeys::pin_key ("P");
DB_PUBLIC std::string ShortKeys::message_key ("H");
// I, W, E
DB_PUBLIC std::string ShortKeys::info_severity_key ("I");
DB_PUBLIC std::string ShortKeys::warning_severity_key ("W");
DB_PUBLIC std::string ShortKeys::error_severity_key ("E");
}
}

View File

@ -47,7 +47,7 @@ namespace db
* (circuits before subcircuits, nets before use ...)
*
* Main body:
* [version|description|unit|top|layer|connect|global|circuit|class|device|any]*
* [version|description|unit|top|layer|connect|global|circuit|class|device|message-entry|any]*
*
* [version]:
* version(<number>) - file format version [short key: V]
@ -181,6 +181,17 @@ namespace db
* mirror - if specified, the instance is mirrored before rotation [short key: M]
* scale(<mag>) - magnification (default is 1) [short key: S]
*
* [message-entry]:
* message([severity] [message|any]*) - message entry [short key: H]
*
* [message]:
* description(<name>) - error description [short key: B]
*
* [severity]:
* info | - [short key: I]
* warning | - [short key: W]
* error - [short key: E]
*
* [any]:
* * |
* <token> |
@ -220,8 +231,12 @@ namespace l2n_std_format
static std::string mirror_key;
static std::string scale_key;
static std::string pin_key;
static std::string message_key;
static std::string indent1;
static std::string indent2;
static std::string info_severity_key;
static std::string warning_severity_key;
static std::string error_severity_key;
};
struct DB_PUBLIC LongKeys
@ -253,8 +268,12 @@ namespace l2n_std_format
static std::string mirror_key;
static std::string scale_key;
static std::string pin_key;
static std::string message_key;
static std::string indent1;
static std::string indent2;
static std::string info_severity_key;
static std::string warning_severity_key;
static std::string error_severity_key;
};
template <bool Short> struct DB_PUBLIC keys;

View File

@ -184,6 +184,52 @@ void LayoutToNetlistStandardReader::skip_element ()
}
}
bool LayoutToNetlistStandardReader::read_message (std::string &msg)
{
if (test (skeys::description_key) || test (lkeys::description_key)) {
Brace br (this);
read_word_or_quoted (msg);
br.done ();
return true;
} else {
return false;
}
}
bool LayoutToNetlistStandardReader::read_severity (db::Severity &severity)
{
if (test (skeys::info_severity_key) || test (lkeys::info_severity_key)) {
severity = db::Info;
return true;
} else if (test (skeys::warning_severity_key) || test (lkeys::warning_severity_key)) {
severity = db::Warning;
return true;
} else if (test (skeys::error_severity_key) || test (lkeys::error_severity_key)) {
severity = db::Error;
return true;
} else {
return false;
}
}
void LayoutToNetlistStandardReader::read_message_entry (db::LogEntryData &data)
{
data.severity = db::NoSeverity;
data.msg.clear ();
Brace br (this);
while (br) {
if (read_severity (data.severity)) {
// continue
} else if (read_message (data.msg)) {
// continue
} else {
skip_element ();
}
}
br.done ();
}
void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n)
{
tl::SelfTimer timer (tl::verbosity () >= 21, tl::to_string (tr ("File read: ")) + m_path);
@ -359,6 +405,13 @@ void LayoutToNetlistStandardReader::read_netlist (db::Netlist *netlist, db::Layo
}
br.done ();
} else if (l2n && (test (skeys::message_key) || test (lkeys::message_key))) {
db::LogEntryData data;
read_message_entry (data);
l2n->log_entry (data);
} else if (l2n && (test (skeys::global_key) || test (lkeys::global_key))) {
Brace br (this);

View File

@ -109,6 +109,8 @@ protected:
void read_netlist (Netlist *netlist, db::LayoutToNetlist *l2n, Brace *nested = 0, std::map<const db::Circuit *, ObjectMap> *map_per_circuit = 0);
static size_t terminal_id (const db::DeviceClass *device_class, const std::string &tname);
static std::pair<db::DeviceAbstract *, const db::DeviceClass *> device_model_by_name (db::Netlist *netlist, const std::string &dmname);
bool read_message (std::string &msg);
bool read_severity (Severity &severity);
const std::string &path () const
{
@ -140,6 +142,15 @@ protected:
void skip ();
void skip_element ();
private:
tl::TextInputStream m_stream;
std::string m_path;
std::string m_line;
double m_dbu;
tl::Extractor m_ex;
db::Point m_ref;
tl::AbsoluteProgress m_progress;
void read_net (Netlist *netlist, db::LayoutToNetlist *l2n, db::Circuit *circuit, ObjectMap &map);
void read_pin (Netlist *netlist, db::LayoutToNetlist *l2n, db::Circuit *circuit, ObjectMap &map);
void read_device (Netlist *netlist, db::LayoutToNetlist *l2n, db::Circuit *circuit, ObjectMap &map, std::map<db::CellInstArray, std::list<Connections> > &connections);
@ -151,15 +162,7 @@ protected:
db::Box read_rect ();
void read_geometries (db::NetlistObject *obj, Brace &br, db::LayoutToNetlist *l2n, db::local_cluster<NetShape> &lc, db::Cell &cell);
db::Point read_point ();
private:
tl::TextInputStream m_stream;
std::string m_path;
std::string m_line;
double m_dbu;
tl::Extractor m_ex;
db::Point m_ref;
tl::AbsoluteProgress m_progress;
void read_message_entry (db::LogEntryData &data);
};
}

View File

@ -142,6 +142,30 @@ std_writer_impl<Keys>::std_writer_impl (tl::OutputStream &stream, double dbu, co
m_progress.set_unit (1024 * 1024);
}
template <class Keys>
std::string std_writer_impl<Keys>::message_to_s (const std::string &msg)
{
if (msg.empty ()) {
return std::string ();
} else {
return Keys::description_key + "(" + tl::to_word_or_quoted_string (msg) + ")";
}
}
template <class Keys>
std::string std_writer_impl<Keys>::severity_to_s (const db::Severity severity)
{
if (severity == db::Info) {
return Keys::info_severity_key;
} else if (severity == db::Warning) {
return Keys::warning_severity_key;
} else if (severity == db::Error) {
return Keys::error_severity_key;
} else {
return std::string ();
}
}
static std::string name_for_layer (const db::LayoutToNetlist *l2n, unsigned int l)
{
std::string n = l2n->name (l);
@ -318,6 +342,16 @@ void std_writer_impl<Keys>::write (bool nested, TokenizedOutput &stream, std::ma
}
if (! mp_l2n->log_entries ().empty ()) {
if (! Keys::is_short ()) {
stream << endl << "# Log entries" << endl;
}
for (auto l = mp_l2n->log_entries ().begin (); l != mp_l2n->log_entries ().end (); ++l) {
TokenizedOutput (stream, Keys::message_key) << severity_to_s (l->severity) << message_to_s (l->msg);
m_progress.set (mp_stream->pos ());
}
}
}
if (mp_netlist->begin_device_classes () != mp_netlist->end_device_classes () && ! Keys::is_short ()) {

View File

@ -28,6 +28,7 @@
#include "dbTrans.h"
#include "dbPolygon.h"
#include "dbHierNetworkProcessor.h"
#include "dbLog.h"
#include "tlStream.h"
#include "tlProgress.h"
@ -92,6 +93,9 @@ protected:
return *mp_stream;
}
std::string severity_to_s (const db::Severity severity);
std::string message_to_s (const std::string &msg);
private:
tl::OutputStream *mp_stream;
db::Point m_ref;

View File

@ -43,11 +43,7 @@ namespace lvs_std_format
DB_PUBLIC std::string LongKeys::warning_key ("warning");
DB_PUBLIC std::string LongKeys::skipped_key ("skipped");
DB_PUBLIC std::string LongKeys::info_severity_key ("info");
DB_PUBLIC std::string LongKeys::warning_severity_key ("warning");
DB_PUBLIC std::string LongKeys::error_severity_key ("error");
// E, H, I, J, L, M, S, W, X, Z, 0, 1
// H, J, L, M, S, X, Z, 0, 1
DB_PUBLIC std::string ShortKeys::reference_key ("H");
DB_PUBLIC std::string ShortKeys::layout_key ("J");
@ -60,10 +56,6 @@ namespace lvs_std_format
DB_PUBLIC std::string ShortKeys::nomatch_key ("X");
DB_PUBLIC std::string ShortKeys::warning_key ("W");
DB_PUBLIC std::string ShortKeys::skipped_key ("S");
DB_PUBLIC std::string ShortKeys::info_severity_key ("I");
DB_PUBLIC std::string ShortKeys::warning_severity_key ("W");
DB_PUBLIC std::string ShortKeys::error_severity_key ("E");
}
}

View File

@ -67,7 +67,7 @@ namespace db
* Content is the Netlist dump (reduced version of LayoutToNetlist)
*
* [xrefs]:
* xref([xref|any]*) - cross-reference part [short key: Z]
* xref([xref|log|any]*) - cross-reference part [short key: Z]
*
* [xref]:
* circuit([non] [non] [status|message|log|circuit-xrefs|any]*)
@ -82,11 +82,6 @@ namespace db
* [log-entry]:
* entry([severity] [message|any]*) - log entry [short key: M]
*
* [severity]:
* info | - [short key: I]
* warning | - [short key: W]
* error - [short key: E]
*
* [circuit-xrefs]:
* xref([xref-pin|xref-device|xref-circuit|xref-net|any]*)
* - circuit cross-reference part [short key: Z]
@ -113,6 +108,11 @@ namespace db
* [message]:
* description(<name>) - error description [short key: B]
*
* [severity]:
* info | - [short key: I]
* warning | - [short key: W]
* error - [short key: E]
*
* [status]:
* mismatch | - [short key: 0]
* match | - [short key: 1]
@ -145,10 +145,6 @@ namespace lvs_std_format
static std::string nomatch_key;
static std::string warning_key;
static std::string skipped_key;
static std::string info_severity_key;
static std::string warning_severity_key;
static std::string error_severity_key;
};
struct DB_PUBLIC LongKeys
@ -166,10 +162,6 @@ namespace lvs_std_format
static std::string nomatch_key;
static std::string warning_key;
static std::string skipped_key;
static std::string info_severity_key;
static std::string warning_severity_key;
static std::string error_severity_key;
};
template <bool Short> struct DB_PUBLIC keys;

View File

@ -116,18 +116,6 @@ void LayoutVsSchematicStandardReader::read_netlist (db::LayoutVsSchematic *lvs)
}
}
bool LayoutVsSchematicStandardReader::read_message (std::string &msg)
{
if (test (skeys::description_key) || test (lkeys::description_key)) {
Brace br (this);
read_word_or_quoted (msg);
br.done ();
return true;
} else {
return false;
}
}
bool LayoutVsSchematicStandardReader::read_status (db::NetlistCrossReference::Status &status)
{
if (test (skeys::match_key) || test (lkeys::match_key)) {
@ -150,25 +138,9 @@ bool LayoutVsSchematicStandardReader::read_status (db::NetlistCrossReference::St
}
}
bool LayoutVsSchematicStandardReader::read_severity (db::NetlistCrossReference::Severity &severity)
{
if (test (skeys::info_severity_key) || test (lkeys::info_severity_key)) {
severity = db::NetlistCrossReference::Info;
return true;
} else if (test (skeys::warning_severity_key) || test (lkeys::warning_severity_key)) {
severity = db::NetlistCrossReference::Warning;
return true;
} else if (test (skeys::error_severity_key) || test (lkeys::error_severity_key)) {
severity = db::NetlistCrossReference::Error;
return true;
} else {
return false;
}
}
void LayoutVsSchematicStandardReader::read_log_entry (db::NetlistCrossReference *xref)
{
db::NetlistCrossReference::Severity severity = db::NetlistCrossReference::NoSeverity;
db::Severity severity = db::NoSeverity;
std::string msg;
Brace br (this);
@ -186,7 +158,7 @@ void LayoutVsSchematicStandardReader::read_log_entry (db::NetlistCrossReference
xref->log_entry (severity, msg);
}
void LayoutVsSchematicStandardReader::read_logs_for_circuits (db::NetlistCrossReference *xref)
void LayoutVsSchematicStandardReader::read_logs (db::NetlistCrossReference *xref)
{
Brace br (this);
while (br) {
@ -194,7 +166,7 @@ void LayoutVsSchematicStandardReader::read_logs_for_circuits (db::NetlistCrossRe
if (test (skeys::log_entry_key) || test (lkeys::log_entry_key)) {
read_log_entry (xref);
} else if (at_end ()) {
throw tl::Exception (tl::to_string (tr ("Unexpected end of file inside circuit definition (net, pin, device or circuit expected)")));
throw tl::Exception (tl::to_string (tr ("Unexpected end of file inside log section (entry expected)")));
} else {
skip_element ();
}
@ -269,7 +241,7 @@ void LayoutVsSchematicStandardReader::read_xref (db::NetlistCrossReference *xref
} else if (test (skeys::xref_key) || test (lkeys::xref_key)) {
read_xrefs_for_circuits (xref, circuit_a, circuit_b);
} else if (test (skeys::log_key) || test (lkeys::log_key)) {
read_logs_for_circuits (xref);
read_logs (xref);
} else if (at_end ()) {
throw tl::Exception (tl::to_string (tr ("Unexpected end of file inside circuit definition (status keyword of xrefs expected)")));
} else {
@ -282,6 +254,8 @@ void LayoutVsSchematicStandardReader::read_xref (db::NetlistCrossReference *xref
br.done ();
} else if (test (skeys::log_key) || test (lkeys::log_key)) {
read_logs (xref);
} else {
skip_element ();
}

View File

@ -28,6 +28,7 @@
#include "dbCell.h"
#include "dbLayoutVsSchematic.h"
#include "dbLayoutToNetlistReader.h"
#include "dbLog.h"
#include "tlStream.h"
namespace db {
@ -78,10 +79,8 @@ private:
void read_netlist (db::LayoutVsSchematic *lvs);
bool read_status (db::NetlistCrossReference::Status &status);
bool read_message (std::string &msg);
void read_log_entry (db::NetlistCrossReference *xref);
void read_logs_for_circuits (db::NetlistCrossReference *xref);
bool read_severity (db::NetlistCrossReference::Severity &severity);
void read_logs (db::NetlistCrossReference *xref);
void read_xref (db::NetlistCrossReference *xref);
void read_xrefs_for_circuits (db::NetlistCrossReference *xref, const db::Circuit *circuit_a, const db::Circuit *circuit_b);
void read_net_pair (db::NetlistCrossReference *xref, const db::Circuit *circuit_a, const db::Circuit *circuit_b);

View File

@ -72,8 +72,6 @@ private:
}
std::string status_to_s (const db::NetlistCrossReference::Status status);
std::string severity_to_s (const db::NetlistCrossReference::Severity severity);
std::string message_to_s (const std::string &msg);
void write (TokenizedOutput &stream, const db::NetlistCrossReference *xref);
std::map<const db::Circuit *, std::map<const db::Net *, unsigned int> > m_net2id_per_circuit_a, m_net2id_per_circuit_b;
@ -178,16 +176,6 @@ static std::string pin_id_to_s (const db::Pin *pin, const std::map<const db::Pin
}
}
template <class Keys>
std::string std_writer_impl<Keys>::message_to_s (const std::string &msg)
{
if (msg.empty ()) {
return std::string ();
} else {
return Keys::description_key + "(" + tl::to_word_or_quoted_string (msg) + ")";
}
}
template <class Keys>
std::string std_writer_impl<Keys>::status_to_s (const db::NetlistCrossReference::Status status)
{
@ -206,30 +194,28 @@ std::string std_writer_impl<Keys>::status_to_s (const db::NetlistCrossReference:
}
}
template <class Keys>
std::string std_writer_impl<Keys>::severity_to_s (const db::NetlistCrossReference::Severity severity)
{
if (severity == db::NetlistCrossReference::Info) {
return Keys::info_severity_key;
} else if (severity == db::NetlistCrossReference::Warning) {
return Keys::warning_severity_key;
} else if (severity == db::NetlistCrossReference::Error) {
return Keys::error_severity_key;
} else {
return std::string ();
}
}
template <class Keys>
void std_writer_impl<Keys>::write (TokenizedOutput &stream, const db::NetlistCrossReference *xref)
{
for (db::NetlistCrossReference::circuits_iterator c = xref->begin_circuits (); c != xref->end_circuits (); ++c) {
if (! xref->other_log_entries ().empty ()) {
TokenizedOutput o (stream, Keys::log_key);
o << endl;
for (auto l = xref->other_log_entries ().begin (); l != xref->other_log_entries ().end (); ++l) {
TokenizedOutput (o, Keys::log_entry_key, true) << this->severity_to_s (l->severity) << this->message_to_s (l->msg);
o << endl;
}
}
for (auto c = xref->begin_circuits (); c != xref->end_circuits (); ++c) {
const db::NetlistCrossReference::PerCircuitData *pcd = xref->per_circuit_data_for (*c);
tl_assert (pcd != 0);
TokenizedOutput out (stream, Keys::circuit_key);
out << name_to_s (c->first) << name_to_s (c->second) << status_to_s (pcd->status) << message_to_s (pcd->msg);
out << name_to_s (c->first) << name_to_s (c->second) << status_to_s (pcd->status) << this->message_to_s (pcd->msg);
out << endl;
if (! pcd->log_entries.empty ()) {
@ -237,8 +223,8 @@ void std_writer_impl<Keys>::write (TokenizedOutput &stream, const db::NetlistCro
TokenizedOutput o (out, Keys::log_key);
o << endl;
for (db::NetlistCrossReference::PerCircuitData::log_entries_const_iterator l = pcd->log_entries.begin (); l != pcd->log_entries.end (); ++l) {
TokenizedOutput (o, Keys::log_entry_key, true) << severity_to_s (l->severity) << message_to_s (l->msg);
for (auto l = pcd->log_entries.begin (); l != pcd->log_entries.end (); ++l) {
TokenizedOutput (o, Keys::log_entry_key, true) << this->severity_to_s (l->severity) << this->message_to_s (l->msg);
o << endl;
}
@ -249,7 +235,7 @@ void std_writer_impl<Keys>::write (TokenizedOutput &stream, const db::NetlistCro
o << endl;
for (db::NetlistCrossReference::PerCircuitData::net_pairs_const_iterator n = pcd->nets.begin (); n != pcd->nets.end (); ++n) {
TokenizedOutput (o, Keys::net_key) << net_id_to_s (n->pair.first, m_net2id_per_circuit_a [c->first]) << net_id_to_s (n->pair.second, m_net2id_per_circuit_b [c->second]) << status_to_s (n->status) << message_to_s (n->msg);
TokenizedOutput (o, Keys::net_key) << net_id_to_s (n->pair.first, m_net2id_per_circuit_a [c->first]) << net_id_to_s (n->pair.second, m_net2id_per_circuit_b [c->second]) << status_to_s (n->status) << this->message_to_s (n->msg);
}
std::map<const db::Pin *, unsigned int> pin2index_a, pin2index_b;
@ -257,15 +243,15 @@ void std_writer_impl<Keys>::write (TokenizedOutput &stream, const db::NetlistCro
build_pin_index_map (c->second, pin2index_b);
for (db::NetlistCrossReference::PerCircuitData::pin_pairs_const_iterator n = pcd->pins.begin (); n != pcd->pins.end (); ++n) {
TokenizedOutput (o, Keys::pin_key) << pin_id_to_s (n->pair.first, pin2index_a) << pin_id_to_s (n->pair.second, pin2index_b) << status_to_s (n->status) << message_to_s (n->msg);
TokenizedOutput (o, Keys::pin_key) << pin_id_to_s (n->pair.first, pin2index_a) << pin_id_to_s (n->pair.second, pin2index_b) << status_to_s (n->status) << this->message_to_s (n->msg);
}
for (db::NetlistCrossReference::PerCircuitData::device_pairs_const_iterator n = pcd->devices.begin (); n != pcd->devices.end (); ++n) {
TokenizedOutput (o, Keys::device_key) << ion_to_s (n->pair.first) << ion_to_s (n->pair.second) << status_to_s (n->status) << message_to_s (n->msg);
TokenizedOutput (o, Keys::device_key) << ion_to_s (n->pair.first) << ion_to_s (n->pair.second) << status_to_s (n->status) << this->message_to_s (n->msg);
}
for (db::NetlistCrossReference::PerCircuitData::subcircuit_pairs_const_iterator n = pcd->subcircuits.begin (); n != pcd->subcircuits.end (); ++n) {
TokenizedOutput (o, Keys::circuit_key) << ion_to_s (n->pair.first) << ion_to_s (n->pair.second) << status_to_s (n->status) << message_to_s (n->msg);
TokenizedOutput (o, Keys::circuit_key) << ion_to_s (n->pair.first) << ion_to_s (n->pair.second) << status_to_s (n->status) << this->message_to_s (n->msg);
}
}

31
src/db/db/dbLog.cc Normal file
View File

@ -0,0 +1,31 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2023 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 "dbCommon.h"
#include "dbLog.h"
namespace db
{
// .. nothing yet ..
}

57
src/db/db/dbLog.h Normal file
View File

@ -0,0 +1,57 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2023 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
*/
#ifndef _HDR_dbLog
#define _HDR_dbLog
#include "dbCommon.h"
#include <string>
namespace db
{
/**
* @brief An enum describing the severity for a log entry
*/
enum Severity {
NoSeverity = 0, // unspecific
Info = 1, // information only
Warning = 2, // a warning
Error = 3 // an error
};
/**
* @brief A class representing one log entry
*/
struct LogEntryData
{
LogEntryData (Severity s, const std::string &m) : severity (s), msg (m) { }
LogEntryData () : severity (NoSeverity) { }
Severity severity;
std::string msg;
};
}
#endif

View File

@ -385,7 +385,7 @@ NetlistComparer::compare_impl (const db::Netlist *a, const db::Netlist *b) const
std::string msg = generate_subcircuits_not_verified_warning (ca, verified_circuits_a, cb, verified_circuits_b);
if (m_with_log) {
mp_logger->log_entry (db::NetlistCompareLogger::Error, msg);
mp_logger->log_entry (db::Error, msg);
}
mp_logger->circuit_skipped (ca, cb, msg);
@ -899,7 +899,7 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
if (mp_logger) {
if (p->second && ! exact_match) {
if (m_with_log) {
mp_logger->log_entry (db::NetlistCompareLogger::Error,
mp_logger->log_entry (db::Error,
tl::sprintf (tl::to_string (tr ("Nets %s are paired explicitly, but are not identical topologically")), nets2string (p->first)));
}
mp_logger->net_mismatch (p->first.first, p->first.second);
@ -1145,12 +1145,12 @@ static void
analyze_pin_mismatch (const db::Pin *pin1, const db::Circuit *c1, const db::Pin *pin2, const db::Circuit * /*c2*/, db::NetlistCompareLogger *logger)
{
if (! pin1) {
logger->log_entry (db::NetlistCompareLogger::Error, tl::sprintf (tl::to_string (tr ("No equivalent pin %s from reference netlist found in netlist.\nThis is an indication that a physical connection is not made to the subcircuit.")), pin2->expanded_name ()));
logger->log_entry (db::Error, tl::sprintf (tl::to_string (tr ("No equivalent pin %s from reference netlist found in netlist.\nThis is an indication that a physical connection is not made to the subcircuit.")), pin2->expanded_name ()));
}
if (! pin2) {
logger->log_entry (db::NetlistCompareLogger::Error, tl::sprintf (tl::to_string (tr ("No equivalent pin %s from netlist found in reference netlist.\nThis is an indication that additional physical connections are made to the subcircuit cell.")), pin1->expanded_name ()));
logger->log_entry (db::Error, tl::sprintf (tl::to_string (tr ("No equivalent pin %s from netlist found in reference netlist.\nThis is an indication that additional physical connections are made to the subcircuit cell.")), pin1->expanded_name ()));
// attempt to identify pins which are creating invalid connections
for (auto p = c1->begin_parents (); p != c1->end_parents (); ++p) {
@ -1159,7 +1159,7 @@ analyze_pin_mismatch (const db::Pin *pin1, const db::Circuit *c1, const db::Pin
if (sc.circuit_ref () == c1) {
const db::Net *net = sc.net_for_pin (pin1->id ());
if (net && (net->subcircuit_pin_count () > 1 || net->terminal_count () > 0 || net->pin_count () > 0)) {
logger->log_entry (db::NetlistCompareLogger::Info, tl::sprintf (tl::to_string (tr ("Potential invalid connection in circuit %s, subcircuit cell reference at %s")), p->name (), sc.trans ().to_string ()));
logger->log_entry (db::Info, tl::sprintf (tl::to_string (tr ("Potential invalid connection in circuit %s, subcircuit cell reference at %s")), p->name (), sc.trans ().to_string ()));
}
}
}

View File

@ -25,6 +25,7 @@
#include "dbCommon.h"
#include "dbNetlist.h"
#include "dbLog.h"
#include <set>
#include <map>
@ -50,16 +51,6 @@ public:
NetlistCompareLogger () { }
virtual ~NetlistCompareLogger () { }
/**
* @brief An enum describing the severity for the log_entry function
*/
enum Severity {
NoSeverity = 0, // unspecific
Info = 1, // information only
Warning = 2, // a warning
Error = 3 // an error
};
/**
* @brief Begin logging for netlist a and b
*/
@ -101,7 +92,7 @@ public:
/**
* @brief Receives log entries for the current circuit pair
*/
virtual void log_entry (Severity /*level*/, const std::string & /*msg*/) { }
virtual void log_entry (db::Severity /*level*/, const std::string & /*msg*/) { }
/**
* @brief Nets a and b match exactly

View File

@ -1052,7 +1052,7 @@ NetlistCompareCore::derive_node_identities_from_ambiguity_group (const NodeRange
if (ambiguous) {
if (logger) {
if (with_log) {
logger->log_entry (db::NetlistCompareLogger::Warning,
logger->log_entry (db::Warning,
tl::sprintf (tl::to_string (tr ("Matching nets %s from an ambiguous group of nets")), nets2string (p->first->net (), p->second->net ())));
}
logger->match_ambiguous_nets (p->first->net (), p->second->net ());
@ -1116,7 +1116,7 @@ NetlistCompareCore::derive_node_identities_from_ambiguity_group (const NodeRange
}
if (logger && with_log && was_ambiguous) {
logger->log_entry (db::NetlistCompareLogger::Info,
logger->log_entry (db::Info,
tl::sprintf (tl::to_string (tr ("Matching nets %s following an ambiguous match")), nets2string (n->net (), n_other->net ())));
}
@ -1397,7 +1397,7 @@ analyze_nodes_for_close_matches (const std::multimap<size_t, const NetGraphNode
double fuzz_factor = double (fuzz) / ne;
if (fuzz_factor < max_fuzz_factor) {
std::string msg = tl::to_string (tr ("Net %s from netlist approximately matches net %s from reference netlist (fuzziness %d nodes)"));
logger->log_entry (db::NetlistCompareLogger::Info, tl::sprintf (msg,
logger->log_entry (db::Info, tl::sprintf (msg,
i->second->net ()->expanded_name (),
j->second->net ()->expanded_name (),
int (fuzz)));
@ -1417,7 +1417,7 @@ analyze_nodes_for_close_matches (const std::multimap<size_t, const NetGraphNode
size_t fuzz = distance3 (*i->second, *j->second, *k->second, g2);
double fuzz_factor = double (fuzz) / i->first;
if (fuzz_factor < max_fuzz_factor) {
logger->log_entry (db::NetlistCompareLogger::Info, tl::sprintf (msg,
logger->log_entry (db::Info, tl::sprintf (msg,
(layout2ref ? i : j)->second->net ()->expanded_name (),
(layout2ref ? j : k)->second->net ()->expanded_name (),
(layout2ref ? k : i)->second->net ()->expanded_name (),
@ -1493,7 +1493,7 @@ NetlistCompareCore::analyze_failed_matches () const
}
for (auto i = singular1.begin (); i != singular1.end (); ++i) {
logger->log_entry (db::NetlistCompareLogger::Error, tl::sprintf (tl::to_string (tr ("Net %s is not matching any net from reference netlist")), (*i)->net ()->expanded_name ()));
logger->log_entry (db::Error, tl::sprintf (tl::to_string (tr ("Net %s is not matching any net from reference netlist")), (*i)->net ()->expanded_name ()));
}
// attempt some analysis for close matches (including shorts / opens)
@ -1552,7 +1552,7 @@ NetlistCompareCore::derive_node_identities_from_node_set (std::vector<NodeEdgePa
if (max_depth != std::numeric_limits<size_t>::max() && depth > max_depth) {
if (with_log) {
logger->log_entry (db::NetlistCompareLogger::Warning, tl::sprintf (tl::to_string (tr ("Maximum depth exhausted (max depth is %d)")), int (max_depth)));
logger->log_entry (db::Warning, tl::sprintf (tl::to_string (tr ("Maximum depth exhausted (max depth is %d)")), int (max_depth)));
}
if (db::NetlistCompareGlobalOptions::options ()->debug_netcompare) {
tl::info << indent_s << "max. depth exhausted (" << depth << ">" << max_depth << ")";
@ -1670,7 +1670,7 @@ NetlistCompareCore::derive_node_identities_from_node_set (std::vector<NodeEdgePa
} else if (max_n_branch != std::numeric_limits<size_t>::max () && double (std::max (nr->num1, nr->num2)) * double (n_branch) > double (max_n_branch)) {
if (with_log) {
logger->log_entry (db::NetlistCompareLogger::Warning, tl::sprintf (tl::to_string (tr ("Maximum complexity exhausted (max complexity is %s, needs at least %s)")), tl::to_string (max_n_branch), tl::to_string (std::max (nr->num1, nr->num2) * n_branch)));
logger->log_entry (db::Warning, tl::sprintf (tl::to_string (tr ("Maximum complexity exhausted (max complexity is %s, needs at least %s)")), tl::to_string (max_n_branch), tl::to_string (std::max (nr->num1, nr->num2) * n_branch)));
}
if (db::NetlistCompareGlobalOptions::options ()->debug_netcompare) {
tl::info << indent_s << "max. complexity exhausted (" << std::max (nr->num1, nr->num2) << "*" << n_branch << ">" << max_n_branch << ") - mismatch.";

View File

@ -105,15 +105,6 @@ public:
std::string msg;
};
struct LogEntryData
{
LogEntryData (Severity s, const std::string &m) : severity (s), msg (m) { }
LogEntryData () : severity (NoSeverity) { }
Severity severity;
std::string msg;
};
struct PerCircuitData
{
PerCircuitData () : status (None) { }

View File

@ -265,6 +265,14 @@ public:
*/
void extract (DeepShapeStore &dss, unsigned int layout_index, const input_layers &layers, Netlist &netlist, hier_clusters_type &clusters, double device_scaling = 1.0);
/**
* @brief Clears the errors
*/
void clear_errors ()
{
m_errors.clear ();
}
/**
* @brief Gets the error iterator, begin
*/

View File

@ -137,16 +137,16 @@ public:
db::NetlistCompareLogger::circuit_mismatch (a, b, msg);
}
virtual void log_entry (db::NetlistCompareLogger::Severity severity, const std::string &msg)
virtual void log_entry (db::Severity severity, const std::string &msg)
{
if (cb_log_entry.can_issue ()) {
cb_log_entry.issue<GenericNetlistCompareLogger, db::NetlistCompareLogger::Severity, const std::string &> (&GenericNetlistCompareLogger::log_entry, severity, msg);
cb_log_entry.issue<GenericNetlistCompareLogger, db::Severity, const std::string &> (&GenericNetlistCompareLogger::log_entry, severity, msg);
} else {
db::NetlistCompareLogger::log_entry (severity, msg);
}
}
void log_entry_fb (db::NetlistCompareLogger::Severity severity, const std::string &msg)
void log_entry_fb (db::Severity severity, const std::string &msg)
{
db::NetlistCompareLogger::log_entry (severity, msg);
}
@ -657,17 +657,17 @@ Class<db::NetlistComparer> decl_dbNetlistComparer ("db", "NetlistComparer",
"This class has been introduced in version 0.26."
);
gsi::EnumIn<GenericNetlistCompareLogger, db::NetlistCompareLogger::Severity> decl_CompareLoggerSeverity ("db", "Severity",
gsi::enum_const ("NoSeverity", db::NetlistCompareLogger::NoSeverity,
gsi::EnumIn<GenericNetlistCompareLogger, db::Severity> decl_CompareLoggerSeverity ("db", "Severity",
gsi::enum_const ("NoSeverity", db::NoSeverity,
"@brief Unspecific severity\n"
) +
gsi::enum_const ("Info", db::NetlistCompareLogger::Info,
gsi::enum_const ("Info", db::Info,
"@brief Information only\n"
) +
gsi::enum_const ("Warning", db::NetlistCompareLogger::Warning,
gsi::enum_const ("Warning", db::Warning,
"@brief A warning\n"
) +
gsi::enum_const ("Error", db::NetlistCompareLogger::Error,
gsi::enum_const ("Error", db::Error,
"@brief An error\n"
),
"@brief This class represents the log severity level for \\GenericNetlistCompareLogger#log_entry.\n"

View File

@ -1132,9 +1132,9 @@ NetlistBrowserPage::setup_trees ()
db::LayoutToNetlist *l2ndb = mp_database.get ();
db::LayoutVsSchematic *lvsdb = dynamic_cast<db::LayoutVsSchematic *> (l2ndb);
if (lvsdb && lvsdb->cross_ref ()) {
if ((lvsdb && lvsdb->cross_ref ()) || (l2ndb && ! l2ndb->log_entries ().empty ())) {
NetlistLogModel *new_model = new NetlistLogModel (log_view, lvsdb->cross_ref ());
NetlistLogModel *new_model = new NetlistLogModel (log_view, lvsdb->cross_ref () /*@@@, l2ndb*/);
delete log_view->model ();
log_view->setModel (new_model);

View File

@ -137,6 +137,7 @@ NetlistLogModel::rowCount (const QModelIndex &parent) const
} else if (parent.parent ().isValid ()) {
return 0;
} else if (parent.row () >= 0 && parent.row () < int (m_circuits.size ())) {
// @@@ that would crash for "other entries"!
return int (m_circuits [parent.row ()].second->size ());
} else {
return 0;
@ -152,7 +153,7 @@ NetlistLogModel::columnCount (const QModelIndex & /*parent*/) const
QVariant
NetlistLogModel::data (const QModelIndex &index, int role) const
{
const db::NetlistCrossReference::LogEntryData *le = 0;
const db::LogEntryData *le = 0;
if (index.parent ().isValid ()) {
const circuit_entry *ce = (const circuit_entry *) index.internalPointer ();
if (ce) {
@ -164,11 +165,11 @@ NetlistLogModel::data (const QModelIndex &index, int role) const
if (! le) {
// ignore
} else if (le->severity == db::NetlistCrossReference::Error) {
} else if (le->severity == db::Error) {
return QIcon (QString::fromUtf8 (":/error_16px.png"));
} else if (le->severity == db::NetlistCrossReference::Warning) {
} else if (le->severity == db::Warning) {
return QIcon (QString::fromUtf8 (":/warn_16px.png"));
} else if (le->severity == db::NetlistCrossReference::Info) {
} else if (le->severity == db::Info) {
return QIcon (QString::fromUtf8 (":/info_16px.png"));
}
@ -192,7 +193,7 @@ NetlistLogModel::data (const QModelIndex &index, int role) const
} else if (role == Qt::FontRole) {
if (index.parent ().isValid ()) {
if (le && le->severity == db::NetlistCrossReference::Error) {
if (le && le->severity == db::Error) {
QFont f;
f.setBold (true);
return QVariant (f);
@ -208,9 +209,9 @@ NetlistLogModel::data (const QModelIndex &index, int role) const
if (index.parent ().isValid ()) {
if (!le) {
// ignore
} else if (le->severity == db::NetlistCrossReference::Error) {
} else if (le->severity == db::Error) {
return QColor (255, 0, 0);
} else if (le->severity == db::NetlistCrossReference::Warning) {
} else if (le->severity == db::Warning) {
return QColor (0, 0, 255);
}
}