mirror of https://github.com/KLayout/klayout.git
Made SPICE netlist elements case insensitive in LVS scripts
This commit is contained in:
parent
3777d311af
commit
c48be51cb6
|
|
@ -186,8 +186,10 @@ void Circuit::rename_pin (size_t id, const std::string &name)
|
|||
|
||||
const Pin *Circuit::pin_by_name (const std::string &name) const
|
||||
{
|
||||
std::string nn = mp_netlist ? mp_netlist->normalize_name (name) : name;
|
||||
|
||||
for (Circuit::const_pin_iterator p = begin_pins (); p != end_pins (); ++p) {
|
||||
if (p->name () == name) {
|
||||
if (p->name () == nn) {
|
||||
return p.operator-> ();
|
||||
}
|
||||
}
|
||||
|
|
@ -331,6 +333,11 @@ void Circuit::remove_pin (size_t id)
|
|||
}
|
||||
}
|
||||
|
||||
Net *Circuit::net_by_name (const std::string &name)
|
||||
{
|
||||
return m_net_by_name.object_by (mp_netlist ? mp_netlist->normalize_name (name) : name);
|
||||
}
|
||||
|
||||
void Circuit::add_net (Net *net)
|
||||
{
|
||||
if (! net) {
|
||||
|
|
@ -423,6 +430,11 @@ void Circuit::remove_device (Device *device)
|
|||
m_devices.erase (device);
|
||||
}
|
||||
|
||||
Device *Circuit::device_by_name (const std::string &name)
|
||||
{
|
||||
return m_device_by_name.object_by (mp_netlist ? mp_netlist->normalize_name (name) : name);
|
||||
}
|
||||
|
||||
void Circuit::add_subcircuit (SubCircuit *subcircuit)
|
||||
{
|
||||
if (! subcircuit) {
|
||||
|
|
@ -456,6 +468,11 @@ void Circuit::remove_subcircuit (SubCircuit *subcircuit)
|
|||
m_subcircuits.erase (subcircuit);
|
||||
}
|
||||
|
||||
SubCircuit *Circuit::subcircuit_by_name (const std::string &name)
|
||||
{
|
||||
return m_subcircuit_by_name.object_by (mp_netlist ? mp_netlist->normalize_name (name) : name);
|
||||
}
|
||||
|
||||
void Circuit::register_ref (SubCircuit *r)
|
||||
{
|
||||
m_refs.push_back (r);
|
||||
|
|
|
|||
|
|
@ -496,10 +496,7 @@ public:
|
|||
*
|
||||
* If the name is not valid, null is returned.
|
||||
*/
|
||||
Net *net_by_name (const std::string &name)
|
||||
{
|
||||
return m_net_by_name.object_by (name);
|
||||
}
|
||||
Net *net_by_name (const std::string &name);
|
||||
|
||||
/**
|
||||
* @brief Adds a device to this circuit
|
||||
|
|
@ -556,10 +553,7 @@ public:
|
|||
*
|
||||
* If the name is not valid, null is returned.
|
||||
*/
|
||||
Device *device_by_name (const std::string &name)
|
||||
{
|
||||
return m_device_by_name.object_by (name);
|
||||
}
|
||||
Device *device_by_name (const std::string &name);
|
||||
|
||||
/**
|
||||
* @brief Begin iterator for the devices of the circuit (non-const version)
|
||||
|
|
@ -648,10 +642,7 @@ public:
|
|||
*
|
||||
* If the name is not valid, null is returned.
|
||||
*/
|
||||
SubCircuit *subcircuit_by_name (const std::string &name)
|
||||
{
|
||||
return m_subcircuit_by_name.object_by (name);
|
||||
}
|
||||
SubCircuit *subcircuit_by_name (const std::string &name);
|
||||
|
||||
/**
|
||||
* @brief Begin iterator for the subcircuits of the circuit (non-const version)
|
||||
|
|
|
|||
|
|
@ -204,6 +204,16 @@ Net::~Net ()
|
|||
clear ();
|
||||
}
|
||||
|
||||
Netlist *Net::netlist ()
|
||||
{
|
||||
return mp_circuit ? mp_circuit->netlist () : 0;
|
||||
}
|
||||
|
||||
const Netlist *Net::netlist () const
|
||||
{
|
||||
return mp_circuit ? mp_circuit->netlist () : 0;
|
||||
}
|
||||
|
||||
void Net::clear ()
|
||||
{
|
||||
m_name.clear ();
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ class Circuit;
|
|||
class DeviceTerminalDefinition;
|
||||
class DeviceClass;
|
||||
class Pin;
|
||||
class Netlist;
|
||||
|
||||
/**
|
||||
* @brief A reference to a terminal of a device
|
||||
|
|
@ -418,6 +419,18 @@ public:
|
|||
return mp_circuit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the netlist the net lives in
|
||||
* This pointer is 0 if the net is not part of a netlist.
|
||||
*/
|
||||
Netlist *netlist ();
|
||||
|
||||
/**
|
||||
* @brief Gets the netlist the net lives in (const version)
|
||||
* This pointer is 0 if the net is not part of a netlist.
|
||||
*/
|
||||
const Netlist *netlist () const;
|
||||
|
||||
/**
|
||||
* @brief Clears the circuit
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ namespace db
|
|||
// Netlist class implementation
|
||||
|
||||
Netlist::Netlist (NetlistManipulationCallbacks *callbacks)
|
||||
: mp_callbacks (callbacks),
|
||||
: m_case_sensitive (true), mp_callbacks (callbacks),
|
||||
m_valid_topology (false), m_lock_count (0),
|
||||
m_circuit_by_name (this, &Netlist::begin_circuits, &Netlist::end_circuits),
|
||||
m_circuit_by_cell_index (this, &Netlist::begin_circuits, &Netlist::end_circuits),
|
||||
|
|
@ -44,7 +44,8 @@ Netlist::Netlist (NetlistManipulationCallbacks *callbacks)
|
|||
}
|
||||
|
||||
Netlist::Netlist (const Netlist &other)
|
||||
: gsi::ObjectBase (other), tl::Object (other), m_valid_topology (false), m_lock_count (0),
|
||||
: gsi::ObjectBase (other), tl::Object (other), m_case_sensitive (true),
|
||||
m_valid_topology (false), m_lock_count (0),
|
||||
m_circuit_by_name (this, &Netlist::begin_circuits, &Netlist::end_circuits),
|
||||
m_circuit_by_cell_index (this, &Netlist::begin_circuits, &Netlist::end_circuits),
|
||||
m_device_abstract_by_name (this, &Netlist::begin_device_abstracts, &Netlist::end_device_abstracts),
|
||||
|
|
@ -69,6 +70,8 @@ Netlist &Netlist::operator= (const Netlist &other)
|
|||
|
||||
clear ();
|
||||
|
||||
set_case_sensitive (other.is_case_sensitive ());
|
||||
|
||||
std::map<const DeviceClass *, DeviceClass *> dct;
|
||||
for (const_device_class_iterator dc = other.begin_device_classes (); dc != other.end_device_classes (); ++dc) {
|
||||
DeviceClass *dc_new = dc->clone ();
|
||||
|
|
@ -100,6 +103,34 @@ Netlist &Netlist::operator= (const Netlist &other)
|
|||
return *this;
|
||||
}
|
||||
|
||||
void Netlist::set_case_sensitive (bool f)
|
||||
{
|
||||
m_case_sensitive = f;
|
||||
}
|
||||
|
||||
int Netlist::name_compare (bool case_sensitive, const std::string &n1, const std::string &n2)
|
||||
{
|
||||
// TODO: unicode support?
|
||||
if (case_sensitive) {
|
||||
return strcmp (n1.c_str (), n2.c_str ());
|
||||
} else {
|
||||
#if defined(_WIN32)
|
||||
return _stricmp (n1.c_str (), n2.c_str ());
|
||||
#else
|
||||
return strcasecmp (n1.c_str (), n2.c_str ());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
std::string Netlist::normalize_name (bool case_sensitive, const std::string &n)
|
||||
{
|
||||
if (case_sensitive) {
|
||||
return n;
|
||||
} else {
|
||||
return tl::to_upper_case (n);
|
||||
}
|
||||
}
|
||||
|
||||
void Netlist::circuits_changed ()
|
||||
{
|
||||
m_circuit_by_cell_index.invalidate ();
|
||||
|
|
@ -472,8 +503,10 @@ void Netlist::flatten ()
|
|||
|
||||
DeviceClass *Netlist::device_class_by_name (const std::string &name)
|
||||
{
|
||||
std::string nn = m_case_sensitive ? name : normalize_name (name);
|
||||
|
||||
for (device_class_iterator d = begin_device_classes (); d != end_device_classes (); ++d) {
|
||||
if (d->name () == name) {
|
||||
if (d->name () == nn) {
|
||||
return d.operator-> ();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,6 +102,19 @@ public:
|
|||
*/
|
||||
void clear ();
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating whether the netlist names are case sensitive
|
||||
*/
|
||||
bool is_case_sensitive () const
|
||||
{
|
||||
return m_case_sensitive;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a value indicating whether the netlist names are case sensitive
|
||||
*/
|
||||
void set_case_sensitive (bool f);
|
||||
|
||||
/**
|
||||
* @brief Returns a parsable string representation of the netlist
|
||||
*
|
||||
|
|
@ -225,7 +238,7 @@ public:
|
|||
*/
|
||||
Circuit *circuit_by_name (const std::string &name)
|
||||
{
|
||||
return m_circuit_by_name.object_by (name);
|
||||
return m_circuit_by_name.object_by (normalize_name (name));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -235,7 +248,7 @@ public:
|
|||
*/
|
||||
const Circuit *circuit_by_name (const std::string &name) const
|
||||
{
|
||||
return m_circuit_by_name.object_by (name);
|
||||
return m_circuit_by_name.object_by (normalize_name (name));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -429,7 +442,7 @@ public:
|
|||
*/
|
||||
DeviceAbstract *device_abstract_by_name (const std::string &name)
|
||||
{
|
||||
return m_device_abstract_by_name.object_by (name);
|
||||
return m_device_abstract_by_name.object_by (normalize_name (name));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -439,7 +452,7 @@ public:
|
|||
*/
|
||||
const DeviceAbstract *device_abstract_by_name (const std::string &name) const
|
||||
{
|
||||
return m_device_abstract_by_name.object_by (name);
|
||||
return m_device_abstract_by_name.object_by (normalize_name (name));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -502,10 +515,29 @@ public:
|
|||
*/
|
||||
void combine_devices ();
|
||||
|
||||
/**
|
||||
* @brief Compares two names with the given case sensitivity
|
||||
*/
|
||||
static int name_compare (bool case_sensitive, const std::string &n1, const std::string &n2);
|
||||
|
||||
/**
|
||||
* @brief Normalizes a name with the given case sensitivity
|
||||
*/
|
||||
static std::string normalize_name (bool case_sensitive, const std::string &n);
|
||||
|
||||
/**
|
||||
* @brief Normalizes a name with the given case sensitivity of the netlist
|
||||
*/
|
||||
std::string normalize_name (const std::string &n) const
|
||||
{
|
||||
return normalize_name (is_case_sensitive (), n);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Circuit;
|
||||
friend class DeviceAbstract;
|
||||
|
||||
bool m_case_sensitive;
|
||||
tl::weak_ptr<db::NetlistManipulationCallbacks> mp_callbacks;
|
||||
circuit_list m_circuits;
|
||||
device_class_list m_device_classes;
|
||||
|
|
|
|||
|
|
@ -48,15 +48,12 @@ struct GlobalCompareOptions
|
|||
debug_netcompare = tl::app_flag ("netlist-compare-debug-netcompare");
|
||||
// $KLAYOUT_NETLIST_COMPARE_DEBUG_NETGRAPH
|
||||
debug_netgraph = tl::app_flag ("netlist-compare-debug-netgraph");
|
||||
// $KLAYOUT_NETLIST_COMPARE_CASE_SENSITIVE
|
||||
compare_case_sensitive = tl::app_flag ("netlist-compare-case-sensitive");
|
||||
m_is_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool debug_netcompare;
|
||||
bool debug_netgraph;
|
||||
bool compare_case_sensitive;
|
||||
|
||||
private:
|
||||
bool m_is_initialized;
|
||||
|
|
@ -90,29 +87,19 @@ namespace db
|
|||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// A generic string compare
|
||||
|
||||
static int name_compare (const std::string &n1, const std::string &n2)
|
||||
bool combined_case_sensitive (const db::Netlist *a, const db::Netlist *b)
|
||||
{
|
||||
// TODO: unicode support?
|
||||
if (options ()->compare_case_sensitive) {
|
||||
return strcmp (n1.c_str (), n2.c_str ());
|
||||
} else {
|
||||
#if defined(_WIN32)
|
||||
return _stricmp (n1.c_str (), n2.c_str ());
|
||||
#else
|
||||
return strcasecmp (n1.c_str (), n2.c_str ());
|
||||
#endif
|
||||
}
|
||||
bool csa = a ? a->is_case_sensitive () : true;
|
||||
bool csb = b ? b->is_case_sensitive () : true;
|
||||
return csa && csb;
|
||||
}
|
||||
|
||||
static inline std::string normalize_name (const std::string &n)
|
||||
int name_compare (const db::Net *a, const db::Net *b)
|
||||
{
|
||||
if (options ()->compare_case_sensitive) {
|
||||
return n;
|
||||
} else {
|
||||
return tl::to_upper_case (n);
|
||||
}
|
||||
return db::Netlist::name_compare (combined_case_sensitive (a->netlist (), b->netlist ()), a->name (), b->name ());
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// DeviceCompare definition and implementation
|
||||
|
||||
|
|
@ -404,11 +391,16 @@ class generic_categorizer
|
|||
{
|
||||
public:
|
||||
generic_categorizer (bool with_name = true)
|
||||
: m_next_cat (0), m_with_name (with_name)
|
||||
: m_next_cat (0), m_with_name (with_name), m_case_sensitive (true)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void set_case_sensitive (bool f)
|
||||
{
|
||||
m_case_sensitive = f;
|
||||
}
|
||||
|
||||
void same (const Obj *ca, const Obj *cb)
|
||||
{
|
||||
if (! ca && ! cb) {
|
||||
|
|
@ -471,7 +463,7 @@ public:
|
|||
|
||||
if (m_with_name) {
|
||||
|
||||
std::string cls_name = normalize_name (cls->name ());
|
||||
std::string cls_name = db::Netlist::normalize_name (m_case_sensitive, cls->name ());
|
||||
|
||||
std::map<std::string, size_t>::const_iterator c = m_cat_by_name.find (cls_name);
|
||||
if (c != m_cat_by_name.end ()) {
|
||||
|
|
@ -498,6 +490,7 @@ public:
|
|||
std::map<std::string, size_t> m_cat_by_name;
|
||||
size_t m_next_cat;
|
||||
bool m_with_name;
|
||||
bool m_case_sensitive;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
@ -559,6 +552,11 @@ public:
|
|||
return m_strict_device_categories.find (cat) != m_strict_device_categories.end ();
|
||||
}
|
||||
|
||||
void set_case_sensitive (bool f)
|
||||
{
|
||||
generic_categorizer::set_case_sensitive (f);
|
||||
}
|
||||
|
||||
private:
|
||||
std::set<size_t> m_strict_device_categories;
|
||||
};
|
||||
|
|
@ -606,6 +604,11 @@ public:
|
|||
{
|
||||
return generic_categorizer<db::Circuit>::cat_for (cr);
|
||||
}
|
||||
|
||||
void set_case_sensitive (bool f)
|
||||
{
|
||||
generic_categorizer::set_case_sensitive (f);
|
||||
}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
@ -1461,7 +1464,7 @@ NetGraphNode::net_less (const db::Net *a, const db::Net *b)
|
|||
const std::string &pna = a->begin_pins ()->pin ()->name ();
|
||||
const std::string &pnb = b->begin_pins ()->pin ()->name ();
|
||||
if (! pna.empty () && ! pnb.empty ()) {
|
||||
return name_compare (pna, pnb) < 0;
|
||||
return db::Netlist::name_compare (combined_case_sensitive (a->netlist (), b->netlist ()), pna, pnb) < 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
@ -1484,7 +1487,7 @@ NetGraphNode::edge_equal (const db::Net *a, const db::Net *b)
|
|||
const std::string &pna = a->begin_pins ()->pin ()->name ();
|
||||
const std::string &pnb = b->begin_pins ()->pin ()->name ();
|
||||
if (! pna.empty () && ! pnb.empty ()) {
|
||||
return name_compare (pna, pnb) == 0;
|
||||
return db::Netlist::name_compare (combined_case_sensitive (a->netlist (), b->netlist ()), pna, pnb) == 0;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
@ -2256,7 +2259,7 @@ namespace {
|
|||
bool operator() (const std::pair<const NetGraphNode *, NetGraphNode::edge_iterator> &a, const std::pair<const NetGraphNode *, NetGraphNode::edge_iterator>b) const
|
||||
{
|
||||
tl_assert (a.first->net () && b.first->net ());
|
||||
return name_compare (a.first->net ()->name (), b.first->net ()->name ()) < 0;
|
||||
return name_compare (a.first->net (), b.first->net ()) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -2317,7 +2320,7 @@ static bool net_names_are_different (const db::Net *a, const db::Net *b)
|
|||
if (! a || ! b || a->name ().empty () || b->name ().empty ()) {
|
||||
return false;
|
||||
} else {
|
||||
return name_compare (a->name (), b->name ()) != 0;
|
||||
return name_compare (a, b) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2326,7 +2329,7 @@ static bool net_names_are_equal (const db::Net *a, const db::Net *b)
|
|||
if (! a || ! b || a->name ().empty () || b->name ().empty ()) {
|
||||
return false;
|
||||
} else {
|
||||
return name_compare (a->name (), b->name ()) == 0;
|
||||
return name_compare (a, b) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2815,6 +2818,7 @@ NetlistComparer::NetlistComparer (NetlistCompareLogger *logger)
|
|||
m_depth_first = true;
|
||||
|
||||
m_dont_consider_net_names = false;
|
||||
m_case_sensitive = false;
|
||||
}
|
||||
|
||||
NetlistComparer::~NetlistComparer ()
|
||||
|
|
@ -2887,6 +2891,7 @@ NetlistComparer::unmatched_circuits (db::Netlist *a, db::Netlist *b, std::vector
|
|||
{
|
||||
// we need to create a copy because this method is supposed to be const.
|
||||
db::CircuitCategorizer circuit_categorizer = *mp_circuit_categorizer;
|
||||
circuit_categorizer.set_case_sensitive (m_case_sensitive);
|
||||
|
||||
std::map<size_t, std::pair<std::vector<db::Circuit *>, std::vector<db::Circuit *> > > cat2circuits;
|
||||
|
||||
|
|
@ -2928,11 +2933,16 @@ NetlistComparer::unmatched_circuits (db::Netlist *a, db::Netlist *b, std::vector
|
|||
bool
|
||||
NetlistComparer::compare (const db::Netlist *a, const db::Netlist *b) const
|
||||
{
|
||||
m_case_sensitive = combined_case_sensitive (a, b);
|
||||
|
||||
// we need to create a copy because this method is supposed to be const.
|
||||
db::CircuitCategorizer circuit_categorizer = *mp_circuit_categorizer;
|
||||
db::DeviceCategorizer device_categorizer = *mp_device_categorizer;
|
||||
db::CircuitPinMapper circuit_pin_mapper = *mp_circuit_pin_mapper;
|
||||
|
||||
circuit_categorizer.set_case_sensitive (m_case_sensitive);
|
||||
device_categorizer.set_case_sensitive (m_case_sensitive);
|
||||
|
||||
bool good = true;
|
||||
|
||||
std::map<size_t, std::pair<std::vector<const db::Circuit *>, std::vector<const db::Circuit *> > > cat2circuits;
|
||||
|
|
@ -3745,14 +3755,14 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g
|
|||
for (db::Circuit::const_pin_iterator p = c2->begin_pins (); p != c2->end_pins (); ++p) {
|
||||
const db::Net *net = c2->net_for_pin (p->id ());
|
||||
if (!net && !p->name ().empty ()) {
|
||||
abstract_pins_by_name.insert (std::make_pair (normalize_name (p->name ()), std::make_pair ((const db::Pin *) 0, (const db::Pin *) 0))).first->second.second = p.operator-> ();
|
||||
abstract_pins_by_name.insert (std::make_pair (db::Netlist::normalize_name (m_case_sensitive, p->name ()), std::make_pair ((const db::Pin *) 0, (const db::Pin *) 0))).first->second.second = p.operator-> ();
|
||||
}
|
||||
}
|
||||
|
||||
for (db::Circuit::const_pin_iterator p = c1->begin_pins (); p != c1->end_pins (); ++p) {
|
||||
const db::Net *net = c1->net_for_pin (p->id ());
|
||||
if (!net && !p->name ().empty ()) {
|
||||
abstract_pins_by_name.insert (std::make_pair (normalize_name (p->name ()), std::make_pair ((const db::Pin *) 0, (const db::Pin *) 0))).first->second.first = p.operator-> ();
|
||||
abstract_pins_by_name.insert (std::make_pair (db::Netlist::normalize_name (m_case_sensitive, p->name ()), std::make_pair ((const db::Pin *) 0, (const db::Pin *) 0))).first->second.first = p.operator-> ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -364,6 +364,7 @@ protected:
|
|||
size_t m_max_depth;
|
||||
bool m_depth_first;
|
||||
bool m_dont_consider_net_names;
|
||||
mutable bool m_case_sensitive;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -299,6 +299,9 @@ void NetlistSpiceReader::read (tl::InputStream &stream, db::Netlist &netlist)
|
|||
m_global_nets.clear ();
|
||||
m_circuits_read.clear ();
|
||||
|
||||
// SPICE netlists are case insensitive
|
||||
netlist.set_case_sensitive (false);
|
||||
|
||||
try {
|
||||
|
||||
mp_delegate->start (&netlist);
|
||||
|
|
@ -775,13 +778,7 @@ std::string NetlistSpiceReader::read_name_with_case (tl::Extractor &ex)
|
|||
|
||||
std::string NetlistSpiceReader::read_name (tl::Extractor &ex)
|
||||
{
|
||||
// TODO: allow configuring Spice reader as case sensitive?
|
||||
// this is easy to do: just avoid to_upper here:
|
||||
#if 1
|
||||
return tl::to_upper_case (read_name_with_case (ex));
|
||||
#else
|
||||
return read_name_with_case (ex);
|
||||
#endif
|
||||
return mp_netlist->normalize_name (read_name_with_case (ex));
|
||||
}
|
||||
|
||||
bool NetlistSpiceReader::read_element (tl::Extractor &ex, const std::string &element, const std::string &name)
|
||||
|
|
|
|||
|
|
@ -298,8 +298,7 @@ module LVS
|
|||
# resolve otherwise.
|
||||
#
|
||||
# circuit_a and net_a are for the layout netlist, circuit_b and net_b for the schematic netlist.
|
||||
# Note that SPICE netlists are normalized to @b upper case @/b. So enter
|
||||
# upper case circuit or net names for SPICE schematic netlists.
|
||||
# Names are case sensitive for layout-derived netlists and case-insensitive for SPICE schematic netlists.
|
||||
#
|
||||
# Use this method andwhere in the script before the \compare call.
|
||||
|
||||
|
|
@ -378,8 +377,7 @@ module LVS
|
|||
# method allows establishing an explicit correspondence.
|
||||
#
|
||||
# circuit_a is for the layout netlist, circuit_b for the schematic netlist.
|
||||
# Note that SPICE netlists are normalized to @b upper case @/b. So enter
|
||||
# upper case circuit names for SPICE schematic netlists.
|
||||
# Names are case sensitive for layout-derived netlists and case-insensitive for SPICE schematic netlists.
|
||||
#
|
||||
# One of the circuits may be nil. In this case, the corresponding
|
||||
# other circuit is mapped to "nothing", i.e. ignored.
|
||||
|
|
@ -420,8 +418,7 @@ module LVS
|
|||
# \schematic.
|
||||
#
|
||||
# class_a is for the layout netlist, class_b for the schematic netlist.
|
||||
# Note that SPICE netlists are normalized to @b upper case @/b. So enter
|
||||
# upper case device names for SPICE schematic netlists.
|
||||
# Names are case sensitive for layout-derived netlists and case-insensitive for SPICE schematic netlists.
|
||||
#
|
||||
# One of the device classes may be "nil". In this case, the corresponding
|
||||
# other device class is mapped to "nothing", i.e. ignored.
|
||||
|
|
@ -484,8 +481,7 @@ module LVS
|
|||
# The circuit argument is either a circuit name (a string) or a Circuit object
|
||||
# from the schematic netlist.
|
||||
#
|
||||
# Note that SPICE netlists are normalized to @b upper case @/b. So enter
|
||||
# upper case circuit names for SPICE schematic netlists.
|
||||
# Names are case sensitive for layout-derived netlists and case-insensitive for SPICE schematic netlists.
|
||||
#
|
||||
# The pin arguments are zero-based pin numbers, where 0 is the first number, 1 the second etc.
|
||||
# If the netlist provides named pins, names can be used instead of numbers. Again, use upper
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
#include "lymMacro.h"
|
||||
#include "tlFileUtils.h"
|
||||
|
||||
void run_test (tl::TestBase *_this, const std::string &suffix, const std::string &layout, bool with_l2n = false, const std::string &top = std::string ())
|
||||
void run_test (tl::TestBase *_this, const std::string &suffix, const std::string &layout, bool with_l2n = false, const std::string &top = std::string (), bool change_case = false)
|
||||
{
|
||||
std::string rs = tl::testsrc ();
|
||||
rs += "/testdata/lvs/" + suffix + ".lvs";
|
||||
|
|
@ -58,7 +58,8 @@ void run_test (tl::TestBase *_this, const std::string &suffix, const std::string
|
|||
"$lvs_test_target_cir = '%s'\n"
|
||||
"$lvs_test_target_l2n = '%s'\n"
|
||||
"$lvs_test_top = '%s'\n"
|
||||
, src, output_lvsdb, output_cir, output_l2n, top)
|
||||
"$change_case = %s\n"
|
||||
, src, output_lvsdb, output_cir, output_l2n, top, change_case ? "true" : "false")
|
||||
);
|
||||
config.set_interpreter (lym::Macro::Ruby);
|
||||
EXPECT_EQ (config.run (), 0);
|
||||
|
|
@ -108,11 +109,15 @@ TEST(5_simple_same_device_classes)
|
|||
TEST(6_simple_pin_swapping)
|
||||
{
|
||||
run_test (_this, "ringo_simple_pin_swapping", "ringo.gds");
|
||||
// change case
|
||||
run_test (_this, "ringo_simple_pin_swapping", "ringo.gds", false, std::string (), true);
|
||||
}
|
||||
|
||||
TEST(7_net_and_circuit_equivalence)
|
||||
{
|
||||
run_test (_this, "ringo_simple_net_and_circuit_equivalence", "ringo_renamed.gds");
|
||||
// change case
|
||||
run_test (_this, "ringo_simple_net_and_circuit_equivalence", "ringo_renamed.gds", false, std::string (), true);
|
||||
}
|
||||
|
||||
TEST(8_simplification)
|
||||
|
|
@ -143,6 +148,8 @@ TEST(12_simple_dmos)
|
|||
TEST(13_simple_ringo_device_subcircuits)
|
||||
{
|
||||
run_test (_this, "ringo_device_subcircuits", "ringo.gds");
|
||||
// change case
|
||||
run_test (_this, "ringo_device_subcircuits", "ringo.gds", false, std::string (), true);
|
||||
}
|
||||
|
||||
TEST(14_simple_ringo_mixed_hierarchy)
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ connect_global(bulk, "SUBSTRATE")
|
|||
connect_global(ptie, "SUBSTRATE")
|
||||
|
||||
# Test same_device_classes
|
||||
same_device_classes("PMOS", "XPMOS")
|
||||
same_device_classes("PMOS", $change_case ? "xpMos" : "XPMOS")
|
||||
|
||||
# Compare section
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ target_netlist($lvs_test_target_cir, write_spice, "Extracted by KLayout")
|
|||
schematic("ringo.cir")
|
||||
|
||||
# preempt configuration (see below)
|
||||
same_nets("top", "ENABLE", "RINGO", "ENABLE")
|
||||
same_nets("top", "ENABLE", $change_case ? "Ringo" : "RINGO", $change_case ? "enable" : "ENABLE")
|
||||
|
||||
deep
|
||||
|
||||
|
|
@ -71,8 +71,8 @@ connect_global(ptie, "SUBSTRATE")
|
|||
|
||||
# Compare section
|
||||
|
||||
same_circuits("top", "RINGO")
|
||||
same_circuits("INV", "INVX1")
|
||||
same_circuits("top", $change_case ? "ringo" : "RINGO")
|
||||
same_circuits("INV", $change_case ? "invX1" : "INVX1")
|
||||
same_circuits("DOESNOTEXIST", "DOESNOTEXIST2")
|
||||
same_nets("DOESNOTEXIST", "ENABLE", "DOESNOTEXIST2", "ENABLE")
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ target_netlist($lvs_test_target_cir, write_spice, "Extracted by KLayout")
|
|||
schematic("ringo_pin_swapping.cir")
|
||||
|
||||
# preempt configuration
|
||||
equivalent_pins("ND2X1", 4, 5)
|
||||
equivalent_pins($change_case ? "nd2X1" : "ND2X1", 4, 5)
|
||||
|
||||
deep
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue