From 66a683259416f54e2245e8089f890c1b10057c0a Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 15 Feb 2023 22:11:12 +0100 Subject: [PATCH] Some enhancements to DEF reader based on the 'complete' example. VIAs in FILL und PIN, a variety of syntax fixes. --- .../lefdef/db_plugin/dbDEFImporter.cc | 82 +++++++++++++++--- .../lefdef/unit_tests/dbLEFDEFImportTests.cc | 2 +- testdata/lefdef/specialnets_geo/au.oas.gz | Bin 682 -> 478 bytes .../lefdef/specialnets_geo/au_no_spnet.oas.gz | Bin 529 -> 350 bytes .../specialnets_geo/au_spnet_mapped.oas.gz | Bin 765 -> 510 bytes testdata/lefdef/viasize/au.oas.gz | Bin 863 -> 519 bytes testdata/lefdef/viasize2/au.oas.gz | Bin 424 -> 542 bytes 7 files changed, 69 insertions(+), 15 deletions(-) diff --git a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc index 117d88b20..989081b88 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc @@ -1127,9 +1127,9 @@ DEFImporter::read_vias (db::Layout &layout, db::Cell & /*design*/, double scale) if (vd.m1.empty () && vd.m2.empty ()) { // analyze the layers to find the metals - if (routing_layers.size () == 2) { - vd.m1 = routing_layers[0]; - vd.m2 = routing_layers[1]; + if (routing_layers.size () == 2 || routing_layers.size () == 1) { + vd.m1 = routing_layers.front (); + vd.m2 = routing_layers.back (); } else { warn (tl::to_string (tr ("Cannot determine routing layers for via: ")) + n); } @@ -1244,18 +1244,36 @@ DEFImporter::read_pins (db::Layout &layout, db::Cell &design, double scale) } else if (test ("VIA")) { - // TODO: implement - warn (tl::to_string (tr ("VIA not supported on pins currently"))); + // TODO: clarify - VIA on pins is regarded VIA purpose, not PIN and gives a separate cell - get (); + std::string vn = get (); + unsigned int mask = 0; if (test ("MASK")) { - get_mask (get_long ()); + mask = get_mask (get_long ()); } - test ("("); - db::Vector d = get_vector (scale); - test (")"); + while (test ("(")) { + + db::Vector pt = get_vector (scale); + test (")"); + + unsigned int mask_top = (mask / 100) % 10; + unsigned int mask_cut = (mask / 10) % 10; + unsigned int mask_bottom = mask % 10; + + std::map::const_iterator vd = m_via_desc.find (vn); + if (vd != m_via_desc.end ()) { + std::string nondefaultrule; + db::Cell *cell = reader_state ()->via_cell (vn, nondefaultrule, layout, mask_bottom, mask_cut, mask_top, &m_lef_importer); + if (cell) { + design.insert (db::CellInstArray (db::CellInst (cell->cell_index ()), db::Trans (pt))); + } + } else { + warn (tl::to_string (tr ("Invalid via name: ")) + vn); + } + + } } else { while (! peek ("+") && ! peek ("-") && ! peek (";")) { @@ -1408,13 +1426,49 @@ DEFImporter::read_fills (db::Layout &layout, db::Cell &design, double scale) } else if (test ("VIA")) { - // TODO: implement - warn (tl::to_string (tr ("VIA not supported on fills currently"))); + // TODO: clarify - VIA on fill is regarded VIA purpose, not PIN and gives a separate cell - while (! at_end () && ! test (";")) { - take (); + std::string vn = get (); + + unsigned int mask = 0; + while (test ("+")) { + if (test ("MASK")) { + mask = get_mask (get_long ()); + } else if (test ("OPC")) { + // ignore + } else { + error (tl::to_string (tr ("Expected 'MASK' or 'OPC' inside fill/VIA definition"))); + } } + if (peek ("+") && test ("MASK")) { + mask = get_mask (get_long ()); + } + + unsigned int mask_top = (mask / 100) % 10; + unsigned int mask_cut = (mask / 10) % 10; + unsigned int mask_bottom = mask % 10; + + while (test ("(")) { + + db::Vector pt = get_vector (scale); + test (")"); + + std::map::const_iterator vd = m_via_desc.find (vn); + if (vd != m_via_desc.end ()) { + std::string nondefaultrule; + db::Cell *cell = reader_state ()->via_cell (vn, nondefaultrule, layout, mask_bottom, mask_cut, mask_top, &m_lef_importer); + if (cell) { + design.insert (db::CellInstArray (db::CellInst (cell->cell_index ()), db::Trans (pt))); + } + } else { + warn (tl::to_string (tr ("Invalid via name: ")) + vn); + } + + } + + test (";"); + } else { error (tl::to_string (tr ("'LAYER' or 'VIA' keyword expected"))); } diff --git a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc index c97677899..328feedcc 100644 --- a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc +++ b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc @@ -420,7 +420,7 @@ TEST(def16) { db::LEFDEFReaderOptions opt = default_options (); opt.set_macro_resolution_mode (1); - run_test (_this, "def16", "lef:a.lef+def:a.def", "au.oas.gz", opt); + run_test (_this, "def16", "lef:a.lef+lef:tech.lef+def:a.def", "au.oas.gz", opt); } TEST(100) diff --git a/testdata/lefdef/specialnets_geo/au.oas.gz b/testdata/lefdef/specialnets_geo/au.oas.gz index dced1c01d169597f188d940a11aa1f5310af4dcf..72437372a7be92691aa6a0fe39523b295dcde6f4 100644 GIT binary patch literal 478 zcmV<40U`b$iwFovN$q0*19WY0UomB7Wid86VJ>fBa{yBfcJ=kt^>+;R4CduxWH!_@ zV0gjKC?n3q!6L)YEF;ds&!EJR>XUoMnybM;fb~F;;|1o9>4KX(8~>b$4qRRSKbqrK z6n{_8gJqfS+Zf>O#gP;E6wD0`9A3uI6PEAWpd*Jx2!1$+>p)oV-LX!#kC(dv@ zYtGD@X5jDcoTj#bV-70=FO#S>GXo=2N{X?us3jvKlTCo8yr?A;Ba?=Ps3*|KU|3+hgyTe4ZpxDshMVfzs}68%`NwiWgE?h!3ZoK(lTq?Bk8>w45e=gz4L7gzV3QChL+W7|izk8BD%-}W#tG5%&^WMEWgEM{zB UWMpU+;R4CduxWH!_@V0gjKfDB|rrGn#q9V6m{J>C6WUE)3cLR{TlgW|(I zT|zuKSY&u*Akv|J*c8Z!as|hS_y@#0yZZR>a3p7B7Q~n27qIgM$Gf`(#|H%Y2e<}> zL~^pGl;-AEGQ$-x^M!dj#sjfoJXnUC-9I$M$J5W1nT45w2bsgo%m2W_A%qpgNG01q=HrrbA38m>T%cF&$$%!?cC*3KLwogZ}^%NVtbzvf7c3 diff --git a/testdata/lefdef/specialnets_geo/au_no_spnet.oas.gz b/testdata/lefdef/specialnets_geo/au_no_spnet.oas.gz index 021f51106a270a0e6eaf02b9087957147f539168..dfb6a9b0b28952912fd91ea8f4295eb9d3b36701 100644 GIT binary patch literal 350 zcmV-k0ipgMiwFovN$q0*19WY0Uo+;R4CduxWH!_@ zV0gjKC?n3q!6L)YEF;ds&!EJR>XUoMnybM;fb~F;;|1o9>4KX(8~>b$4qRRSKbqrK z6n{_8gJqfq3(W`A5$1JZsL(n`Yqe z?wqE!fMX6T122=PH6sHflTCo8yr?BJBU4I>v9YKn6C;y`hNvhnBVJhs!Ea0xm?tm` zeqcPo$RKiu_{16UXD=oAkF+;R4CduxWH!_@V0gjKfDB|rrGn#q9V6m{J>C6WUE)3cLR{TlgW|(I zT|zuKSY&u*Akv|J*c8Z!as|hS_y@#0yZZR>a3p7B7Q~n27ce7Od|{rB@jz@CpHiBe zTglDt9~$E0>F3JK!py*f%;9G8HDqQ43PNch--wwR%m>rlEFe>unSdg27B8cyH6sHf zlTCo8yr?BJBU4I>v9YKn6C;y`hNvhngWxyD3Ct6i1q)6vGKd^zVOYb&)G(3(0|NjH CakUo! diff --git a/testdata/lefdef/specialnets_geo/au_spnet_mapped.oas.gz b/testdata/lefdef/specialnets_geo/au_spnet_mapped.oas.gz index 70d7ce49400a914d3c7979334c442de450e5c290..244696cf00d99bf7087d90cd8a466f89c2eab4b9 100644 GIT binary patch literal 510 zcmVQlGcIpoa{yBfcJ=kt^>+;R4CduxWH!_@ zV0gjKC?n3q!6L)YEF;ds&!EJR>XUoMnybM;fb~F;;|1o9>4KX(8~>b$4qRRSKbqrK z6n{_8gJqfS+Zf>O#!#qZx$7$dBc|U&qQk_h_wXpS zM@n2X=&Vh9_9$IEk)>-+!j!=DCkao|MYbj++8-_HSlRra;j-njWFOlA&5pi}fXl_+4ly|The2$;_^ zW|Q1I^l6{wxfBa{yBfcJ=kt^>+;R4CduxWH!_@ zV0gjKC?n3q!6L)YEF;ds&!EJR>XUoMnybM;fb~F;;|1o9>4KX(8~>b$4qRRSKbqrK z6n{_8gJqfS+Zf>O#!zads$7$dBc|U&qQkyyS;6NYQm=mQY0D literal 863 zcmY!lcJ=kt^>+;R4CduxWH!_@V0gjKfDB|rrGn#q9V6m{J>C6WUE)3cLR{TlgW|(I zT|zuKSY&u*Akv|J*c8Z!as|hS_y@#0yZZR>a3p7B7Q~n27qIgM$Gf`(#|H%Y2e<}> zL~^pGl;-AEGQ$-x^M!dj#sjfod~t4KP7V@3C$T6!m7Co^G{nc#&y|^xnSlqH!_DJs zsORSzq8}UpB$?TP(ikE@HAYBkIKgVrM7TLXw(9{2W)7e{3XfY1CTA7w8RcrAXJ8Zo zB7iCxdGN?_OJL|T0c$h?>SW@e|ASubqh%Cs+$fThm zD$2_s_>E}-^8{wW4~!=m8AJ{gk$e}L&6(=nzVe$gJVD3XpfOmJlT#&%FZxt XVY~toW@G{x^M#o~mZ@PR0|o{F;1vXa diff --git a/testdata/lefdef/viasize2/au.oas.gz b/testdata/lefdef/viasize2/au.oas.gz index 5da4dd619c09b1b68a4422c59bb31f10d52a30e7..c1ab0c221a0f64ddf30e46b875986f89f7a0c222 100644 GIT binary patch literal 542 zcmV+(0^$81iwFoYN9|((19WY0UomB7Wid86VJ>fBa{yBfcJ=kt^>+;R4CduxWH!_@ zV0gjKC?n3q!6L)YEF;ds&!EJR>XUoMnybM;fb~F;;|1o9>4KX(8~>b$4qRRSKbqrK z6n{_8gJqfS+Zf>O#!y2ZH$7$dBc|U&qQkyyS;6NYQm=mQY*47|*u)*Q@?Oa=y$lDtenHX|dGhK8spFC&o6 z1Y{dXit+;e+{aih{O6brBL}O!!Q6xtfj!488Y7<=C?A$m3v?}WTgG`tT_W|0q@~19 zNmt&82(gX23DF13dY-d&uesswS63$Jc1+koLp$r>p}MY@0>SM68J89N9G_A3!?pUr zA`h!;1_!6kO~`t{u4#REOY282j~Np=Q_hH|u|)#y4s%L==5g+XPKW+U{Rx8U4`!S? zaz^;sO9}oXZ67^5T@^O^sioQNh$zfU^5gUPqOZJ}BgRC1qlT^NJ%f7+_ZU>ZPZVTe gVw}v($iS$~Sj^bM$jHzzvH$}E02kfczu5u+07+I9IRF3v literal 424 zcmV;Z0ayMXiwFoh6Jufk17US8Z((x)<&C>a13?sqXU?qIjl1g-aH5e-VIkTWH^D-* z3TB84$tGmhYcs?PDkLag3cHjR7I_4*vas|4L_vaxm57gEsUX(QDu(q!Ucfob;r##i z&zvF7itcDB%Uy1EW0Foe=t)K4W77dHirEFh-Mq(g!u5QXXB9E;=KL8=u}%9E&w76a zY}(C*Un+}fRwx+S%Esol*xTAxd$`EwxF}ajWmfSQqg|`}_4)y62Z%A}W`(?Iv0U9D zJ#DpHuhwcIU90Y_ujy)O)-SjoBbXo~EOeuoPI=59<7L^2D)BEzW-=is`jPqJ=vuHX zB^%Ks|EBc#mzw165_3{cW+7;jVWR`n`~GI*5`xhQ>ixgqc$*TVBQ*(~lFPwy5(yLJ zj4_OiP-