From 548f16f1dfec09c4ecfef737f31d31365bd5bc3a Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 4 May 2019 00:37:38 +0200 Subject: [PATCH] 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) --- src/db/db/dbLayoutToNetlist.cc | 30 ++++++++-------- src/db/db/dbLayoutToNetlist.h | 33 ++++++++++++++++-- src/db/unit_tests/dbLayoutToNetlistTests.cc | 27 ++++++++++++++ .../laybasic/layNetlistBrowserDialog.cc | 2 +- .../algo/device_extract_au1_rebuild_pr.gds | Bin 0 -> 29092 bytes 5 files changed, 75 insertions(+), 17 deletions(-) create mode 100644 testdata/algo/device_extract_au1_rebuild_pr.gds diff --git a/src/db/db/dbLayoutToNetlist.cc b/src/db/db/dbLayoutToNetlist.cc index 26ab0ebca..682eb4293 100644 --- a/src/db/db/dbLayoutToNetlist.cc +++ b/src/db/db/dbLayoutToNetlist.cc @@ -608,16 +608,16 @@ db::Region *LayoutToNetlist::shapes_of_net (const db::Net &net, const db::Region } void -LayoutToNetlist::build_net_rec (const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map &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, 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 &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 (); 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 -LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &target, db::Cell &tc, const std::map &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, 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 &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; @@ -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 (); size_t subcid = c->id (); - std::map, db::cell_index_type>::const_iterator cm = cmap.find (std::make_pair (subci, subcid)); - if (cm == cmap.end ()) { + CellReuseTableKey cmap_key (subci, netname_propid, subcid); + + cell_reuse_table_type::const_iterator cm = reuse_table.find (cmap_key); + if (cm == reuse_table.end ()) { const char *name_prefix = 0; 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); 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 { - cm = cmap.insert (std::make_pair (std::make_pair (subci, subcid), std::numeric_limits::max ())).first; + cm = reuse_table.insert (std::make_pair (cmap_key, std::numeric_limits::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"))); } - std::map, db::cell_index_type> cell_map; + cell_reuse_table_type cell_reuse_table; double mag = internal_layout ()->dbu () / target.dbu (); 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 @@ -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"))); } - std::map, db::cell_index_type> cell_map; + cell_reuse_table_type cell_reuse_table; double mag = internal_layout ()->dbu () / target.dbu (); 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); - 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) { 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 { - 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); } } diff --git a/src/db/db/dbLayoutToNetlist.h b/src/db/db/dbLayoutToNetlist.h index fc5cabc77..fd86500ca 100644 --- a/src/db/db/dbLayoutToNetlist.h +++ b/src/db/db/dbLayoutToNetlist.h @@ -675,10 +675,39 @@ private: bool m_is_flat; 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 cell_reuse_table_type; + void init (); size_t search_net (const db::ICplxTrans &trans, const db::Cell *cell, const db::local_cluster &test_cluster, std::vector &rev_inst_path); - void build_net_rec (const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map &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, 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 &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, 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 &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 &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; void ensure_layout () const; std::string make_new_name (const std::string &stem = std::string ()); diff --git a/src/db/unit_tests/dbLayoutToNetlistTests.cc b/src/db/unit_tests/dbLayoutToNetlistTests.cc index 9d4a39438..1c9bdc953 100644 --- a/src/db/unit_tests/dbLayoutToNetlistTests.cc +++ b/src/db/unit_tests/dbLayoutToNetlistTests.cc @@ -488,6 +488,33 @@ TEST(1_BasicExtraction) 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 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; ly2.dbu (ly.dbu ()); diff --git a/src/laybasic/laybasic/layNetlistBrowserDialog.cc b/src/laybasic/laybasic/layNetlistBrowserDialog.cc index 8a72b5280..fb7e32bc6 100644 --- a/src/laybasic/laybasic/layNetlistBrowserDialog.cc +++ b/src/laybasic/laybasic/layNetlistBrowserDialog.cc @@ -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)); - // @@@ not used yet .. + // TODO: not used yet .. db::DBox stop_search_box; if (trace_path) { stop_search_box = db::DBox (m_mouse_first_point, m_mouse_first_point).enlarged (db::DVector (l, l)); diff --git a/testdata/algo/device_extract_au1_rebuild_pr.gds b/testdata/algo/device_extract_au1_rebuild_pr.gds new file mode 100644 index 0000000000000000000000000000000000000000..36c92dfb00cd11e92c1e59c0e74c7692c32c3574 GIT binary patch literal 29092 zcmcg#&x<8j6~6ttyIyxsN5;0@#2`Uh(AdU#@AY)g5Db${D``e&hUv}_!$9%}Cx$qBd4 z`|8yB&bf8Z{ZXSTH5xsq9$6ZV|E*Tlic)G#ea8NOwKl50arCrO+sms@KJ|-(Yk&Xa zy~~Ghe&z0OpFdHLtakryyQ;1p-Maeh(a8%Zx1PFwyt6k|D{D$s4~^8asy;EId+nZI zp3mn$o6rCE0ZXNpAEnlxK%$+cs=hQ*kEylYYUgO8)XFF6?^p>fm^2owv=%6}^tt)` z^dDNzUnhA=))*?_}~b9mvn@a$|w#Q7J#LpbS4AS|&e0lkzjW)OaV8pV?4;4jKzG`GEyx z`0>y(`2m`kpZ&%=nf&Yx<>z8!K_)-2pbS4AS|&e06Z5mzcqfyei$nRDH5O#@0}IOV z_m z_K4|%{J3bj{1`N`cc@n?^!^!YLAmh(^#uj_anW-5F=$eLF1PhUZvQsW0_Dr2O!#OriW4XaUdLmEh<0AuS;m<0nAN;-^KE^24*vp?9bn7Ow5K7R1qH zYr6rO2WV@K|t04>WqEt=Fjlc;xunN{spUw^t# zpB!RYo)Ko1g_ZEjmbcrd^~&(k%;I<7tg6GE>)*U_yhEehgrytMO={MtHwCDyn?$Ai z*ZZN!LkUZ*9aKlxZ%=nSdzE0+ImSdi;CMzM)UY+!yt+xB22<7*L z_L`RCAI#?ueoAOYqP==8h9>p)g)T2nRQ2%EOG=T?so(mQQt)Ne=YcjDGQQeqpN@8S zJ*3q7r?uRChYWa_Zet|cNk(>i8MJdQ8hQKk8g1!4jix2qYuSy4p5qQb>GGpw`L>q4 z6K(lV^z=p&e`@q?=2^@2@6+{v(z6&jep{*4ZRTA|;E;^mUC0zI3wOl(1?EUc9K0Uo z$kGFsu}GHZ1@?Ny(BygHp=IU;(4^kxIx*%&+Px>pi%=U3mB|Y{U75V_(9Sq7aCa$F zT(d@*y0lnc&`MpCKV|a*d+f^Og@=}z7eJGGo9pwaw+}>l5onjq3p`z!yztP@I4^K_ zDN{UG5M^q=jdyrGrB^mD_Qcxwqya=?xP?`4yo~}$@cxY#w z7r48WDbA-TQ+o^Mg{4KRZqj~(fqOW%H{?3P?yOI4=pn)QdqS4PP#%4Tj3( z1)i=ZalFcsB~)aofc;2Ey0k-~ib-~aH+ zm6n_D=(R&gw7V-;I0q6k&nUbyrO}q&(`Z_v-Cw!#(5w|mTBZ6_y{an3ibw z*E9Rj_)84Slw2%Ven)7$oythGleE^gJT$96(EA>if28HgZIbl02uQS(>_$V3@A66) zeJ6u#(-Jm8qP^EP7j2ike236>c_oin_zfi5S;lOWWTWlBI-eYky`Zk`jsHL!@fyWmunL}7dcZ3b|L*C{-1v9Va{K=tv;pz&qUFZF zi0pjd+b=PZq3zZ9U)>ihuX?ac=y(Xu0v< zgEk=kU9{ZzchPd=zYk3w{{~GM|MaU^jM8edApS#b#A^(jR`Qw^>Ats$tp~h9@$a7Q z&W(Q;EjRvq&<4c6iPQ8?Q^T zV_VveOXhQyI)EncERyP~|(09c2Xi3fE z58B4#PTz3)A#q15gv=kGX=DDhL_16Cshac8asEjAE%rG5{R?}%m1sYGYjHF}xTg7A z`WmB=ZAPM9UF$*f_#@k%)ch^|Rr9AM+F8cXg#1y}9^-}9<~&~d-V~v>$D*}rtXE=j zt`X-PA<=GUVS7$Hj0r{~PYBLC259I-&*Z#gdv_sEG`mPVZF#4F<5||D1s07bt#>7_ zw^Q^kdIH!wryau*?Vky;toNkw^sj}L@bLNe^g7SPcKEkD3qmh@y2yc8e$mQb(?5cf zlpgSmzpb3odnT~s0y{7u(ca{g<)bj8gsadYmK9UnLvu{&o;tY;BY`CveT7(7Op!hG zT@LKDz|IRuv^P62LM-$dyW;&9DJ;pj%fd>;`dU>rF}|^dZxJ*Rh{&P{j9j(iv%T6K z>zz6-&f!k|<%Grt>+0qfec8c$gMqFSTkd&#x`Y1mLz_d^6V$&p--T#?jq7PYo!q!d zn{mh!Yg^i9H3t2j|KKYN&b1BtLD#kIyWQ75d$0T27q4_*n~^u@Pt=yLe$ajGnG4<5 zZoSlf?asT-we#&esE(=HKc0@&H`c3M6K1ML;s3yLU#p&PR4Rcr(^#I@eJrD8?%8!m zqvf&Gf#vblq2)2xq2+Pdq2;mJq2=+~q2)2$p_TA`y&^)L#Le2TU0yX>3Evy7gzt@3 z!uLii;d`T%@V(JW_}*wGd~dW8zBgJ4-(S>mpTMfuc9lxlb)c~l&sgu1P%7cC%Non` zz4g5s-2+hPQ}+QLlYyQd8PP{a?m96R=uyp4<9V?d=;=z-#A4g`1bS47#`>s0PtQyQ zIS}aW8$6G%K#%6`>ic@^2YPxoE?_p$qq*=JFLB=~`0!%D$D_@d8qbTUKo5L)(Guu^ zkJNp^MEMy=rD7da;!H76kz5)^hv` z{j&&PW-Kkyz9`lU-_uwu8RNz8w34yR^=2P+TYa0Sbmm;{KSO9&=qX8#-zAG^&I}Um l)s@btw6N&TUtlaP8RNw_H5N;>H(2!V8@86w2z6ye{U27%2g?8e literal 0 HcmV?d00001