mirror of https://github.com/KLayout/klayout.git
WIP: reimplementing connect_implicit on netlist basis
This commit is contained in:
parent
033d630992
commit
e7a8569052
|
|
@ -366,14 +366,11 @@ void Circuit::remove_net (Net *net)
|
|||
|
||||
void Circuit::join_nets (Net *net, Net *with)
|
||||
{
|
||||
if (! net) {
|
||||
return;
|
||||
}
|
||||
if (net == with || ! with) {
|
||||
if (net == with || ! with || ! net) {
|
||||
return;
|
||||
}
|
||||
if (net->circuit () != this || with->circuit () != this) {
|
||||
throw tl::Exception (tl::to_string (tr ("Nets not withing given circuit")));
|
||||
throw tl::Exception (tl::to_string (tr ("Nets not within given circuit")));
|
||||
}
|
||||
|
||||
while (with->begin_terminals () != with->end_terminals ()) {
|
||||
|
|
@ -390,7 +387,6 @@ void Circuit::join_nets (Net *net, Net *with)
|
|||
connect_pin (with->begin_pins ()->pin_id (), net);
|
||||
}
|
||||
|
||||
// TODO: join clusters too, join net properties(?)
|
||||
if (netlist ()->callbacks ()) {
|
||||
netlist ()->callbacks ()->link_nets (net, with);
|
||||
}
|
||||
|
|
@ -676,7 +672,42 @@ void Circuit::connect_pin (size_t pin_id, Net *net)
|
|||
}
|
||||
|
||||
if (net) {
|
||||
net->add_pin (NetPinRef (pin_id));
|
||||
if (net->begin_pins () != net->end_pins ()) {
|
||||
join_pins (net->begin_pins ()->pin_id (), pin_id);
|
||||
} else {
|
||||
net->add_pin (NetPinRef (pin_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Circuit::join_pins (size_t pin, size_t with)
|
||||
{
|
||||
if (with < m_pin_by_id.size () && ! tl::is_null_iterator (m_pin_by_id [with])) {
|
||||
|
||||
m_pins.erase (m_pin_by_id [with]);
|
||||
m_pin_by_id.erase (m_pin_by_id.begin () + with);
|
||||
m_pin_refs.erase (m_pin_refs.begin () + with);
|
||||
|
||||
// join nets in calls
|
||||
for (auto s = begin_refs (); s != end_refs (); ++s) {
|
||||
|
||||
db::SubCircuit &sc = *s;
|
||||
|
||||
db::Net *with_net = sc.net_for_pin (with);
|
||||
// remove the subcircuit pin reference from the "with" net
|
||||
for (auto sc_pin = with_net->begin_subcircuit_pins (); sc_pin != with_net->end_subcircuit_pins (); ++sc_pin) {
|
||||
if (sc_pin->subcircuit () == &sc && sc_pin->pin_id () == with) {
|
||||
with_net->erase_subcircuit_pin (sc_pin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sc.circuit ()->join_nets (sc.net_for_pin (pin), with_net);
|
||||
|
||||
sc.erase_pin_ref (with);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -819,7 +819,7 @@ private:
|
|||
bool combine_parallel_devices (const db::DeviceClass &cls);
|
||||
bool combine_serial_devices (const db::DeviceClass &cls);
|
||||
void do_purge_nets (bool keep_pins);
|
||||
|
||||
void join_pins (size_t pin_id, size_t with);
|
||||
void devices_changed ();
|
||||
void subcircuits_changed ();
|
||||
void nets_changed ();
|
||||
|
|
|
|||
|
|
@ -414,7 +414,7 @@ void LayoutToNetlist::extract_netlist ()
|
|||
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 ();
|
||||
do_join_nets ();
|
||||
|
||||
if (tl::verbosity () >= 41) {
|
||||
MemStatisticsCollector m (false);
|
||||
|
|
@ -425,6 +425,102 @@ void LayoutToNetlist::extract_netlist ()
|
|||
m_netlist_extracted = true;
|
||||
}
|
||||
|
||||
static std::vector<db::Net *> nets_from_pattern (db::Circuit &c, const tl::GlobPattern &p)
|
||||
{
|
||||
std::vector<db::Net *> result;
|
||||
for (auto n = c.begin_nets (); n != c.end_nets (); ++n) {
|
||||
if (p.match (n->name ())) {
|
||||
result.push_back (n.operator-> ());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::vector<db::Net *> nets_from_pattern (db::Circuit &c, const std::set<std::string> &p)
|
||||
{
|
||||
std::vector<db::Net *> result;
|
||||
for (auto n = p.begin (); n != p.end (); ++n) {
|
||||
db::Net *net = c.net_by_name (*n);
|
||||
if (net) {
|
||||
result.push_back (net);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void LayoutToNetlist::do_join_nets (db::Circuit &c, const std::vector<db::Net *> &nets)
|
||||
{
|
||||
if (nets.size () <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::set<std::string> names;
|
||||
for (auto n = nets.begin (); n != nets.end (); ++n) {
|
||||
if (! (*n)->name ().empty ()) {
|
||||
names.insert ((*n)->name ());
|
||||
}
|
||||
}
|
||||
|
||||
nets [0]->set_name (tl::join (names.begin (), names.end (), ","));
|
||||
|
||||
for (auto n = nets.begin () + 1; n != nets.end (); ++n) {
|
||||
c.join_nets (nets [0], *n);
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutToNetlist::do_join_nets ()
|
||||
{
|
||||
if (! mp_netlist) {
|
||||
return;
|
||||
}
|
||||
|
||||
// prevents updates
|
||||
NetlistLocker locked_netlist (mp_netlist.get ());
|
||||
|
||||
for (auto jn = m_joined_net_names.begin (); jn != m_joined_net_names.end (); ++jn) {
|
||||
for (auto c = mp_netlist->begin_top_down (); c != mp_netlist->end_top_down (); ++c) {
|
||||
do_join_nets (*c, nets_from_pattern (*c, *jn));
|
||||
}
|
||||
}
|
||||
|
||||
for (auto jn = m_joined_nets.begin (); jn != m_joined_nets.end (); ++jn) {
|
||||
for (auto c = mp_netlist->begin_top_down (); c != mp_netlist->end_top_down (); ++c) {
|
||||
do_join_nets (*c, nets_from_pattern (*c, *jn));
|
||||
}
|
||||
}
|
||||
|
||||
for (auto jn = m_joined_net_names_per_cell.begin (); jn != m_joined_net_names_per_cell.end (); ++jn) {
|
||||
for (auto c = mp_netlist->begin_top_down (); c != mp_netlist->end_top_down (); ++c) {
|
||||
if (jn->first.match (c->name ())) {
|
||||
do_join_nets (*c, nets_from_pattern (*c, jn->second));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto jn = m_joined_nets_per_cell.begin (); jn != m_joined_nets_per_cell.end (); ++jn) {
|
||||
for (auto c = mp_netlist->begin_top_down (); c != mp_netlist->end_top_down (); ++c) {
|
||||
if (jn->first.match (c->name ())) {
|
||||
do_join_nets (*c, nets_from_pattern (*c, jn->second));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutToNetlist::error (const std::string &msg)
|
||||
{
|
||||
m_log_entries.push_back (db::LogEntryData (db::Error, msg));
|
||||
}
|
||||
|
||||
void LayoutToNetlist::warn (const std::string &msg)
|
||||
{
|
||||
m_log_entries.push_back (db::LogEntryData (db::Warning, msg));
|
||||
}
|
||||
|
||||
void LayoutToNetlist::info (const std::string &msg)
|
||||
{
|
||||
m_log_entries.push_back (db::LogEntryData (db::Info, msg));
|
||||
}
|
||||
|
||||
void LayoutToNetlist::mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self, void *parent) const
|
||||
{
|
||||
if (! no_self) {
|
||||
|
|
|
|||
|
|
@ -993,6 +993,11 @@ private:
|
|||
void connect_impl (const db::ShapeCollection &a, const db::ShapeCollection &b);
|
||||
size_t connect_global_impl (const db::ShapeCollection &l, const std::string &gn);
|
||||
bool is_persisted_impl (const db::ShapeCollection &coll) const;
|
||||
void do_join_nets (db::Circuit &c, const std::vector<Net *> &nets);
|
||||
void do_join_nets ();
|
||||
void error (const std::string &msg);
|
||||
void warn (const std::string &msg);
|
||||
void info (const std::string &msg);
|
||||
|
||||
// implementation of NetlistManipulationCallbacks
|
||||
virtual size_t link_net_to_parent_circuit (const Net *subcircuit_net, Circuit *parent_circuit, const DCplxTrans &trans);
|
||||
|
|
|
|||
|
|
@ -90,6 +90,11 @@ void SubCircuit::set_trans (const db::DCplxTrans &t)
|
|||
m_trans = t;
|
||||
}
|
||||
|
||||
void SubCircuit::erase_pin_ref (size_t pin_id)
|
||||
{
|
||||
m_pin_refs.erase (m_pin_refs.begin () + pin_id);
|
||||
}
|
||||
|
||||
void SubCircuit::set_pin_ref_for_pin (size_t pin_id, Net::subcircuit_pin_iterator iter)
|
||||
{
|
||||
if (m_pin_refs.size () < pin_id + 1) {
|
||||
|
|
|
|||
|
|
@ -230,6 +230,11 @@ private:
|
|||
*/
|
||||
void set_circuit_ref (Circuit *c);
|
||||
|
||||
/**
|
||||
* @brief Erases the given pin reference
|
||||
*/
|
||||
void erase_pin_ref (size_t pin_id);
|
||||
|
||||
/**
|
||||
* @brief Sets the circuit the subcircuit belongs to
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue