mirror of https://github.com/KLayout/klayout.git
WIP
This commit is contained in:
parent
c4fb287eb7
commit
befbde0f43
|
|
@ -1001,6 +1001,8 @@ local_clusters<T>::mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpo
|
|||
db::mem_stat (stat, purpose, cat, m_bbox, true, (void *) this);
|
||||
db::mem_stat (stat, purpose, cat, m_clusters, true, (void *) this);
|
||||
db::mem_stat (stat, purpose, cat, m_next_dummy_id, true, (void *) this);
|
||||
db::mem_stat (stat, purpose, cat, m_soft_connections, true, (void *) this);
|
||||
db::mem_stat (stat, purpose, cat, m_soft_connections_rev, true, (void *) this);
|
||||
}
|
||||
|
||||
namespace
|
||||
|
|
@ -1268,6 +1270,10 @@ private:
|
|||
|
||||
void join (typename std::list<cluster_value>::iterator ic1, typename std::list<cluster_value>::iterator ic2)
|
||||
{
|
||||
if (ic1 == ic2) {
|
||||
return;
|
||||
}
|
||||
|
||||
ic1->first.insert (ic1->first.end (), ic2->first.begin (), ic2->first.end ());
|
||||
ic1->second.insert (ic2->second.begin (), ic2->second.end ());
|
||||
|
||||
|
|
@ -1280,21 +1286,35 @@ private:
|
|||
|
||||
m_clusters.erase (ic2);
|
||||
|
||||
auto i1 = m_soft_connections.find (std::make_pair (ic1.operator-> (), ic2.operator-> ()));
|
||||
if (i1 != m_soft_connections.end ()) {
|
||||
i1->second = 0;
|
||||
// remap soft connections: remove soft connections between ic1 and ic2 and
|
||||
// remap ic2 connections to ic1 as first
|
||||
|
||||
auto i2 = m_soft_connections.lower_bound (std::make_pair (ic2.operator-> (), (const cluster_value *) 0));
|
||||
for (auto i = i2; i != m_soft_connections.end () && i->first.first == ic2.operator-> (); ++i) {
|
||||
m_soft_connections.erase (std::make_pair (i->first.second, i->first.first));
|
||||
}
|
||||
|
||||
auto i2 = m_soft_connections.find (std::make_pair (ic2.operator-> (), ic1.operator-> ()));
|
||||
if (i2 != m_soft_connections.end ()) {
|
||||
i2->second = 0;
|
||||
for (auto i = i2; i != m_soft_connections.end () && i->first.first == ic2.operator-> (); ++i) {
|
||||
if (i->first.second != ic1.operator-> ()) {
|
||||
register_soft_connection (ic1.operator-> (), i->first.second, i->second);
|
||||
}
|
||||
}
|
||||
|
||||
auto i2_from = i2;
|
||||
for ( ; i2 != m_soft_connections.end () && i2->first.first == ic2.operator-> (); ++i2)
|
||||
;
|
||||
m_soft_connections.erase (i2_from, i2);
|
||||
}
|
||||
|
||||
void register_soft_connection (typename std::list<cluster_value>::iterator ic1, typename std::list<cluster_value>::iterator ic2, int soft)
|
||||
{
|
||||
auto i1 = m_soft_connections.find (std::make_pair (ic1.operator-> (), ic2.operator-> ()));
|
||||
auto i2 = m_soft_connections.find (std::make_pair (ic2.operator-> (), ic1.operator-> ()));
|
||||
register_soft_connection (ic1.operator-> (), ic2.operator-> (), soft);
|
||||
}
|
||||
|
||||
void register_soft_connection (const cluster_value *c1, const cluster_value *c2, int soft)
|
||||
{
|
||||
auto i1 = m_soft_connections.find (std::make_pair (c1, c2));
|
||||
auto i2 = m_soft_connections.find (std::make_pair (c2, c1));
|
||||
|
||||
if (i1 != m_soft_connections.end () && i1->second != 0 && i1->second != soft) {
|
||||
i1->second = 0;
|
||||
|
|
@ -1305,8 +1325,8 @@ private:
|
|||
|
||||
if (i1 == m_soft_connections.end ()) {
|
||||
tl_assert (i2 == m_soft_connections.end ());
|
||||
m_soft_connections.insert (std::make_pair (std::make_pair (ic1.operator-> (), ic2.operator-> ()), soft));
|
||||
m_soft_connections.insert (std::make_pair (std::make_pair (ic2.operator-> (), ic1.operator-> ()), -soft));
|
||||
m_soft_connections.insert (std::make_pair (std::make_pair (c1, c2), soft));
|
||||
m_soft_connections.insert (std::make_pair (std::make_pair (c2, c1), -soft));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -338,7 +338,7 @@ public:
|
|||
bool interacts (const db::Cell &cell, const db::ICplxTrans &trans, const Connectivity &conn) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the bounding box of this cluster
|
||||
* @brief Gets the bounding box ofF this cluster
|
||||
*/
|
||||
const box_type &bbox () const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "dbLayoutToNetlistFormatDefs.h"
|
||||
#include "dbLayoutVsSchematicFormatDefs.h"
|
||||
#include "dbShapeProcessor.h"
|
||||
#include "dbNetlistDeviceClasses.h"
|
||||
#include "dbLog.h"
|
||||
#include "tlGlobPattern.h"
|
||||
|
||||
|
|
@ -425,7 +426,9 @@ void LayoutToNetlist::extract_netlist ()
|
|||
netex.extract_nets (dss (), m_layout_index, m_conn, *mp_netlist, m_net_clusters);
|
||||
|
||||
// @@@ NOTE: can we have multiple pins on a net? Will this happen later maybe?
|
||||
// @@@ do_soft_connections ()
|
||||
tl_assert (check_many_pins (mp_netlist.get ())); // @@@
|
||||
do_soft_connections ();
|
||||
tl_assert (check_many_pins (mp_netlist.get ())); // @@@
|
||||
do_join_nets ();
|
||||
tl_assert (check_many_pins (mp_netlist.get ())); // @@@
|
||||
|
||||
|
|
@ -640,6 +643,42 @@ void LayoutToNetlist::check_must_connect_impl (const db::Circuit &c, const db::N
|
|||
}
|
||||
}
|
||||
|
||||
void LayoutToNetlist::do_soft_connections ()
|
||||
{
|
||||
|
||||
// @@@ NetlistLocker locked_netlist (mp_netlist.get ());
|
||||
|
||||
db::DeviceClassDiode *soft_diode = new db::DeviceClassDiode ();
|
||||
soft_diode->set_name ("SOFT");
|
||||
mp_netlist->add_device_class (soft_diode);
|
||||
|
||||
for (auto c = mp_netlist->begin_bottom_up (); c != mp_netlist->end_bottom_up (); ++c) {
|
||||
|
||||
// @@@ create diodes as of now
|
||||
|
||||
auto clusters = net_clusters ().clusters_per_cell (c->cell_index ());
|
||||
|
||||
for (auto n = c->begin_nets (); n != c->end_nets (); ++n) {
|
||||
|
||||
auto soft_connections = clusters.upward_soft_connections (n->cluster_id ());
|
||||
for (auto sc = soft_connections.begin (); sc != soft_connections.end (); ++sc) {
|
||||
|
||||
db::Device *sc_device = new db::Device (soft_diode);
|
||||
c->add_device (sc_device);
|
||||
|
||||
auto nn = c->net_by_cluster_id (*sc);
|
||||
if (nn) {
|
||||
sc_device->connect_terminal (db::DeviceClassDiode::terminal_id_C, n.operator-> ());
|
||||
sc_device->connect_terminal (db::DeviceClassDiode::terminal_id_A, nn);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutToNetlist::do_join_nets ()
|
||||
{
|
||||
if (! mp_netlist) {
|
||||
|
|
|
|||
|
|
@ -1093,6 +1093,7 @@ private:
|
|||
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 do_soft_connections ();
|
||||
void join_nets_from_pattern (db::Circuit &c, const tl::GlobPattern &p);
|
||||
void join_nets_from_pattern (db::Circuit &c, const std::set<std::string> &p);
|
||||
void check_must_connect (const db::Circuit &c, const db::Net &a, const db::Net &b);
|
||||
|
|
|
|||
|
|
@ -288,7 +288,9 @@ NetlistExtractor::extract_nets (const db::DeepShapeStore &dss, unsigned int layo
|
|||
|
||||
const db::local_cluster<db::NetShape> &lc = clusters.cluster_by_id (*c);
|
||||
const connected_clusters_type::connections_type &cc = clusters.connections_for_cluster (*c);
|
||||
if (cc.empty () && lc.empty ()) {
|
||||
const std::set<size_t> &sc_up = clusters.upward_soft_connections (*c);
|
||||
const std::set<size_t> &sc_down = clusters.downward_soft_connections (*c);
|
||||
if (cc.empty () && sc_up.empty () && sc_down.empty () && lc.empty ()) {
|
||||
// this is an entirely empty cluster so we skip it.
|
||||
// Such clusters are left over when joining clusters.
|
||||
continue;
|
||||
|
|
|
|||
Loading…
Reference in New Issue