mirror of https://github.com/KLayout/klayout.git
WIP: refactoring - separated pins of net into outgoing and subcircuit.
This commit is contained in:
parent
261b14a260
commit
eb435d5d85
|
|
@ -356,46 +356,41 @@ LayoutToNetlist::build_all_nets (const db::CellMapping &cmap, db::Layout &target
|
|||
continue;
|
||||
}
|
||||
|
||||
std::set<const Net *> excluded_nets;
|
||||
if (circuit_cell_name_prefix) {
|
||||
for (db::Circuit::const_pin_iterator p = c->begin_pins (); p != c->end_pins (); ++p) {
|
||||
excluded_nets.insert (c->net_for_pin (p->id ()));
|
||||
}
|
||||
}
|
||||
|
||||
db::cell_index_type target_ci = cmap.cell_mapping (c->cell_index ());
|
||||
|
||||
for (db::Circuit::const_net_iterator n = c->begin_nets (); n != c->end_nets (); ++n) {
|
||||
|
||||
if (excluded_nets.find (n.operator-> ()) == excluded_nets.end ()) {
|
||||
// exlude local nets in recursive mode
|
||||
if (circuit_cell_name_prefix && n->pin_count () > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const db::connected_clusters<db::PolygonRef> &ccl = m_netex.clusters ().clusters_per_cell (c->cell_index ());
|
||||
const db::local_cluster<db::PolygonRef> &cl = ccl.cluster_by_id (n->cluster_id ());
|
||||
const db::connected_clusters<db::PolygonRef> &ccl = m_netex.clusters ().clusters_per_cell (c->cell_index ());
|
||||
const db::local_cluster<db::PolygonRef> &cl = ccl.cluster_by_id (n->cluster_id ());
|
||||
|
||||
bool any_connections = ! ccl.connections_for_cluster (n->cluster_id ()).empty ();
|
||||
bool any_connections = ! ccl.connections_for_cluster (n->cluster_id ()).empty ();
|
||||
|
||||
bool any_shapes = false;
|
||||
for (std::map<unsigned int, const db::Region *>::const_iterator m = lmap.begin (); m != lmap.end () && !any_shapes; ++m) {
|
||||
any_shapes = ! cl.begin (layer_of (*m->second)).at_end ();
|
||||
}
|
||||
bool any_shapes = false;
|
||||
for (std::map<unsigned int, const db::Region *>::const_iterator m = lmap.begin (); m != lmap.end () && !any_shapes; ++m) {
|
||||
any_shapes = ! cl.begin (layer_of (*m->second)).at_end ();
|
||||
}
|
||||
|
||||
if (any_shapes || (circuit_cell_name_prefix && any_connections)) {
|
||||
if (any_shapes || (circuit_cell_name_prefix && any_connections)) {
|
||||
|
||||
db::cell_index_type net_ci = target_ci;
|
||||
db::cell_index_type net_ci = target_ci;
|
||||
|
||||
if (net_cell_name_prefix) {
|
||||
if (net_cell_name_prefix) {
|
||||
|
||||
db::Cell &tc = target.cell (target_ci);
|
||||
net_ci = target.add_cell ((std::string (net_cell_name_prefix) + n->expanded_name ()).c_str ());
|
||||
tc.insert (db::CellInstArray (db::CellInst (net_ci), db::Trans ()));
|
||||
|
||||
}
|
||||
|
||||
build_net_rec (*n, target, target.cell (net_ci), lmap, circuit_cell_name_prefix, cell_map);
|
||||
db::Cell &tc = target.cell (target_ci);
|
||||
net_ci = target.add_cell ((std::string (net_cell_name_prefix) + n->expanded_name ()).c_str ());
|
||||
tc.insert (db::CellInstArray (db::CellInst (net_ci), db::Trans ()));
|
||||
|
||||
}
|
||||
|
||||
build_net_rec (*n, target, target.cell (net_ci), lmap, circuit_cell_name_prefix, cell_map);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -484,16 +479,11 @@ db::Net *LayoutToNetlist::probe_net (const db::Region &of_region, const db::Poin
|
|||
|
||||
// follow the path up in the net hierarchy using the transformation and the upper cell index as the
|
||||
// guide line
|
||||
while (! inst_path.empty () && circuit->is_external_net (net)) {
|
||||
while (! inst_path.empty () && net->pin_count () > 0) {
|
||||
|
||||
cell_indexes.pop_back ();
|
||||
|
||||
db::Pin *pin = 0;
|
||||
for (db::Circuit::pin_iterator p = circuit->begin_pins (); p != circuit->end_pins () && ! pin; ++p) {
|
||||
if (circuit->net_for_pin (p->id ()) == net) {
|
||||
pin = p.operator-> ();
|
||||
}
|
||||
}
|
||||
const db::Pin *pin = circuit->pin_by_id (net->begin_pins ()->pin_id ());
|
||||
tl_assert (pin != 0);
|
||||
|
||||
db::DCplxTrans dtrans = dbu_trans * inst_path.back ().complex_trans () * dbu_trans_inv;
|
||||
|
|
|
|||
|
|
@ -191,9 +191,9 @@ SubCircuit::SubCircuit ()
|
|||
|
||||
SubCircuit::~SubCircuit()
|
||||
{
|
||||
for (std::vector<Net::pin_iterator>::const_iterator p = m_pin_refs.begin (); p != m_pin_refs.end (); ++p) {
|
||||
if (*p != Net::pin_iterator () && (*p)->net ()) {
|
||||
(*p)->net ()->erase_pin (*p);
|
||||
for (std::vector<Net::subcircuit_pin_iterator>::const_iterator p = m_pin_refs.begin (); p != m_pin_refs.end (); ++p) {
|
||||
if (*p != Net::subcircuit_pin_iterator () && (*p)->net ()) {
|
||||
(*p)->net ()->erase_subcircuit_pin (*p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -233,10 +233,10 @@ void SubCircuit::set_trans (const db::DCplxTrans &t)
|
|||
m_trans = t;
|
||||
}
|
||||
|
||||
void SubCircuit::set_pin_ref_for_pin (size_t pin_id, Net::pin_iterator iter)
|
||||
void SubCircuit::set_pin_ref_for_pin (size_t pin_id, Net::subcircuit_pin_iterator iter)
|
||||
{
|
||||
if (m_pin_refs.size () < pin_id + 1) {
|
||||
m_pin_refs.resize (pin_id + 1, Net::pin_iterator ());
|
||||
m_pin_refs.resize (pin_id + 1, Net::subcircuit_pin_iterator ());
|
||||
}
|
||||
m_pin_refs [pin_id] = iter;
|
||||
}
|
||||
|
|
@ -255,8 +255,8 @@ void SubCircuit::set_circuit_ref (Circuit *c)
|
|||
const Net *SubCircuit::net_for_pin (size_t pin_id) const
|
||||
{
|
||||
if (pin_id < m_pin_refs.size ()) {
|
||||
Net::pin_iterator p = m_pin_refs [pin_id];
|
||||
if (p != Net::pin_iterator ()) {
|
||||
Net::subcircuit_pin_iterator p = m_pin_refs [pin_id];
|
||||
if (p != Net::subcircuit_pin_iterator ()) {
|
||||
return p->net ();
|
||||
}
|
||||
}
|
||||
|
|
@ -270,15 +270,15 @@ void SubCircuit::connect_pin (size_t pin_id, Net *net)
|
|||
}
|
||||
|
||||
if (pin_id < m_pin_refs.size ()) {
|
||||
Net::pin_iterator p = m_pin_refs [pin_id];
|
||||
if (p != Net::pin_iterator () && p->net ()) {
|
||||
p->net ()->erase_pin (p);
|
||||
Net::subcircuit_pin_iterator p = m_pin_refs [pin_id];
|
||||
if (p != Net::subcircuit_pin_iterator () && p->net ()) {
|
||||
p->net ()->erase_subcircuit_pin (p);
|
||||
}
|
||||
m_pin_refs [pin_id] = Net::pin_iterator ();
|
||||
m_pin_refs [pin_id] = Net::subcircuit_pin_iterator ();
|
||||
}
|
||||
|
||||
if (net) {
|
||||
net->add_pin (NetPinRef (this, pin_id));
|
||||
net->add_subcircuit_pin (NetSubcircuitPinRef (this, pin_id));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -333,25 +333,19 @@ NetTerminalRef::device_class () const
|
|||
// NetPinRef class implementation
|
||||
|
||||
NetPinRef::NetPinRef ()
|
||||
: m_pin_id (0), mp_subcircuit (0), mp_net (0)
|
||||
: m_pin_id (0), mp_net (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
NetPinRef::NetPinRef (size_t pin_id)
|
||||
: m_pin_id (pin_id), mp_subcircuit (0), mp_net (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
NetPinRef::NetPinRef (SubCircuit *circuit, size_t pin_id)
|
||||
: m_pin_id (pin_id), mp_subcircuit (circuit), mp_net (0)
|
||||
: m_pin_id (pin_id), mp_net (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
NetPinRef::NetPinRef (const NetPinRef &other)
|
||||
: m_pin_id (other.m_pin_id), mp_subcircuit (other.mp_subcircuit), mp_net (0)
|
||||
: m_pin_id (other.m_pin_id), mp_net (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -360,18 +354,51 @@ NetPinRef &NetPinRef::operator= (const NetPinRef &other)
|
|||
{
|
||||
if (this != &other) {
|
||||
m_pin_id = other.m_pin_id;
|
||||
mp_subcircuit = other.mp_subcircuit;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
const Pin *NetPinRef::pin () const
|
||||
{
|
||||
if (! mp_subcircuit) {
|
||||
if (mp_net && mp_net->circuit ()) {
|
||||
return mp_net->circuit ()->pin_by_id (m_pin_id);
|
||||
}
|
||||
} else if (mp_subcircuit->circuit_ref ()) {
|
||||
if (mp_net && mp_net->circuit ()) {
|
||||
return mp_net->circuit ()->pin_by_id (m_pin_id);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
// NetSubcircuitPinRef class implementation
|
||||
|
||||
NetSubcircuitPinRef::NetSubcircuitPinRef ()
|
||||
: m_pin_id (0), mp_subcircuit (0), mp_net (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
NetSubcircuitPinRef::NetSubcircuitPinRef (SubCircuit *circuit, size_t pin_id)
|
||||
: m_pin_id (pin_id), mp_subcircuit (circuit), mp_net (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
NetSubcircuitPinRef::NetSubcircuitPinRef (const NetSubcircuitPinRef &other)
|
||||
: m_pin_id (other.m_pin_id), mp_subcircuit (other.mp_subcircuit), mp_net (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
NetSubcircuitPinRef &NetSubcircuitPinRef::operator= (const NetSubcircuitPinRef &other)
|
||||
{
|
||||
if (this != &other) {
|
||||
m_pin_id = other.m_pin_id;
|
||||
mp_subcircuit = other.mp_subcircuit;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
const Pin *NetSubcircuitPinRef::pin () const
|
||||
{
|
||||
if (mp_subcircuit && mp_subcircuit->circuit_ref ()) {
|
||||
return mp_subcircuit->circuit_ref ()->pin_by_id (m_pin_id);
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -407,6 +434,10 @@ Net &Net::operator= (const Net &other)
|
|||
m_name = other.m_name;
|
||||
m_cluster_id = other.m_cluster_id;
|
||||
|
||||
for (const_subcircuit_pin_iterator i = other.begin_subcircuit_pins (); i != other.end_subcircuit_pins (); ++i) {
|
||||
add_subcircuit_pin (*i);
|
||||
}
|
||||
|
||||
for (const_pin_iterator i = other.begin_pins (); i != other.end_pins (); ++i) {
|
||||
add_pin (*i);
|
||||
}
|
||||
|
|
@ -436,6 +467,10 @@ void Net::clear ()
|
|||
while (! m_pins.empty ()) {
|
||||
erase_pin (begin_pins ());
|
||||
}
|
||||
|
||||
while (! m_subcircuit_pins.empty ()) {
|
||||
erase_subcircuit_pin (begin_subcircuit_pins ());
|
||||
}
|
||||
}
|
||||
|
||||
void Net::set_name (const std::string &name)
|
||||
|
|
@ -483,25 +518,37 @@ void Net::add_pin (const NetPinRef &pin)
|
|||
NetPinRef &new_pin = m_pins.back ();
|
||||
new_pin.set_net (this);
|
||||
|
||||
if (! pin.subcircuit ()) {
|
||||
if (mp_circuit) {
|
||||
mp_circuit->set_pin_ref_for_pin (new_pin.pin_id (), --m_pins.end ());
|
||||
}
|
||||
} else {
|
||||
new_pin.subcircuit ()->set_pin_ref_for_pin (new_pin.pin_id (), --m_pins.end ());
|
||||
if (mp_circuit) {
|
||||
mp_circuit->set_pin_ref_for_pin (new_pin.pin_id (), --m_pins.end ());
|
||||
}
|
||||
}
|
||||
|
||||
void Net::add_subcircuit_pin (const NetSubcircuitPinRef &pin)
|
||||
{
|
||||
m_subcircuit_pins.push_back (pin);
|
||||
NetSubcircuitPinRef &new_pin = m_subcircuit_pins.back ();
|
||||
new_pin.set_net (this);
|
||||
|
||||
tl_assert (pin.subcircuit () != 0);
|
||||
new_pin.subcircuit ()->set_pin_ref_for_pin (new_pin.pin_id (), --m_subcircuit_pins.end ());
|
||||
}
|
||||
|
||||
void Net::erase_pin (pin_iterator iter)
|
||||
{
|
||||
if (iter->subcircuit ()) {
|
||||
iter->subcircuit ()->set_pin_ref_for_pin (iter->pin_id (), pin_iterator ());
|
||||
} else if (mp_circuit) {
|
||||
if (mp_circuit) {
|
||||
mp_circuit->set_pin_ref_for_pin (iter->pin_id (), pin_iterator ());
|
||||
}
|
||||
m_pins.erase (iter);
|
||||
}
|
||||
|
||||
void Net::erase_subcircuit_pin (subcircuit_pin_iterator iter)
|
||||
{
|
||||
if (iter->subcircuit ()) {
|
||||
iter->subcircuit ()->set_pin_ref_for_pin (iter->pin_id (), subcircuit_pin_iterator ());
|
||||
}
|
||||
m_subcircuit_pins.erase (iter);
|
||||
}
|
||||
|
||||
void Net::add_terminal (const NetTerminalRef &terminal)
|
||||
{
|
||||
if (! terminal.device ()) {
|
||||
|
|
@ -612,13 +659,13 @@ Circuit &Circuit::operator= (const Circuit &other)
|
|||
}
|
||||
|
||||
for (Net::const_pin_iterator p = i->begin_pins (); p != i->end_pins (); ++p) {
|
||||
if (! p->subcircuit ()) {
|
||||
n->add_pin (NetPinRef (p->pin_id ()));
|
||||
} else {
|
||||
std::map<const SubCircuit *, SubCircuit *>::const_iterator m = sc_table.find (p->subcircuit ());
|
||||
tl_assert (m != sc_table.end ());
|
||||
n->add_pin (NetPinRef (m->second, p->pin_id ()));
|
||||
}
|
||||
n->add_pin (NetPinRef (p->pin_id ()));
|
||||
}
|
||||
|
||||
for (Net::const_subcircuit_pin_iterator p = i->begin_subcircuit_pins (); p != i->end_subcircuit_pins (); ++p) {
|
||||
std::map<const SubCircuit *, SubCircuit *>::const_iterator m = sc_table.find (p->subcircuit ());
|
||||
tl_assert (m != sc_table.end ());
|
||||
n->add_subcircuit_pin (NetSubcircuitPinRef (m->second, p->pin_id ()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -869,21 +916,6 @@ void Circuit::connect_pin (size_t pin_id, Net *net)
|
|||
}
|
||||
}
|
||||
|
||||
bool Circuit::is_external_net (const db::Net *net) const
|
||||
{
|
||||
if (!net || net->pin_count () == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (std::vector<Net::pin_iterator>::const_iterator p = m_pin_refs.begin (); p != m_pin_refs.end (); ++p) {
|
||||
if (*p != Net::pin_iterator () && (*p)->net () == net) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Circuit::purge_nets ()
|
||||
{
|
||||
std::vector<db::Net *> nets_to_be_purged;
|
||||
|
|
@ -1541,7 +1573,7 @@ void Netlist::make_top_level_pins ()
|
|||
|
||||
// create pins for the named nets and connect them
|
||||
for (Circuit::net_iterator n = circuit->begin_nets (); n != circuit->end_nets (); ++n) {
|
||||
if (! n->name ().empty () && n->terminal_count () + n->pin_count () > 0) {
|
||||
if (! n->name ().empty () && n->terminal_count () + n->subcircuit_pin_count () > 0) {
|
||||
Pin pin = circuit->add_pin (n->name ());
|
||||
circuit->connect_pin (pin.id (), n.operator-> ());
|
||||
}
|
||||
|
|
@ -1633,7 +1665,7 @@ std::string Netlist::to_string () const
|
|||
|
||||
#if 0 // for debugging
|
||||
for (db::Circuit::const_net_iterator n = c->begin_nets (); n != c->end_nets (); ++n) {
|
||||
res += " N" + net_name (n.operator-> ()) + " pins=" + tl::to_string (n->pin_count ()) + " terminals=" + tl::to_string (n->terminal_count ()) + "\n";
|
||||
res += " N" + net_name (n.operator-> ()) + " pins=" + tl::to_string (n->pin_count ()) + " sc_pins=" + tl::to_string (n->subcircuit_pin_count ()) + " terminals=" + tl::to_string (n->terminal_count ()) + "\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -260,9 +260,7 @@ private:
|
|||
/**
|
||||
* @brief A reference to a pin inside a net
|
||||
*
|
||||
* A pin belongs to a subcircuit.
|
||||
* If the subcircuit reference is 0, the pin is a pin of the current circuit
|
||||
* (upward pin).
|
||||
* This object describes a connection to an outgoing pin.
|
||||
*/
|
||||
class DB_PUBLIC NetPinRef
|
||||
{
|
||||
|
|
@ -277,11 +275,6 @@ public:
|
|||
*/
|
||||
NetPinRef (size_t pin_id);
|
||||
|
||||
/**
|
||||
* @brief Creates a pin reference to the given pin of the given subcircuit
|
||||
*/
|
||||
NetPinRef (SubCircuit *circuit, size_t pin_id);
|
||||
|
||||
/**
|
||||
* @brief Copy constructor
|
||||
*/
|
||||
|
|
@ -296,6 +289,95 @@ public:
|
|||
* @brief Comparison
|
||||
*/
|
||||
bool operator< (const NetPinRef &other) const
|
||||
{
|
||||
return m_pin_id < other.m_pin_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Equality
|
||||
*/
|
||||
bool operator== (const NetPinRef &other) const
|
||||
{
|
||||
return (m_pin_id == other.m_pin_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the pin reference (const version)
|
||||
*/
|
||||
size_t pin_id () const
|
||||
{
|
||||
return m_pin_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the pin reference from the pin id
|
||||
* If the pin cannot be resolved, null is returned.
|
||||
*/
|
||||
const Pin *pin () const;
|
||||
|
||||
/**
|
||||
* @brief Gets the net the pin lives in
|
||||
*/
|
||||
Net *net ()
|
||||
{
|
||||
return mp_net;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the net the pin lives in (const version)
|
||||
*/
|
||||
const Net *net () const
|
||||
{
|
||||
return mp_net;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Net;
|
||||
|
||||
size_t m_pin_id;
|
||||
Net *mp_net;
|
||||
|
||||
/**
|
||||
* @brief Sets the net the terminal lives in
|
||||
*/
|
||||
void set_net (Net *net)
|
||||
{
|
||||
mp_net = net;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A reference to a pin inside a net
|
||||
*
|
||||
* This object describes a connection to a pin of a subcircuit.
|
||||
*/
|
||||
class DB_PUBLIC NetSubcircuitPinRef
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*/
|
||||
NetSubcircuitPinRef ();
|
||||
|
||||
/**
|
||||
* @brief Creates a pin reference to the given pin of the given subcircuit
|
||||
*/
|
||||
NetSubcircuitPinRef (SubCircuit *circuit, size_t pin_id);
|
||||
|
||||
/**
|
||||
* @brief Copy constructor
|
||||
*/
|
||||
NetSubcircuitPinRef (const NetSubcircuitPinRef &other);
|
||||
|
||||
/**
|
||||
* @brief Assignment
|
||||
*/
|
||||
NetSubcircuitPinRef &operator= (const NetSubcircuitPinRef &other);
|
||||
|
||||
/**
|
||||
* @brief Comparison
|
||||
*/
|
||||
bool operator< (const NetSubcircuitPinRef &other) const
|
||||
{
|
||||
if (mp_subcircuit != other.mp_subcircuit) {
|
||||
return mp_subcircuit < other.mp_subcircuit;
|
||||
|
|
@ -306,7 +388,7 @@ public:
|
|||
/**
|
||||
* @brief Equality
|
||||
*/
|
||||
bool operator== (const NetPinRef &other) const
|
||||
bool operator== (const NetSubcircuitPinRef &other) const
|
||||
{
|
||||
return (mp_subcircuit == other.mp_subcircuit && m_pin_id == other.m_pin_id);
|
||||
}
|
||||
|
|
@ -388,6 +470,9 @@ public:
|
|||
typedef std::list<NetPinRef> pin_list;
|
||||
typedef pin_list::const_iterator const_pin_iterator;
|
||||
typedef pin_list::iterator pin_iterator;
|
||||
typedef std::list<NetSubcircuitPinRef> subcircuit_pin_list;
|
||||
typedef subcircuit_pin_list::const_iterator const_subcircuit_pin_iterator;
|
||||
typedef subcircuit_pin_list::iterator subcircuit_pin_iterator;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
|
|
@ -525,6 +610,48 @@ public:
|
|||
return m_pins.end ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds a subcircuit pin to this net
|
||||
*/
|
||||
void add_subcircuit_pin (const NetSubcircuitPinRef &pin);
|
||||
|
||||
/**
|
||||
* @brief Erases the given subcircuit pin from this net
|
||||
*/
|
||||
void erase_subcircuit_pin (subcircuit_pin_iterator iter);
|
||||
|
||||
/**
|
||||
* @brief Begin iterator for the pins of the net (const version)
|
||||
*/
|
||||
const_subcircuit_pin_iterator begin_subcircuit_pins () const
|
||||
{
|
||||
return m_subcircuit_pins.begin ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief End iterator for the pins of the net (const version)
|
||||
*/
|
||||
const_subcircuit_pin_iterator end_subcircuit_pins () const
|
||||
{
|
||||
return m_subcircuit_pins.end ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Begin iterator for the pins of the net (non-const version)
|
||||
*/
|
||||
subcircuit_pin_iterator begin_subcircuit_pins ()
|
||||
{
|
||||
return m_subcircuit_pins.begin ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief End iterator for the pins of the net (non-const version)
|
||||
*/
|
||||
subcircuit_pin_iterator end_subcircuit_pins ()
|
||||
{
|
||||
return m_subcircuit_pins.end ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds a terminal to this net
|
||||
*/
|
||||
|
|
@ -572,7 +699,7 @@ public:
|
|||
*/
|
||||
bool is_floating () const
|
||||
{
|
||||
return (m_pins.size () + m_terminals.size ()) < 2;
|
||||
return (m_pins.size () + m_subcircuit_pins.size () + m_terminals.size ()) < 2;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -580,17 +707,25 @@ public:
|
|||
*/
|
||||
bool is_internal () const
|
||||
{
|
||||
return m_pins.size () == 0 && m_terminals.size () == 2;
|
||||
return m_pins.size () == 0 && m_subcircuit_pins.size () == 0 && m_terminals.size () == 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the number of pins connected
|
||||
* @brief Returns the number of outgoing pins connected
|
||||
*/
|
||||
size_t pin_count () const
|
||||
{
|
||||
return m_pins.size ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the number of subcircuit pins connected
|
||||
*/
|
||||
size_t subcircuit_pin_count () const
|
||||
{
|
||||
return m_subcircuit_pins.size ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the number of terminals connected
|
||||
*/
|
||||
|
|
@ -604,6 +739,7 @@ private:
|
|||
|
||||
terminal_list m_terminals;
|
||||
pin_list m_pins;
|
||||
subcircuit_pin_list m_subcircuit_pins;
|
||||
std::string m_name;
|
||||
size_t m_cluster_id;
|
||||
Circuit *mp_circuit;
|
||||
|
|
@ -971,14 +1107,14 @@ private:
|
|||
tl::weak_ptr<Circuit> m_circuit_ref;
|
||||
std::string m_name;
|
||||
db::DCplxTrans m_trans;
|
||||
std::vector<Net::pin_iterator> m_pin_refs;
|
||||
std::vector<Net::subcircuit_pin_iterator> m_pin_refs;
|
||||
size_t m_id;
|
||||
Circuit *mp_circuit;
|
||||
|
||||
/**
|
||||
* @brief Sets the pin reference for a specific pin
|
||||
*/
|
||||
void set_pin_ref_for_pin (size_t ppin_id, Net::pin_iterator iter);
|
||||
void set_pin_ref_for_pin (size_t ppin_id, Net::subcircuit_pin_iterator iter);
|
||||
|
||||
/**
|
||||
* @brief Sets the circuit reference
|
||||
|
|
@ -1531,13 +1667,6 @@ public:
|
|||
*/
|
||||
void connect_pin (size_t pin_id, Net *net);
|
||||
|
||||
/**
|
||||
* @brief Returns true, if the net is an external net
|
||||
*
|
||||
* External nets are nets which are connected to an outgoing pin.
|
||||
*/
|
||||
bool is_external_net (const db::Net *net) const;
|
||||
|
||||
/**
|
||||
* @brief Purge unused nets
|
||||
*
|
||||
|
|
|
|||
|
|
@ -236,18 +236,31 @@ Class<db::NetPinRef> decl_dbNetPinRef ("db", "NetPinRef",
|
|||
gsi::method ("pin", &db::NetPinRef::pin,
|
||||
"@brief Gets the \\Pin object of the pin the connection is made to."
|
||||
) +
|
||||
gsi::method ("subcircuit", (db::SubCircuit *(db::NetPinRef::*) ()) &db::NetPinRef::subcircuit,
|
||||
"@brief Gets the subcircuit reference.\n"
|
||||
"If the pin is a pin of a subcircuit, this attribute "
|
||||
"indicates the subcircuit the net attaches to. The "
|
||||
"subcircuit lives in the same circuit than the net. "
|
||||
"If the pin is a outgoing pin of the circuit, this "
|
||||
"attribute is nil."
|
||||
) +
|
||||
gsi::method ("net", (db::Net *(db::NetPinRef::*) ()) &db::NetPinRef::net,
|
||||
"@brief Gets the net this pin reference is attached to"
|
||||
),
|
||||
"@brief A connection to a pin of a subcircuit or an outgoing pin of the circuit.\n"
|
||||
"@brief A connection to an outgoing pin of the circuit.\n"
|
||||
"This object is used inside a net (see \\Net) to describe the connections a net makes.\n"
|
||||
"\n"
|
||||
"This class has been added in version 0.26."
|
||||
);
|
||||
|
||||
Class<db::NetSubcircuitPinRef> decl_dbNetSubcircuitPinRef ("db", "NetSubcircuitPinRef",
|
||||
gsi::method ("pin_id", &db::NetSubcircuitPinRef::pin_id,
|
||||
"@brief Gets the ID of the pin the connection is made to."
|
||||
) +
|
||||
gsi::method ("pin", &db::NetSubcircuitPinRef::pin,
|
||||
"@brief Gets the \\Pin object of the pin the connection is made to."
|
||||
) +
|
||||
gsi::method ("subcircuit", (db::SubCircuit *(db::NetSubcircuitPinRef::*) ()) &db::NetSubcircuitPinRef::subcircuit,
|
||||
"@brief Gets the subcircuit reference.\n"
|
||||
"This attribute indicates the subcircuit the net attaches to. The "
|
||||
"subcircuit lives in the same circuit than the net. "
|
||||
) +
|
||||
gsi::method ("net", (db::Net *(db::NetSubcircuitPinRef::*) ()) &db::NetSubcircuitPinRef::net,
|
||||
"@brief Gets the net this pin reference is attached to"
|
||||
),
|
||||
"@brief A connection to a pin of a subcircuit.\n"
|
||||
"This object is used inside a net (see \\Net) to describe the connections a net makes.\n"
|
||||
"\n"
|
||||
"This class has been added in version 0.26."
|
||||
|
|
@ -288,10 +301,14 @@ Class<db::Net> decl_dbNet ("db", "Net",
|
|||
"See \\cluster_id= for details about the cluster ID."
|
||||
) +
|
||||
gsi::iterator ("each_pin", (db::Net::pin_iterator (db::Net::*) ()) &db::Net::begin_pins, (db::Net::pin_iterator (db::Net::*) ()) &db::Net::end_pins,
|
||||
"@brief Iterates over all pins the net connects.\n"
|
||||
"@brief Iterates over all outgoing pins the net connects.\n"
|
||||
"Pin connections are described by \\NetPinRef objects. Pin connections "
|
||||
"are either connections to subcircuit pins or to outgoing pins of the "
|
||||
"circuit the net lives in."
|
||||
"are connections to outgoing pins of the circuit the net lives in."
|
||||
) +
|
||||
gsi::iterator ("each_subcircuit_pin", (db::Net::subcircuit_pin_iterator (db::Net::*) ()) &db::Net::begin_subcircuit_pins, (db::Net::subcircuit_pin_iterator (db::Net::*) ()) &db::Net::end_subcircuit_pins,
|
||||
"@brief Iterates over all subcircuit pins the net connects.\n"
|
||||
"Subcircuit pin connections are described by \\NetSubcircuitPinRef objects. These are "
|
||||
"connections to specific pins of subcircuits."
|
||||
) +
|
||||
gsi::iterator ("each_terminal", (db::Net::terminal_iterator (db::Net::*) ()) &db::Net::begin_terminals, (db::Net::terminal_iterator (db::Net::*) ()) &db::Net::end_terminals,
|
||||
"@brief Iterates over all terminals the net connects.\n"
|
||||
|
|
@ -307,7 +324,10 @@ Class<db::Net> decl_dbNet ("db", "Net",
|
|||
"Internal nets are those which connect exactly two terminals and nothing else (pin_count = 0 and terminal_count == 2)."
|
||||
) +
|
||||
gsi::method ("pin_count", &db::Net::pin_count,
|
||||
"@brief Returns the number of pins connected by this net.\n"
|
||||
"@brief Returns the number of outgoing pins connected by this net.\n"
|
||||
) +
|
||||
gsi::method ("subcircuit_pin_count", &db::Net::subcircuit_pin_count,
|
||||
"@brief Returns the number of subcircuit pins connected by this net.\n"
|
||||
) +
|
||||
gsi::method ("terminal_count", &db::Net::terminal_count,
|
||||
"@brief Returns the number of terminals connected by this net.\n"
|
||||
|
|
@ -765,10 +785,6 @@ Class<db::Circuit> decl_dbCircuit ("db", "Circuit",
|
|||
"@brief Gets the cell index of the circuit\n"
|
||||
"See \\cell_index= for details.\n"
|
||||
) +
|
||||
gsi::method ("is_external_net?", &db::Circuit::is_external_net, gsi::arg ("net"),
|
||||
"@brief Returns true, if the given net is an external one.\n"
|
||||
"External nets are nets which are connected to an outgoing pin."
|
||||
) +
|
||||
gsi::method ("net_for_pin", (db::Net *(db::Circuit::*) (size_t)) &db::Circuit::net_for_pin, gsi::arg ("pin_id"),
|
||||
"@brief Gets the net object attached to a specific pin.\n"
|
||||
"This is the net object inside the circuit which attaches to the given outward-bound pin.\n"
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ static void dump_recursive_nets_to_layout (const db::LayoutToNetlist &l2n, db::L
|
|||
for (db::Circuit::const_net_iterator n = c->begin_nets (); n != c->end_nets (); ++n) {
|
||||
|
||||
// only handle nets without outgoing pins - these are local
|
||||
if (c->is_external_net (n.operator-> ())) {
|
||||
if (n->pin_count () > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -165,12 +165,15 @@ static std::string net2string (const db::Net &n)
|
|||
if (! res.empty ()) {
|
||||
res += ",";
|
||||
}
|
||||
if (i->subcircuit ()) {
|
||||
res += i->subcircuit ()->circuit_ref () ? i->subcircuit ()->circuit_ref ()->name () : "(null)";
|
||||
res += ":";
|
||||
} else {
|
||||
res += "+";
|
||||
res += "+";
|
||||
res += i->pin () ? i->pin ()->name () : "(null)";
|
||||
}
|
||||
for (db::Net::const_subcircuit_pin_iterator i = n.begin_subcircuit_pins (); i != n.end_subcircuit_pins (); ++i) {
|
||||
if (! res.empty ()) {
|
||||
res += ",";
|
||||
}
|
||||
res += i->subcircuit ()->circuit_ref () ? i->subcircuit ()->circuit_ref ()->name () : "(null)";
|
||||
res += ":";
|
||||
res += i->pin () ? i->pin ()->name () : "(null)";
|
||||
}
|
||||
return res;
|
||||
|
|
@ -518,25 +521,25 @@ TEST(4_NetlistSubcircuits)
|
|||
c1->add_net (n1a);
|
||||
n1a->set_name ("n1a");
|
||||
n1a->add_pin (db::NetPinRef (0));
|
||||
n1a->add_pin (db::NetPinRef (sc1, 0));
|
||||
n1a->add_subcircuit_pin (db::NetSubcircuitPinRef (sc1, 0));
|
||||
|
||||
db::Net *n1b = new db::Net ();
|
||||
c1->add_net (n1b);
|
||||
n1b->set_name ("n1b");
|
||||
n1b->add_pin (db::NetPinRef (sc1, 1));
|
||||
n1b->add_pin (db::NetPinRef (sc2, 0));
|
||||
n1b->add_subcircuit_pin (db::NetSubcircuitPinRef (sc1, 1));
|
||||
n1b->add_subcircuit_pin (db::NetSubcircuitPinRef (sc2, 0));
|
||||
|
||||
db::Net *n1c = new db::Net ();
|
||||
c1->add_net (n1c);
|
||||
n1c->set_name ("n1c");
|
||||
n1c->add_pin (db::NetPinRef (sc2, 1));
|
||||
n1c->add_subcircuit_pin (db::NetSubcircuitPinRef (sc2, 1));
|
||||
n1c->add_pin (db::NetPinRef (1));
|
||||
|
||||
EXPECT_EQ (nl2string (*nl),
|
||||
"[c1]\n"
|
||||
"+c1p1,c2:c2p1\n"
|
||||
"c2:c2p2,c2:c2p1\n"
|
||||
"c2:c2p2,+c1p2\n"
|
||||
"+c1p2,c2:c2p2\n"
|
||||
"[c2]\n"
|
||||
"D:A,+c2p1\n"
|
||||
"D:B,+c2p2\n"
|
||||
|
|
@ -571,7 +574,7 @@ TEST(4_NetlistSubcircuits)
|
|||
"[c1]\n"
|
||||
"+c1p1,c2:c2p1\n"
|
||||
"c2:c2p2,c2:c2p1\n"
|
||||
"c2:c2p2,+c1p2\n"
|
||||
"+c1p2,c2:c2p2\n"
|
||||
"[c2]\n"
|
||||
"D:A,+c2p1\n"
|
||||
"D:B,+c2p2\n"
|
||||
|
|
@ -751,24 +754,25 @@ TEST(8_NetSubCircuitsEditing)
|
|||
n2->set_name ("n2");
|
||||
c.add_net (n2);
|
||||
|
||||
EXPECT_EQ (c.is_external_net (n1), false);
|
||||
EXPECT_EQ (n1->pin_count (), size_t (0));
|
||||
c.connect_pin (0, n1);
|
||||
|
||||
EXPECT_EQ (n1->terminal_count (), size_t (0));
|
||||
EXPECT_EQ (n1->pin_count (), size_t (1));
|
||||
EXPECT_EQ (n1->is_floating (), true);
|
||||
EXPECT_EQ (n1->is_internal (), false);
|
||||
EXPECT_EQ (c.is_external_net (n1), true);
|
||||
EXPECT_NE (n1->pin_count (), size_t (0));
|
||||
|
||||
EXPECT_EQ (c.net_for_pin (0), n1);
|
||||
EXPECT_EQ (c.net_for_pin (1), 0);
|
||||
|
||||
sc1->connect_pin (0, n1);
|
||||
sc1->connect_pin (1, n2);
|
||||
EXPECT_EQ (c.is_external_net (n2), false);
|
||||
EXPECT_EQ (n2->pin_count (), size_t (0));
|
||||
|
||||
EXPECT_EQ (n1->terminal_count (), size_t (0));
|
||||
EXPECT_EQ (n1->pin_count (), size_t (2));
|
||||
EXPECT_EQ (n1->pin_count (), size_t (1));
|
||||
EXPECT_EQ (n1->subcircuit_pin_count (), size_t (1));
|
||||
EXPECT_EQ (n1->is_floating (), false);
|
||||
EXPECT_EQ (n1->is_internal (), false);
|
||||
|
||||
|
|
@ -814,7 +818,7 @@ TEST(8_NetSubCircuitsEditing)
|
|||
EXPECT_EQ (net2string (*n2), "sc2:A");
|
||||
|
||||
c.connect_pin (1, n1);
|
||||
EXPECT_EQ (net2string (*n1), "sc2:B,+Y");
|
||||
EXPECT_EQ (net2string (*n1), "+Y,sc2:B");
|
||||
EXPECT_EQ (c.net_for_pin (1), n1);
|
||||
|
||||
delete n1;
|
||||
|
|
@ -849,14 +853,14 @@ TEST(10_NetPinRefBasics)
|
|||
{
|
||||
db::SubCircuit d1, d2;
|
||||
|
||||
EXPECT_EQ (db::NetPinRef (&d1, 0) == db::NetPinRef (&d1, 0), true);
|
||||
EXPECT_EQ (db::NetPinRef (&d1, 0) == db::NetPinRef (&d1, 1), false);
|
||||
EXPECT_EQ (db::NetPinRef (&d1, 0) == db::NetPinRef (&d2, 0), false);
|
||||
EXPECT_EQ (db::NetSubcircuitPinRef (&d1, 0) == db::NetSubcircuitPinRef (&d1, 0), true);
|
||||
EXPECT_EQ (db::NetSubcircuitPinRef (&d1, 0) == db::NetSubcircuitPinRef (&d1, 1), false);
|
||||
EXPECT_EQ (db::NetSubcircuitPinRef (&d1, 0) == db::NetSubcircuitPinRef (&d2, 0), false);
|
||||
|
||||
EXPECT_EQ (db::NetPinRef (&d1, 0) < db::NetPinRef (&d1, 0), false);
|
||||
EXPECT_EQ (db::NetPinRef (&d1, 0) < db::NetPinRef (&d1, 1), true);
|
||||
EXPECT_EQ (db::NetPinRef (&d1, 1) < db::NetPinRef (&d1, 0), false);
|
||||
EXPECT_NE ((db::NetPinRef (&d1, 0) < db::NetPinRef (&d2, 0)), (db::NetPinRef (&d2, 0) < db::NetPinRef (&d1, 0)));
|
||||
EXPECT_EQ (db::NetSubcircuitPinRef (&d1, 0) < db::NetSubcircuitPinRef (&d1, 0), false);
|
||||
EXPECT_EQ (db::NetSubcircuitPinRef (&d1, 0) < db::NetSubcircuitPinRef (&d1, 1), true);
|
||||
EXPECT_EQ (db::NetSubcircuitPinRef (&d1, 1) < db::NetSubcircuitPinRef (&d1, 0), false);
|
||||
EXPECT_NE ((db::NetSubcircuitPinRef (&d1, 0) < db::NetSubcircuitPinRef (&d2, 0)), (db::NetSubcircuitPinRef (&d2, 0) < db::NetSubcircuitPinRef (&d1, 0)));
|
||||
}
|
||||
|
||||
TEST(11_NetlistCircuitRefs)
|
||||
|
|
|
|||
|
|
@ -330,7 +330,8 @@ class DBNetlist_TestClass < TestBase
|
|||
assert_equal(net.is_internal?, false)
|
||||
|
||||
sc1.connect_pin(1, net)
|
||||
assert_equal(net.pin_count, 1)
|
||||
assert_equal(net.pin_count, 0)
|
||||
assert_equal(net.subcircuit_pin_count, 1)
|
||||
assert_equal(net.terminal_count, 0)
|
||||
assert_equal(net.is_floating?, true)
|
||||
assert_equal(net.is_internal?, false)
|
||||
|
|
@ -338,16 +339,19 @@ class DBNetlist_TestClass < TestBase
|
|||
assert_equal(sc1.net_for_pin(0).inspect, "nil")
|
||||
|
||||
sc2.connect_pin(0, net)
|
||||
assert_equal(net.pin_count, 2)
|
||||
assert_equal(net.pin_count, 0)
|
||||
assert_equal(net.subcircuit_pin_count, 2)
|
||||
assert_equal(net.terminal_count, 0)
|
||||
assert_equal(net.is_floating?, false)
|
||||
assert_equal(net.is_internal?, false)
|
||||
|
||||
cnames = []
|
||||
net.each_pin { |p| cnames << p.subcircuit.name + ":" + p.pin.name }
|
||||
net.each_pin { |p| cnames << "+" + p.pin.name }
|
||||
net.each_subcircuit_pin { |p| cnames << p.subcircuit.name + ":" + p.pin.name }
|
||||
assert_equal(cnames, [ "SC1:B", "SC2:A" ])
|
||||
cnames = []
|
||||
net.each_pin { |p| cnames << p.subcircuit.name + ":" + p.pin_id.to_s }
|
||||
net.each_pin { |p| cnames << "+" + p.pin.name }
|
||||
net.each_subcircuit_pin { |p| cnames << p.subcircuit.name + ":" + p.pin_id.to_s }
|
||||
assert_equal(cnames, [ "SC1:1", "SC2:0" ])
|
||||
net.each_pin { |p| assert_equal(p.net.name, "NET") }
|
||||
|
||||
|
|
@ -355,9 +359,10 @@ class DBNetlist_TestClass < TestBase
|
|||
assert_equal(sc1.net_for_pin(1).inspect, "nil")
|
||||
|
||||
cnames = []
|
||||
net.each_pin { |p| cnames << p.subcircuit.name + ":" + p.pin.name }
|
||||
net.each_pin { |p| cnames << "+" + p.pin.name }
|
||||
net.each_subcircuit_pin { |p| cnames << p.subcircuit.name + ":" + p.pin.name }
|
||||
assert_equal(cnames, [ "SC2:A" ])
|
||||
net.each_pin { |p| assert_equal(p.net.name, "NET") }
|
||||
net.each_subcircuit_pin { |p| assert_equal(p.net.name, "NET") }
|
||||
|
||||
net.clear
|
||||
assert_equal(sc1.net_for_pin(1).inspect, "nil")
|
||||
|
|
@ -510,9 +515,13 @@ class DBNetlist_TestClass < TestBase
|
|||
c.each_net { |n| names << n.name }
|
||||
assert_equal(names, [ "NET1", "NET2" ])
|
||||
|
||||
assert_equal(c.is_external_net?(net1), false)
|
||||
assert_equal(net1.pin_count, 0)
|
||||
c.connect_pin(pina1, net1)
|
||||
assert_equal(c.is_external_net?(net1), true)
|
||||
cnames = []
|
||||
net1.each_pin { |p| cnames << "+" + p.pin.name }
|
||||
net1.each_subcircuit_pin { |p| cnames << p.subcircuit.name + ":" + p.pin.name }
|
||||
assert_equal(cnames, [ "+A1" ])
|
||||
assert_equal(net1.pin_count, 1)
|
||||
c.connect_pin(pinb1.id, net1)
|
||||
c.connect_pin(pina2, net2)
|
||||
c.connect_pin(pinb2.id, net2)
|
||||
|
|
|
|||
Loading…
Reference in New Issue