mirror of https://github.com/KLayout/klayout.git
WIP: tried to provide a more consistent net building feature (here: building hierarchical nets with properties as net annotation - needs cell variants if properties are assigned to subcells too)
This commit is contained in:
parent
2aaec56adb
commit
548f16f1df
|
|
@ -608,16 +608,16 @@ db::Region *LayoutToNetlist::shapes_of_net (const db::Net &net, const db::Region
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LayoutToNetlist::build_net_rec (const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const char *net_cell_name_prefix, db::properties_id_type netname_propid, BuildNetHierarchyMode hier_mode, const char *cell_name_prefix, const char *device_cell_name_prefix, std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> &cmap, const db::ICplxTrans &tr) const
|
LayoutToNetlist::build_net_rec (const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const char *net_cell_name_prefix, db::properties_id_type netname_propid, BuildNetHierarchyMode hier_mode, const char *cell_name_prefix, const char *device_cell_name_prefix, cell_reuse_table_type &reuse_table, const db::ICplxTrans &tr) const
|
||||||
{
|
{
|
||||||
const db::Circuit *circuit = net.circuit ();
|
const db::Circuit *circuit = net.circuit ();
|
||||||
tl_assert (circuit != 0);
|
tl_assert (circuit != 0);
|
||||||
|
|
||||||
build_net_rec (circuit->cell_index (), net.cluster_id (), target, target_cell, lmap, &net, net_cell_name_prefix, netname_propid, hier_mode, cell_name_prefix, device_cell_name_prefix, cmap, tr);
|
build_net_rec (circuit->cell_index (), net.cluster_id (), target, target_cell, lmap, &net, net_cell_name_prefix, netname_propid, hier_mode, cell_name_prefix, device_cell_name_prefix, reuse_table, tr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &target, db::Cell &tc, const std::map<unsigned int, const db::Region *> &lmap, const db::Net *net, const char *net_cell_name_prefix, db::properties_id_type netname_propid, BuildNetHierarchyMode hier_mode, const char *circuit_cell_name_prefix, const char *device_cell_name_prefix, std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> &cmap, const db::ICplxTrans &tr) const
|
LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &target, db::Cell &tc, const std::map<unsigned int, const db::Region *> &lmap, const db::Net *net, const char *net_cell_name_prefix, db::properties_id_type netname_propid, BuildNetHierarchyMode hier_mode, const char *circuit_cell_name_prefix, const char *device_cell_name_prefix, cell_reuse_table_type &reuse_table, const db::ICplxTrans &tr) const
|
||||||
{
|
{
|
||||||
db::Cell *target_cell = &tc;
|
db::Cell *target_cell = &tc;
|
||||||
|
|
||||||
|
|
@ -673,8 +673,10 @@ LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &
|
||||||
db::cell_index_type subci = c->inst_cell_index ();
|
db::cell_index_type subci = c->inst_cell_index ();
|
||||||
size_t subcid = c->id ();
|
size_t subcid = c->id ();
|
||||||
|
|
||||||
std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type>::const_iterator cm = cmap.find (std::make_pair (subci, subcid));
|
CellReuseTableKey cmap_key (subci, netname_propid, subcid);
|
||||||
if (cm == cmap.end ()) {
|
|
||||||
|
cell_reuse_table_type::const_iterator cm = reuse_table.find (cmap_key);
|
||||||
|
if (cm == reuse_table.end ()) {
|
||||||
|
|
||||||
const char *name_prefix = 0;
|
const char *name_prefix = 0;
|
||||||
if (mp_netlist->device_abstract_by_cell_index (subci)) {
|
if (mp_netlist->device_abstract_by_cell_index (subci)) {
|
||||||
|
|
@ -688,12 +690,12 @@ LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &
|
||||||
std::string cell_name = internal_layout ()->cell_name (subci);
|
std::string cell_name = internal_layout ()->cell_name (subci);
|
||||||
|
|
||||||
db::cell_index_type target_ci = target.add_cell ((std::string (name_prefix) + cell_name).c_str ());
|
db::cell_index_type target_ci = target.add_cell ((std::string (name_prefix) + cell_name).c_str ());
|
||||||
cm = cmap.insert (std::make_pair (std::make_pair (subci, subcid), target_ci)).first;
|
cm = reuse_table.insert (std::make_pair (cmap_key, target_ci)).first;
|
||||||
|
|
||||||
build_net_rec (subci, subcid, target, target.cell (target_ci), lmap, 0, 0, netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, cmap, tr_mag);
|
build_net_rec (subci, subcid, target, target.cell (target_ci), lmap, 0, 0, netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, reuse_table, tr_mag);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
cm = cmap.insert (std::make_pair (std::make_pair (subci, subcid), std::numeric_limits<db::cell_index_type>::max ())).first;
|
cm = reuse_table.insert (std::make_pair (cmap_key, std::numeric_limits<db::cell_index_type>::max ())).first;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -730,12 +732,12 @@ LayoutToNetlist::build_net (const db::Net &net, db::Layout &target, db::Cell &ta
|
||||||
throw tl::Exception (tl::to_string (tr ("The netlist has not been extracted yet")));
|
throw tl::Exception (tl::to_string (tr ("The netlist has not been extracted yet")));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> cell_map;
|
cell_reuse_table_type cell_reuse_table;
|
||||||
|
|
||||||
double mag = internal_layout ()->dbu () / target.dbu ();
|
double mag = internal_layout ()->dbu () / target.dbu ();
|
||||||
|
|
||||||
db::properties_id_type netname_propid = make_netname_propid (target, netname_prop, net);
|
db::properties_id_type netname_propid = make_netname_propid (target, netname_prop, net);
|
||||||
build_net_rec (net, target, target_cell, lmap, 0, netname_propid, hier_mode, cell_name_prefix, device_cell_name_prefix, cell_map, db::ICplxTrans (mag));
|
build_net_rec (net, target, target_cell, lmap, 0, netname_propid, hier_mode, cell_name_prefix, device_cell_name_prefix, cell_reuse_table, db::ICplxTrans (mag));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -745,7 +747,7 @@ LayoutToNetlist::build_all_nets (const db::CellMapping &cmap, db::Layout &target
|
||||||
throw tl::Exception (tl::to_string (tr ("The netlist has not been extracted yet")));
|
throw tl::Exception (tl::to_string (tr ("The netlist has not been extracted yet")));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> cell_map;
|
cell_reuse_table_type cell_reuse_table;
|
||||||
double mag = internal_layout ()->dbu () / target.dbu ();
|
double mag = internal_layout ()->dbu () / target.dbu ();
|
||||||
|
|
||||||
const db::Netlist *netlist = mp_netlist.get ();
|
const db::Netlist *netlist = mp_netlist.get ();
|
||||||
|
|
@ -767,7 +769,7 @@ LayoutToNetlist::build_all_nets (const db::CellMapping &cmap, db::Layout &target
|
||||||
}
|
}
|
||||||
|
|
||||||
db::properties_id_type netname_propid = make_netname_propid (target, netname_prop, *n);
|
db::properties_id_type netname_propid = make_netname_propid (target, netname_prop, *n);
|
||||||
build_net_rec (*n, target, target.cell (target_ci), lmap, net_cell_name_prefix, netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, cell_map, db::ICplxTrans (mag));
|
build_net_rec (*n, target, target.cell (target_ci), lmap, net_cell_name_prefix, netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, cell_reuse_table, db::ICplxTrans (mag));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -796,9 +798,9 @@ LayoutToNetlist::build_all_nets (const db::CellMapping &cmap, db::Layout &target
|
||||||
|
|
||||||
if (net_cell_name_prefix) {
|
if (net_cell_name_prefix) {
|
||||||
std::string ncn = std::string (net_cell_name_prefix) + subcircuit.expanded_name () + ":";
|
std::string ncn = std::string (net_cell_name_prefix) + subcircuit.expanded_name () + ":";
|
||||||
build_net_rec (*n, target, target.cell (target_ci), lmap, ncn.c_str (), netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, cell_map, tr);
|
build_net_rec (*n, target, target.cell (target_ci), lmap, ncn.c_str (), netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, cell_reuse_table, tr);
|
||||||
} else {
|
} else {
|
||||||
build_net_rec (*n, target, target.cell (target_ci), lmap, net_cell_name_prefix, netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, cell_map, tr);
|
build_net_rec (*n, target, target.cell (target_ci), lmap, net_cell_name_prefix, netname_propid, hier_mode, circuit_cell_name_prefix, device_cell_name_prefix, cell_reuse_table, tr);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -675,10 +675,39 @@ private:
|
||||||
bool m_is_flat;
|
bool m_is_flat;
|
||||||
db::DeepLayer m_dummy_layer;
|
db::DeepLayer m_dummy_layer;
|
||||||
|
|
||||||
|
struct CellReuseTableKey
|
||||||
|
{
|
||||||
|
CellReuseTableKey (db::cell_index_type _cell_index, db::properties_id_type _netname_propid, size_t _cluster_id)
|
||||||
|
: cell_index (_cell_index), netname_propid (_netname_propid), cluster_id (_cluster_id)
|
||||||
|
{
|
||||||
|
// .. nothing yet ..
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator< (const CellReuseTableKey &other) const
|
||||||
|
{
|
||||||
|
if (cell_index != other.cell_index) {
|
||||||
|
return cell_index < other.cell_index;
|
||||||
|
}
|
||||||
|
if (netname_propid != other.netname_propid) {
|
||||||
|
return netname_propid < other.netname_propid;
|
||||||
|
}
|
||||||
|
if (cluster_id != other.cluster_id) {
|
||||||
|
return cluster_id < other.cluster_id;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
db::cell_index_type cell_index;
|
||||||
|
db::properties_id_type netname_propid;
|
||||||
|
size_t cluster_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::map<CellReuseTableKey, db::cell_index_type> cell_reuse_table_type;
|
||||||
|
|
||||||
void init ();
|
void init ();
|
||||||
size_t search_net (const db::ICplxTrans &trans, const db::Cell *cell, const db::local_cluster<db::PolygonRef> &test_cluster, std::vector<db::InstElement> &rev_inst_path);
|
size_t search_net (const db::ICplxTrans &trans, const db::Cell *cell, const db::local_cluster<db::PolygonRef> &test_cluster, std::vector<db::InstElement> &rev_inst_path);
|
||||||
void build_net_rec (const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const char *net_cell_name_prefix, db::properties_id_type netname_propid, BuildNetHierarchyMode hier_mode, const char *cell_name_prefix, const char *device_cell_name_prefix, std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> &cmap, const ICplxTrans &tr) const;
|
void build_net_rec (const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const char *net_cell_name_prefix, db::properties_id_type netname_propid, BuildNetHierarchyMode hier_mode, const char *cell_name_prefix, const char *device_cell_name_prefix, cell_reuse_table_type &reuse_table, const ICplxTrans &tr) const;
|
||||||
void build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const Net *net, const char *net_cell_name_prefix, db::properties_id_type netname_propid, BuildNetHierarchyMode hier_mode, const char *cell_name_prefix, const char *device_cell_name_prefix, std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> &cmap, const ICplxTrans &tr) const;
|
void build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const Net *net, const char *net_cell_name_prefix, db::properties_id_type netname_propid, BuildNetHierarchyMode hier_mode, const char *cell_name_prefix, const char *device_cell_name_prefix, cell_reuse_table_type &reuse_table, const ICplxTrans &tr) const;
|
||||||
db::DeepLayer deep_layer_of (const db::Region ®ion) const;
|
db::DeepLayer deep_layer_of (const db::Region ®ion) const;
|
||||||
void ensure_layout () const;
|
void ensure_layout () const;
|
||||||
std::string make_new_name (const std::string &stem = std::string ());
|
std::string make_new_name (const std::string &stem = std::string ());
|
||||||
|
|
|
||||||
|
|
@ -488,6 +488,33 @@ TEST(1_BasicExtraction)
|
||||||
db::compare_layouts (_this, ly2, au);
|
db::compare_layouts (_this, ly2, au);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
db::Layout ly2;
|
||||||
|
ly2.dbu (ly.dbu ());
|
||||||
|
db::Cell &top2 = ly2.cell (ly2.add_cell ("TOP"));
|
||||||
|
|
||||||
|
db::CellMapping cm = l2n.cell_mapping_into (ly2, top2, true /*with device cells*/);
|
||||||
|
|
||||||
|
std::map<unsigned int, const db::Region *> lmap;
|
||||||
|
lmap [ly2.insert_layer (db::LayerProperties (10, 0))] = &rpsd;
|
||||||
|
lmap [ly2.insert_layer (db::LayerProperties (11, 0))] = &rnsd;
|
||||||
|
lmap [ly2.insert_layer (db::LayerProperties (3, 0)) ] = rpoly.get ();
|
||||||
|
lmap [ly2.insert_layer (db::LayerProperties (4, 0)) ] = rdiff_cont.get ();
|
||||||
|
lmap [ly2.insert_layer (db::LayerProperties (5, 0)) ] = rpoly_cont.get ();
|
||||||
|
lmap [ly2.insert_layer (db::LayerProperties (6, 0)) ] = rmetal1.get ();
|
||||||
|
lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = rvia1.get ();
|
||||||
|
lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = rmetal2.get ();
|
||||||
|
|
||||||
|
l2n.build_all_nets (cm, ly2, lmap, 0, tl::Variant (42), db::LayoutToNetlist::BNH_SubcircuitCells, "CIRCUIT_", 0);
|
||||||
|
|
||||||
|
std::string au = tl::testsrc ();
|
||||||
|
au = tl::combine_path (au, "testdata");
|
||||||
|
au = tl::combine_path (au, "algo");
|
||||||
|
au = tl::combine_path (au, "device_extract_au1_rebuild_pr.gds");
|
||||||
|
|
||||||
|
db::compare_layouts (_this, ly2, au);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
db::Layout ly2;
|
db::Layout ly2;
|
||||||
ly2.dbu (ly.dbu ());
|
ly2.dbu (ly.dbu ());
|
||||||
|
|
|
||||||
|
|
@ -194,7 +194,7 @@ NetlistBrowserDialog::probe_net (const db::DPoint &p, bool trace_path)
|
||||||
|
|
||||||
db::DBox start_search_box = db::DBox (p, p).enlarged (db::DVector (l, l));
|
db::DBox start_search_box = db::DBox (p, p).enlarged (db::DVector (l, l));
|
||||||
|
|
||||||
// @@@ not used yet ..
|
// TODO: not used yet ..
|
||||||
db::DBox stop_search_box;
|
db::DBox stop_search_box;
|
||||||
if (trace_path) {
|
if (trace_path) {
|
||||||
stop_search_box = db::DBox (m_mouse_first_point, m_mouse_first_point).enlarged (db::DVector (l, l));
|
stop_search_box = db::DBox (m_mouse_first_point, m_mouse_first_point).enlarged (db::DVector (l, l));
|
||||||
|
|
|
||||||
Binary file not shown.
Loading…
Reference in New Issue