From 41a5c9db37724f5f15d40bc84cd845ed6bca1169 Mon Sep 17 00:00:00 2001 From: Ayan Biswas Date: Sun, 19 Feb 2023 22:32:57 -0800 Subject: [PATCH 1/8] add drv_shunt_peak layout, schematic, measurements, design script --- OA/bag3_analog/drv_shunt_peak/data.dm | Bin 0 -> 4164 bytes .../drv_shunt_peak/schematic/data.dm | Bin 0 -> 3412 bytes .../drv_shunt_peak/schematic/master.tag | 2 + .../drv_shunt_peak/schematic/sch.oa | Bin 0 -> 33892 bytes .../schematic/thumbnail_128x128.png | Bin 0 -> 1000 bytes .../drv_shunt_peak/symbol/master.tag | 2 + .../drv_shunt_peak/symbol/symbol.oa | Bin 0 -> 24588 bytes .../symbol/thumbnail_128x128.png | Bin 0 -> 575 bytes OA/bag3_analog/gm_stage/data.dm | Bin 0 -> 4100 bytes OA/bag3_analog/gm_stage/schematic/data.dm | Bin 0 -> 3332 bytes OA/bag3_analog/gm_stage/schematic/master.tag | 2 + OA/bag3_analog/gm_stage/schematic/sch.oa | Bin 0 -> 33508 bytes .../gm_stage/schematic/thumbnail_128x128.png | Bin 0 -> 805 bytes OA/bag3_analog/gm_stage/symbol/master.tag | 2 + OA/bag3_analog/gm_stage/symbol/symbol.oa | Bin 0 -> 25340 bytes .../gm_stage/symbol/thumbnail_128x128.png | Bin 0 -> 785 bytes OA/bag3_analog/res_diff/data.dm | Bin 0 -> 4012 bytes OA/bag3_analog/res_diff/schematic/data.dm | Bin 0 -> 3332 bytes OA/bag3_analog/res_diff/schematic/master.tag | 2 + OA/bag3_analog/res_diff/schematic/sch.oa | Bin 0 -> 31804 bytes .../res_diff/schematic/thumbnail_128x128.png | Bin 0 -> 772 bytes OA/bag3_analog/res_diff/symbol/master.tag | 2 + OA/bag3_analog/res_diff/symbol/symbol.oa | Bin 0 -> 24492 bytes .../res_diff/symbol/thumbnail_128x128.png | Bin 0 -> 797 bytes src/bag3_analog/design/drv_shunt_peak.py | 134 +++ src/bag3_analog/layout/drv_shunt_peak.py | 126 ++ src/bag3_analog/layout/gm_stage.py | 319 +++++ src/bag3_analog/layout/res_diff.py | 102 ++ src/bag3_analog/measurement/drv_shunt_peak.py | 283 +++++ src/bag3_analog/schematic/drv_shunt_peak.py | 135 +++ src/bag3_analog/schematic/gm_stage.py | 109 ++ .../netlist_info/drv_shunt_peak.symbol.yaml | 503 ++++++++ .../netlist_info/drv_shunt_peak.yaml | 1029 +++++++++++++++++ .../netlist_info/gm_stage.symbol.yaml | 433 +++++++ .../schematic/netlist_info/gm_stage.yaml | 736 ++++++++++++ .../netlist_info/res_diff.symbol.yaml | 358 ++++++ .../schematic/netlist_info/res_diff.yaml | 565 +++++++++ src/bag3_analog/schematic/res_diff.py | 106 ++ 38 files changed, 4950 insertions(+) create mode 100644 OA/bag3_analog/drv_shunt_peak/data.dm create mode 100644 OA/bag3_analog/drv_shunt_peak/schematic/data.dm create mode 100644 OA/bag3_analog/drv_shunt_peak/schematic/master.tag create mode 100644 OA/bag3_analog/drv_shunt_peak/schematic/sch.oa create mode 100644 OA/bag3_analog/drv_shunt_peak/schematic/thumbnail_128x128.png create mode 100644 OA/bag3_analog/drv_shunt_peak/symbol/master.tag create mode 100644 OA/bag3_analog/drv_shunt_peak/symbol/symbol.oa create mode 100644 OA/bag3_analog/drv_shunt_peak/symbol/thumbnail_128x128.png create mode 100644 OA/bag3_analog/gm_stage/data.dm create mode 100644 OA/bag3_analog/gm_stage/schematic/data.dm create mode 100644 OA/bag3_analog/gm_stage/schematic/master.tag create mode 100644 OA/bag3_analog/gm_stage/schematic/sch.oa create mode 100644 OA/bag3_analog/gm_stage/schematic/thumbnail_128x128.png create mode 100644 OA/bag3_analog/gm_stage/symbol/master.tag create mode 100644 OA/bag3_analog/gm_stage/symbol/symbol.oa create mode 100644 OA/bag3_analog/gm_stage/symbol/thumbnail_128x128.png create mode 100644 OA/bag3_analog/res_diff/data.dm create mode 100644 OA/bag3_analog/res_diff/schematic/data.dm create mode 100644 OA/bag3_analog/res_diff/schematic/master.tag create mode 100644 OA/bag3_analog/res_diff/schematic/sch.oa create mode 100644 OA/bag3_analog/res_diff/schematic/thumbnail_128x128.png create mode 100644 OA/bag3_analog/res_diff/symbol/master.tag create mode 100644 OA/bag3_analog/res_diff/symbol/symbol.oa create mode 100644 OA/bag3_analog/res_diff/symbol/thumbnail_128x128.png create mode 100644 src/bag3_analog/design/drv_shunt_peak.py create mode 100644 src/bag3_analog/layout/drv_shunt_peak.py create mode 100644 src/bag3_analog/layout/gm_stage.py create mode 100644 src/bag3_analog/layout/res_diff.py create mode 100644 src/bag3_analog/measurement/drv_shunt_peak.py create mode 100644 src/bag3_analog/schematic/drv_shunt_peak.py create mode 100644 src/bag3_analog/schematic/gm_stage.py create mode 100644 src/bag3_analog/schematic/netlist_info/drv_shunt_peak.symbol.yaml create mode 100644 src/bag3_analog/schematic/netlist_info/drv_shunt_peak.yaml create mode 100644 src/bag3_analog/schematic/netlist_info/gm_stage.symbol.yaml create mode 100644 src/bag3_analog/schematic/netlist_info/gm_stage.yaml create mode 100644 src/bag3_analog/schematic/netlist_info/res_diff.symbol.yaml create mode 100644 src/bag3_analog/schematic/netlist_info/res_diff.yaml create mode 100644 src/bag3_analog/schematic/res_diff.py diff --git a/OA/bag3_analog/drv_shunt_peak/data.dm b/OA/bag3_analog/drv_shunt_peak/data.dm new file mode 100644 index 0000000000000000000000000000000000000000..e22fd18a650828bb53e681a64583208b34b7d165 GIT binary patch literal 4164 zcmeI0J8u&~5XUcX9^n-N3NNub0&);oCV*)p#h^qA5GfKMD6I3{+Fo(KJI-q>MM^#Z zAAypR8c|SCq)0(Qk%A9ELq`uYcmJ^?OF_^;gtC(Jo7vgfogMGaT4~(9G&JUnIMVKr zaFjkn=(q}=2QPr5;23xY90xCh6W~Sg5I6}Iz=})+UFKKNn_vhg;0E{u?Im<)I2W1- z;1#%VJnx@{UDlEPEx}*~;KQfpf(9;iuzI_91?pQ}*Ss@tip4SfO?$ha+Pb zNSE&bCdUuz70-Ik^2&;7+q_rai!DsZ?=8U0LZ88H@C*1A{0_>&oWwlS;0$;Tfxa1d7klv|DWc1H*^TlJ%lK*RX9FG5k7@Vu zk21ht3%(k;E1Ns|ekmj5O(q{Bu3hZQM^5S!iCJS?_S+JR4S~a;ocA&42OV3<+>_PR$~*{on4vp&W^UBrRuRNaIjuyrQ6QM zh}Kw5b=|Bh_lc`$xz@up(5Wi8rW$u_%T>9MkkGAK&x9mAs#N&z+8SG2%~ zUJSy$A2S8HM%#LB7rii?Q|(0imUfe+eeWcf4#AviwiDy)${x=thf0mEVL%_gmks*= F!B4G7fP(-4 literal 0 HcmV?d00001 diff --git a/OA/bag3_analog/drv_shunt_peak/schematic/data.dm b/OA/bag3_analog/drv_shunt_peak/schematic/data.dm new file mode 100644 index 0000000000000000000000000000000000000000..53786e6c5acca7ddc861786dbd5efee5f056d301 GIT binary patch literal 3412 zcmeH~J#W)M7{{IFrM#545>QJ)SZP5ig2<#0)(#+n)Pb4Ba%|VJ46l^ zN-m({7I+oB2A04wxC~an8{j;69XtgtfOYU82ZGJyJ5b%idC^<(VJ$o(Q+EjeQLy{oy6(R3wO{7la}MQ?%9#=yRF7XgZ?@oWXoE4 z_SILLR9RDvrA|TSGA&oXbNVCcyn%HATm&zIRqzsc8C(LdfC`m9osZrgs&guNs{bmr zs*@)rtKOfM%y~&MPt?r3;x89;kMyqN-SMZ?Y3JvnhNPPY7N4;x_6q8VAnb=}5T^c~ z<#*yF7=)?yWNRxPj?8|l-w_7ZdsoNez0BwF=H@+9q5~QV;2c}Xi2mgH`B=bnEq9)=Ky5A8FlviuXaGs zi6NrznV5&!5t(z!$^~=CraV@Upg+{P>lmtG+N|Z}O)8ZblC&-R#x(t{0yqaU-pjBn z;5^9qoqTVopQ;y{sIQDm)i_Q3zGYmR+Mn@^uxIse6R%O;kJDzHze9^^uxc^ex%cc( z|H<{T|9gz{0n9dE%15w|L5?$x+@II*p9bA8&UHLKaJnWY;Ik_{kh~*#Jk{&9wij)< zT`x+*QS1+Eb}dc=H;A{l-RA?ZFZOV++wLW`bsN53>LtBM8V2DobNrQ0)OCj=FAB$e P)@1^LWX?U3|5HBzwV1co literal 0 HcmV?d00001 diff --git a/OA/bag3_analog/drv_shunt_peak/schematic/master.tag b/OA/bag3_analog/drv_shunt_peak/schematic/master.tag new file mode 100644 index 0000000..26be1be --- /dev/null +++ b/OA/bag3_analog/drv_shunt_peak/schematic/master.tag @@ -0,0 +1,2 @@ +-- Master.tag File, Rev:1.0 +sch.oa diff --git a/OA/bag3_analog/drv_shunt_peak/schematic/sch.oa b/OA/bag3_analog/drv_shunt_peak/schematic/sch.oa new file mode 100644 index 0000000000000000000000000000000000000000..ca2a5adccf3ea9919bba889fae71642f5923bc97 GIT binary patch literal 33892 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 literal 0 HcmV?d00001 diff --git a/OA/bag3_analog/drv_shunt_peak/schematic/thumbnail_128x128.png b/OA/bag3_analog/drv_shunt_peak/schematic/thumbnail_128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..861c6797ce284561ed1ee54d6f6d2b7a9195b037 GIT binary patch literal 1000 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 C=|~#@ literal 0 HcmV?d00001 diff --git a/OA/bag3_analog/drv_shunt_peak/symbol/thumbnail_128x128.png b/OA/bag3_analog/drv_shunt_peak/symbol/thumbnail_128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..d61facbed81ffb30ae09e05338c9719222a3413d GIT binary patch literal 575 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSoCO|{#S9F5M?jcysy3fA0|Vnn zPZ!6KiaBrZI{F<75OKH||9Dc2aCedK8&38Y3_%8}yt;RaCmox(Wa0H`?>Co9CC_1t zl#hPTa9hY>4#OiB0rdt8#v_~xehh_79l|i79p~4UC+M$pUvycm`eV&Gu-t+5nLUQG z{Lj}%zds|4t^r}j>|?Xc+vWII?-lv~<5%3%)NB8%8>W`^Scm;_EapVmfY1Q8R4hH%~d9t^EA6B@$_it2H&O4r$e)YFsW=VT*f1LR9`;B>@?Cx7_6HjMY{^xt?>l?oW zB*0FOWOIvP+b4bcz=t%+6G77&&tUggy@cS$8zvL}MrBHAG=y)xozAk+dl^)54O_{n^fBe~<9^;5Gua0-YJ5A@?8aHc=-Lm_*>eia@zoz8#fHt0Ihr z(+UT2xVkxO&T>q?DVK|tQn6H~97`qBlTrx=Uj_ZGX55v2rPQq46&=@YR*H9urL1}S zdld5f!MjZo-@JU-BAzf0PUTbv3+c}~1AP%Z3oe1@!1LfTco8H}>Z3GD zw+H1pO5v3MDb-T?BVQ@sA2$#CWyE3OTsbuSWr1Qu@u92ZPu9WxD5lhx+@}6iE@iN8 zfZXoqe`n%5ZsyNV$Y^7xkqr$N9;KX`#CG+Y*!Iz$uXT`z-W1a319S zJAQ8X%yJ&3vq**aCFM3M{9ViYGP7oRk>s(@Tdw|X;usCvv)jDSKcI$kFXdpaA3L6D zo=%%$KwdBR|Cm-<)+aCxzL9sK?}0q;LFD*sjysP24DyqGMJ`SE1n#*V@}KI7Wg5#& zxH>jwK8nL$q@OEKcSWFl(N@y;)}`un^++F8xB6O#!DDJPGPc9Gw-G2^k3%=@alFAEn&Z~g_*ARH1=dH^0sP*eciJ~CPYRUG_|9ABRs2C>9^5HjVhp4gQf~b zjhY?1AY2n8v!p;jF|!Ce>9<@JyM3i?5lHQu)zE6C*N>%eg2XtrW_r|P)hieu*F68< z^U*lfFw1zQ*Bsw3h$ND(Hr}UUJ-pzVms$|rBvP)d{$nvC*Gw_T$TJU}tB(2q{}W(6 BYcBu* literal 0 HcmV?d00001 diff --git a/OA/bag3_analog/gm_stage/schematic/data.dm b/OA/bag3_analog/gm_stage/schematic/data.dm new file mode 100644 index 0000000000000000000000000000000000000000..8cc33e9f92f15281a276aa646c4f615c540fb364 GIT binary patch literal 3332 zcmeH~yKWOf6o$vwa0$0yP{Kv5oPcZu*0MyVH4zAqQqmwH8QZ(EEv?s<9U>y7q(^i- z0FOaIL6IT_1w{%TfCr$5`91${EK4rZfP{Rc^*6UOduI0RKkN46^;FJejO>9eoV8bq z4Y$c_@89$KL$A^7 z??#i=ZaFjwd&Q%{faaNK9aF_ zyB}Yn{{F>Q6NIcmW2IA+xv`d`{~Ug-op&%7$QAM;Ss*Wwm&sM~3JE~^Afq@vpmUHs z=s#kFPM)+E^!~KH6qhYdOqw}q_{#!zeM&wzs>Z9k-ttcgTrx?qV*T%etRVZk;n(4PZx#Op_Toa9oC5 zVSAR;eZTTX-^e5KJNbkBN$OK#ne!CLRq_r4eK~VJPU6R+t*NfOnMa++8eiagd{XUh z*2V9?+5x18QiSi!!T1rm=QJ*-+(UNdsdgs)0b+-?K*P|D`POPuDqFFJzVSDv^EW9n zO)B4WtmnxkQu#ak-bg>87cjhwFy$pQ4yNy0<)v%=lg~_hH6NRNjV68yTY3J8J=iB` zvHG?5^4Iv;^~(P<=lMd8H{X^ISwA8*&pc{>o^$*>AWp?PogaLvp(8sBw=G1+J@0yui1}_<#K49bg#Dk|MMHFPi0B~ literal 0 HcmV?d00001 diff --git a/OA/bag3_analog/gm_stage/schematic/master.tag b/OA/bag3_analog/gm_stage/schematic/master.tag new file mode 100644 index 0000000..26be1be --- /dev/null +++ b/OA/bag3_analog/gm_stage/schematic/master.tag @@ -0,0 +1,2 @@ +-- Master.tag File, Rev:1.0 +sch.oa diff --git a/OA/bag3_analog/gm_stage/schematic/sch.oa b/OA/bag3_analog/gm_stage/schematic/sch.oa new file mode 100644 index 0000000000000000000000000000000000000000..4151c2d876026bca92ec2da8af1d0b09e13078ad GIT binary patch literal 33508 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 literal 0 HcmV?d00001 diff --git a/OA/bag3_analog/gm_stage/schematic/thumbnail_128x128.png b/OA/bag3_analog/gm_stage/schematic/thumbnail_128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..f49d4298713d508bc8963d742bdb3a46b59faf0e GIT binary patch literal 805 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSoCO|{#S9F5M?jcysy3fA0|V1_ zPZ!6KiaBp@`}WOt5Mg+zHcL6x_})(=yDKrrtkWM`Pdu8y`|-TQvA@4eSN>9&;<}_^ z!KD&rIWNs*!E5W^FbC){HyATmP)1Z|?>+qSpnqWd!ncJlf*5U;nc5ny?)#c+<{f!SuB5G=n{R4 zFaOJ4Ap364lfqpBYt>S>_Psn`cav8|wPBvz$9q0I^wevtPTuulNXxJsAs(Mm8Zkm T!ZsV2?ioB?{an^LB{Ts5ve-R1 literal 0 HcmV?d00001 diff --git a/OA/bag3_analog/gm_stage/symbol/master.tag b/OA/bag3_analog/gm_stage/symbol/master.tag new file mode 100644 index 0000000..e1024da --- /dev/null +++ b/OA/bag3_analog/gm_stage/symbol/master.tag @@ -0,0 +1,2 @@ +-- Master.tag File, Rev:1.0 +symbol.oa diff --git a/OA/bag3_analog/gm_stage/symbol/symbol.oa b/OA/bag3_analog/gm_stage/symbol/symbol.oa new file mode 100644 index 0000000000000000000000000000000000000000..3a65adf5aabb63ba19eb18c9ed5a3758f6297065 GIT binary patch literal 25340 zcmeHQe{7Z4dH%lZYhV8aV+?T!NzIS6P9Ve~l+u*8225f$LtNveq;zvGz8Cv$# zOFEX`GA2E+VccK1=)}>uVui zQiF`EU(JjU5C@4P#KXi-7>+XDM1>qBwzI=6OFYBCLmrPcc^qjbuJ#yEuubcIyy+`U z|C+~h-|%>Oo5#0y6Zd#*+w1ZA?|S@rpT`c$q5f$+JA8IDp30Y6Sd3gjaDoid$GMcx zQn@z9ms8(YWdLM2Ugr5Xao{gA{R-315u2&Me^}`GZ<6mc>;GHwRWh9r$vOWpuYq|D z%xhp?1M?b~*TB36<~8vDRRinSt$%8ywe^|i;nC*ozTxqFq=<^3BFNf)a{c;s8(Y`4 zuGd!E$H!V*nJ`!wI(VpebRa*tv9)*OhUWghzTS=No?X|fnr!pAhx^^XU)GRC@{w1z z?gQ>HLW1_w@pBEgw?RFaEiCd7G!PdP8;Lwd1WOs`F(T0UC`CDRPD(RgPOKnih?T@D zVl}abINdp`o_soQH88%I*hpMLTuOY1*hGAoxQzG+QRj$98GnrU1!6OC1#u-2r&@&7 z#K(zWBz}q5LVSYwBykOKE%7PhI^xsBR^l_n_<3^!)4xpINc;+M6Y;CW=ZIe;ZYF-6 zh(6&F#~>VmaPGlT3FmGcwQydmGQ#l+XKL6TY!2sW*c$8%HU|5GZNaW!Q?Mr-O<_+s z%P%u}#0cj^ocSL!!Wq8VXob;Aqg6($jUG3`x%x{+Ek;im;oe}4(ORRYjMf=FZG<`V zj1i8v&l+to`m)hRBTTnVMqf30&Im`|%|>50!m;<8Mr}r0jJ6tWGio>5ZuGp-3r0H6 z+T*MP`t(@__>A8&`fa05qn$>(j9xVAGQyR^Y{wsEtqNx+K#Vg2#v0+9FfI#iMBSHQ zY!S9FeJgP~Sz(_Dt0Axj*qOWQVcZ$BrLj6^*WlyvKDw8XUrVtZY|29E_k6+9I8p8R z?8$G*q5BN^WBFbASNT)eF#_xn0poz6dS;4hCyu_>`EQIj$JE(3G$I?|7~hu8F~2Px zrXYJlJ+%3fJ(eu}9P(gBuh@g)7|%yvD~saF*L=aiKPj6vUWEPwy<^2}e?I8T4-URu z$bYXrw<8zy=Jt(m8}H1H6?+N?^1F-K10&lH6`33*1-X6g`LRO((9V1@yJKko@Xp~} zVgGB}h7S%EZ_Ar3Wm(@YjOMrJ3dP~kEh8ht*`Dl3estRl!FXY`cyM@ZxIMo=dvLJm zl7sQyVzw~Y+aHV+hE@eb`JxpuhM>21Tl>~6yRMSaGz_SIpaFE_TUvupc!cCaUJ8ra)5k{vDjtdZf-;)|oX{AjSFv$HT(43rg&=ZA8`qu>g* zweRlTzpt-v%xc=#ogXiZ6^4hPNGNxAc08YR>at2khjTkEEk8Pj$1Q`V*8};Xq7~%G zbQbox!RgO;jSd&{=-2aw{)5)b7e|h&lj0o7_vI|XZ!MK zaoa$4sNeJvAGv6BTnnb@UHM{A@EUS(z-&eS;-a%0?|-pg!xj-_TC#cZiy^+hQ#~K} z;=v{2W#Sd$4Wjm8sy7McpPE@te2m@(;CKGqkaJ}soDATfK;Kfq^WpjMQg}7|&oG^8 zNG(e}m+qKSxgOuABCzK`-P7qu`&&7SkP1u@%cM|Nq}C~G_#&o;s#@53+24|j$>sIMxc@l$`Lf7zSLpJP4m5hsZ6 z6SWSio+MO%Mp*7{aHp|>+|TeZJhAE zd$&t03>_d&GWGVad?LtMh3d~KR{nXlhdb%4#Je!$sUJ7I4&D6&)+$CLTZ-GobnCp< z>v9!jh4OD&?=#G=Bvuh6&&MoxGbT`)23t$iIde1PJ;XucQQ|Qo=EmKE^pb?~Bk=bK z)1m4qsvo}CXZ8)B27(`;N;HMtJo?951LSn+m0_wPD6dN|TD;_;haYiopSX0Zt1O)k zGMTFCn%X+I3iG|M<8}<4AQ7(frf83qLX!LG2{frF_}tVJ4t|@X5-jZQLgBbn`#1KUJvt zul7o8=qT|R@eSe$;xCEs5w8&&DWK+k8{_I%5^DaoP(ksy(uJx=`|>2c&NLnOxFFaQ z+n8V-ZvODu0eBkBLoYRNv&?RSQO?3G{HcZMu%fK8raGvtTD+t_)AGcVYt}xs?&;QN z)<3%e7rUItkK8p(^4az{Rc14_yu6|!lc}t%s;aK8sj024t6Q*Op&1MA?K_Me!x5ji zK{SJdQXOu=Ee=c~*DAj-uRo9bZSd_K$XE@u7`;!>jeGu^rU3Oo2QQSCOep5?^V#1`UOqR#al zjCT=xh29ch9w&rStEavu4VA1(s>2XY|Px}b*$NA#vP1I8p z`*AYKuqgMZ4VcF^^PRa+#S@gl?+@(gTwal>1doNuv|uvLXHEJ!#!H4GSFWr)Q?(>m zxJbXzGT&g550P)1j@k^NGN=zK0}V%?pyZz|ahibfa_v#?ng_a6(0Z46p6B>!ft~66 z)jW;wpS7=^?S6&h5%oSMW@PvAeG9M2qTkOo5A-{Eb5!H~Jy6{d^^hy zFE>ut2aPXFCh0@tKHKrsxW&g);~e+Lbrf9ks$=Sh{Dschn2!h=7x^3X6QS9C``?lA z*upsW<_N7G-0#GA+{E~1VjHoY*g=#$pEr~qDCPqTFi(vwI)U}epfnq@y3WbI%`>`3 zjhpuE@GJLnf28xj_8Tf+;(VHJ->-I)Q1&e}vHnknyRD<>u=Jz*4!kph_e!YdY4?rO z`K$OiCiyA-&Z363{zMFZA%G7etGQqr( z;Z!=_V+~*(!jOVoduG68wiC0xSZP(T%I(RnD;SRg#?`&c$8q?y_iIV>X0G;W@qJ8u zKc>C0>{$CUy}yWe&gLR;x7e!y?gz=X*m_uO4R)BV*D&o`<6&f zsxltee1g3o$UiGC%=zqSzZdnJ=?^O4ETP{%?leC?y!zosA6<35n}BK??UM>Y?!@ip za8-3xitnRxuMw7&`Ei)IX_bQBwX!!{HU8_Y!F40G|9AHM?>@_YD<68lY;?uwn$dq) zUH@db+vs16{=f)(3)m@#UM6NKlL6!C=G+|lgZrKLlakHNlk8giblhKK&vC!=H~xE4 z(mlvRu4_7nEMi>u#}Y*IUUHu2pe3Cvbe_0QzMDk(71iI&_H-Y;iSc&gA>tY0W#U!h zHKO#Ggz^_!muHI`IP7s${c2x-S1~tM^5E2h;oy+yPGy49J0J7m)sGPM{>Crv_xxPu zjXIIvT+9zZR(}aJT^w>u#}m(=Z5b=)d|spBRG)|RsR91Zy?ZuC{w}_*&z1j+`=_aW zn9FC)C;5YwRyq0*Z(lYi{%DK;eG7fFr|*4s&p|891I z=@*HO6l{P8%t2x!HLfAh7nK{2w=q4AJ#1h6r>VGOMD4e9z7n7Q zevj48!vn4XyvhK=Jtv3W`BD7grR@RDv)bE8<>f&|g}sv$R94zGb{Leomy?183)8j- zt2Vz>Ywsc~(3#DbzfCW?LAfR44#oW%P*%RQqB5*{C|$dte&M2J4b^pFs;ntfv;2{V zgLJuVPhF@8%cg#O)f0dDKc9T^eRI%1H#}naQ^VH{|CxB+@Sw$OjE)+C|4$9U|6@b& zzi9}5Aozb|__5(zhT#9HA^3k`2>zcNf*%O}pBVnP;Tc2hmmv@45ajv5=yfBA3;b)N z?-^Y%f;`}dJm7~s;D;RG2mZte@__%(jld6izz=!A4>`aO{0pO#M&SP&qfSf5-n+-> zhEbQ%B_j6lFB!dW)N6!2e7BWZYV;kW$BbS!T1MPz_${LjqrFCXBj^M9R@4Q^gSPir z?B5Jm7@?m(G=L#RJ6O zXCl4D2zl6qVC@B+G`eJj^f!#qJ`i!pfH*LIW`X`YEj?}2V}vsh&NI&%y=sK~w+)eh z$_V*?Wwg%d9V6ry4UvD?2>GuWZ817#gu20ly1|3-0T0G!l@aPd`FD*_{*R4tj=~uX z<&h6W{&A!48~vFP@*x-UUo}GhfYA?(@WQLpGt?-!9a6Wa}rsD4E2V!c!m%FqJAgVdVRm|2XI-P@q3B7|MAlKal&&s6Yl8! z#5@D!vK^J68lpJt1L2ehXD5(Bd^~PNdvWnALFG=f{23x_1mUa)8#^D8@I3RA0D1;N zFJ{`9^HbK1KMHod_|o3&_#ZmC{j0B4VU>l4t4!0@nIBn!4kLxIp*&R{hHs|u9pbCI zz5$OH>Kt^}7<4ZQjjz0W$%W;{a$!w(y)j-`bD_>bcMXcAs*hysyU~3wwC_}P7;ddN zl1Vj&4Hh?^RP~#H?usKzk1TpK6CPQ*!oE}0smH8+6DVgSy=~>XN0AhS5UQeY^URge}%5geDKp|KPEa@i@Yd z+$~JC3yR|IseTq*4SsE_)qmMdRaICQ{@UU{3+lof_7~WXdPZkI{=Mp&bd3*aY69!= z>ttT#Zci&&G84n#T->EE$JSog5bVO@i-MH=uI#3NJE;3p9W{+KvqXaRpSn8{>9 zGby0+0uw&Vjj*QkMER}3{rdzMB2dMx!58OurJ<{YHO0?$VvY^Bl5azebB+ZT7zb=O zUS5KWf5vvJf~-jG4X`2E=?LRRqU`oK<7bKS_nO~l`X!>8OG2zK2yTrrTN?_F8{pl(WPSjaC_5FtRWarbARY z;bMj`Da6sniqL-`H|hn!tPEU0zuZu8Jnq+yP-%$2l-}X~M%uN3F9?XB_g66AakPaz z2+{||i1^cDNRUtdQWa@Gp#6dTr`j#CKH1YT#@`^GAf6$O%1-MhI>VIP$JqxOyRH}}}xL^jPU%`-7-3}si#nE>bG zMq34>KNeK7>Q#BoJN>&ROFUyq^{QQ=%4uH653AqWM`)f1Rc^MZ_U{$ZefGtz(U1#$ zM>^(%g1KnyX-iYcWl7FX>Jh#VSA2}l+W)Bn`90O&#fp1~@*m%2JVzWP%0Fs-l^>Mc zNvLrX#>Y+N>e-G{#vFX1I#o%XJKtf+aa3y)IKSgOeZ^94FctEm9@#UK-8%^wA2l*p zenYl`{S^YQcccA>yX&`f*S4Yb>gFN}FsSc}-!H2F8n4w%zA zCVST3v+6!xa>dtSy+^Qta_bz^!T26xjyOOZB#sb^#6!fx#8Y&1r-{;25^CJy{!HVlw0n_Bp&czyxCN@*f!RascW6~m%hq5_;*!gM;x#FomY}eI$`xno->pkoMMeQ7=z;NvRl!7 s^M__*q+lw4n)RF^zC%1qgs((UyGba!Wicm@WI}mMzh&I}?f<>_UknY&i2wiq literal 0 HcmV?d00001 diff --git a/OA/bag3_analog/gm_stage/symbol/thumbnail_128x128.png b/OA/bag3_analog/gm_stage/symbol/thumbnail_128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..f7257a72ddc2cf3f8c137a8b7e5d651cd6bdb3d6 GIT binary patch literal 785 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSoCO|{#S9F5M?jcysy3fA0|V1x zPZ!6KiaBrZ#saCedK8&3HZ7XvwcoZ38p%~{{I>UYu8_e+G;8JBnL zXxVVj&7Pq*m7(DMV)+BwcWxc`)vp)%{e-2#n8AV>M7S^n@0{y@|Nk{nC5E#wL6FQ2 zO}DvxcJtfryj@pYv+s}I@p(K_A6m+@FR(q-V>rj~fCrT*VkxlOxoJmGAA{1m)m?5I zBIYqD)hQXYr0rzt*x~lTBx9O>!=cOzD)|h8e$8w+P7I&F{q$*DWA8 zg)^Xd`v-2Ivb#<$6PP;+q*!blm~410*cO^`=wxbk#Ui5!pfA(3*N79?2lWrcwa~7GRON2@Ag_m@2ha<&1ApBdLY+~ zF-Z19qXi?}^_LH_U(8;5m6PE)OU1Qm-2vb0!j_A=GXvSHXEINldYAQpB_rRW>t3sc z;ojY&_CXROTlGiZfk&H;zAbuO_Wl1H|JirmKeJ!`bYIn-``YuJON$jV zI$fe`ADTAm3jG%qR6n51x&7BH#xtIKu3qPPpnpO-Ucy25=Z^hH8I%g5YtJ$?MA!C8 zGgPczZ^+z`|J5{%A@A#d1EvqX^QZnVDUker@;}pys7iI9s>yR0D<)jm2?r|Ze#&`Z zZQWEG_QribS3lu6U|zpfhB3nwoH&pP>D?kWkG`x~-tu4a)50T)+a2W(-1&SqmSGO# z0ZBOFTllwBVQaL%!B_KHIu8)3?1bP0l+XkK D)4D$j literal 0 HcmV?d00001 diff --git a/OA/bag3_analog/res_diff/data.dm b/OA/bag3_analog/res_diff/data.dm new file mode 100644 index 0000000000000000000000000000000000000000..abe90bebcc04facebd30b7b1d3054ea92a6b1768 GIT binary patch literal 4012 zcmeH~J8u&~5XaAXH~|8L5KwrDl?lj3V2lCNBE_IYvcOU#9+h>zTiYk@rMq*KA|)*n zAA`?;C@3gWq@YLu{_X7U?99&Y&7QmWFXbkUaYM>o zsvM&yhlZ=*dGG=_0ZxKvz&v;voB}U`hrt=J2-amH$TGiz+yh-O1UJARC@&xzV}nW$ z4!ie$OsFthO!%F3* z3L<5;gEc)|UEatW4&|F_wOp%|D|agB$;z(d_t#rdPrJ2Bt9Dy;Evr>4-zv*^R+D_P z{ryIp<(JRCTFj&LaE_Hc#WEMp*;r9>NO?-nNH`jay+{LTgHxcK-|TxM z@2uoeeiymOx#Zl&MZRn0Tn<`C`8xA?E8V|M9P8nDaa+#$Tl8@5#{-&l(WRiA7$ zBi(VCWa~&33yMLT(B%Z)Y9gmx z{W{xqAFb~x<5e$ezQ;5^xyOxKr|**?*Q5BUu(>xXePFweHOddZI4PxL$Bz&Lj?md<6}Px+v8Ca(@`$dFkwrvUcLk;|;l zle+IG-sm%VNPZ!|lHW-s=px4{kt^g)PV~jp`8b|G7Hv(w@@5uw9;<(e>+wm|yHV%A z|7r)29!e3uGyCZya?dF(XWT<}<%xPG{XXW7G=heq8RM-sq*T_ihPLz@)5V(%nI)C) z1^PvDfmHrZzc!h zd&R5&^m-Nlf#ZB6)6KW#1Nw)g#+gO!&vW*l1#?U r4<9@UMsaVu?3Lpv36h=WAZ*5=b(7ug*05jR+%zV%y>+jS{r~eD*{5Zj literal 0 HcmV?d00001 diff --git a/OA/bag3_analog/res_diff/schematic/master.tag b/OA/bag3_analog/res_diff/schematic/master.tag new file mode 100644 index 0000000..26be1be --- /dev/null +++ b/OA/bag3_analog/res_diff/schematic/master.tag @@ -0,0 +1,2 @@ +-- Master.tag File, Rev:1.0 +sch.oa diff --git a/OA/bag3_analog/res_diff/schematic/sch.oa b/OA/bag3_analog/res_diff/schematic/sch.oa new file mode 100644 index 0000000000000000000000000000000000000000..0f08c7e4214d21799f771530943433dee8b3f5bc GIT binary patch literal 31804 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 Z38!|WP;%?n^5-oqAIbwBw*NQ${{RhN3_Jh; literal 0 HcmV?d00001 diff --git a/OA/bag3_analog/res_diff/schematic/thumbnail_128x128.png b/OA/bag3_analog/res_diff/schematic/thumbnail_128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..473fb3f901a5af1354a256980d7df882f55a8751 GIT binary patch literal 772 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSoCO|{#S9F5M?jcysy3fA0|V1G zPZ!6KiaBrZ`1&QpMQGbIB|V{RrLD}4A1OXqz@iaR4_HZ@&50t@HqFHy3Ol< zoBor%!_2~ao25`c;g|a*_Wh#macovE-WDopyeNA8*q)2I!I;4UMC{NCXMCLf$JQ@v zSuw{;;pN6R_ps04^Lrb)bmw>LlxJK?!3^Haf!Ph$?j7fNb;Cw<&v%jcm!^L<2sr-C z`M|y4J;m>zKe+ywS+O9F?GT#hLpc-v%y=octbfzIqnct}U(zlVe@+v)vy5TdvnSbS zudd(Q|DE~Ohctnhsp?JN!_V5)^#QRaNGB^2}wK*=NOt|G=d7@5eJDvKi0!L*rGidg%5zhg-T;{*`M}Y~? zgEj`}iE?i%IP+gNY!C;|b~kd)WJ^7RW%LGa literal 0 HcmV?d00001 diff --git a/OA/bag3_analog/res_diff/symbol/master.tag b/OA/bag3_analog/res_diff/symbol/master.tag new file mode 100644 index 0000000..e1024da --- /dev/null +++ b/OA/bag3_analog/res_diff/symbol/master.tag @@ -0,0 +1,2 @@ +-- Master.tag File, Rev:1.0 +symbol.oa diff --git a/OA/bag3_analog/res_diff/symbol/symbol.oa b/OA/bag3_analog/res_diff/symbol/symbol.oa new file mode 100644 index 0000000000000000000000000000000000000000..a10a8b391cc2a0a63f3a1f4ef46c774f1e87f53a GIT binary patch literal 24492 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 literal 0 HcmV?d00001 diff --git a/src/bag3_analog/design/drv_shunt_peak.py b/src/bag3_analog/design/drv_shunt_peak.py new file mode 100644 index 0000000..cc5270a --- /dev/null +++ b/src/bag3_analog/design/drv_shunt_peak.py @@ -0,0 +1,134 @@ +from typing import Mapping, Any, Dict, Union, List, Type +import numpy as np +from copy import deepcopy + +from bag.util.immutable import Param +from bag.io.sim_data import load_sim_file, save_sim_results +from bag.concurrent.util import GatherHelper +from bag.simulation.cache import DesignInstance +from bag.simulation.measure import MeasurementManager + +from bag3_testbenches.design.optimize.base import OptDesigner, OptimizationError + +from ..measurement.drv_shunt_peak import DrvShuntPeakTranMeas + + +class DrvShuntPeakDesigner(OptDesigner): + def __init__(self, *args, **kwargs) -> None: + super().__init__(*args, **kwargs) + + @classmethod + def get_meas_var_list(cls): + return ['width', 'height', 'i_avg', 'fom'] + + async def async_design(self, **kwargs: Any) -> Mapping[str, Any]: + await self.characterize_designs() + fn_table, swp_order = self.make_models() + opt_specs = self._dsn_specs['opt_specs'] + spec_constraints = {k: tuple(v) for k, v in opt_specs['spec_constraints'].items()} + + self.log(f'Performing eye_area optimization...') + try: + opt_x, opt_y, spec_vals = self.optimize('height', fn_table, swp_order, maximize=True, reduce_fn=np.max, + spec_constraints=spec_constraints) + print('--------------------------') + print(f'opt_x = {opt_x}') + print(f'opt_y = {opt_y}') + print(f'spec_vals = {spec_vals}') + print('--------------------------') + except OptimizationError as e: + self.warn(f'Error occurred while running: {e}') + + return fn_table + + async def verify_design(self, dut: DesignInstance, dsn_params: Dict[str, Any], + sim_swp_params: Dict[str, Any]) -> Dict[str, Any]: + dsn_name = self.get_design_name(dsn_params) + + gatherer = GatherHelper() + gatherer.append(self.run_sim('tran', DrvShuntPeakTranMeas, dut, dsn_name, dsn_params, sim_swp_params)) + res_list = await gatherer.gather_err() + res = self.aggregate_results(res_list) + return res + + async def run_sim(self, meas_name: str, mm_cls: Type[MeasurementManager], dut: DesignInstance, dsn_name: str, + dsn_params: Dict[str, Any], sim_swp_params: Dict[str, Any]) -> Dict[str, Any]: + sim_dir = self.get_meas_dir(dsn_name) + out_dir = self.get_data_dir(dsn_name) + + res_fpath = out_dir / f'{meas_name}.hdf5' + run_meas = self.check_run_meas(res_fpath) + + if not run_meas: + prev_res = load_sim_file(str(res_fpath)) + self.reorder_data_swp(prev_res, self.sim_swp_order) + return prev_res + + # setup measurement specs + mm_specs = deepcopy(self._dsn_specs['meas_params']) + mm_specs['sim_envs'] = sim_swp_params['corner'] + mm_specs['v_incm_swp'] = sim_swp_params['v_incm'] + mm_specs['v_tail_g_swp'] = sim_swp_params['v_tail_g'] + mm_specs['ind_specs']['sp_file_specs']['shunt']['file_name'] = dsn_params['sp_file'] + + mm = self.make_mm(mm_cls, mm_specs) + + data = (await self._sim_db.async_simulate_mm_obj(meas_name, sim_dir / meas_name, dut, mm)).data + + res = self.postproc_tran(data, dsn_params) + res['sweep_params'] = {k: self.sim_swp_order for k in res} + res.update(sim_swp_params) + + save_sim_results(res, str(res_fpath)) + return res + + @staticmethod + def postproc_tran(data: Mapping[str, Any], dsn_params: Dict[str, Any]) -> Dict[str, Any]: + radius: int = int(dsn_params['radius']) + height: float = data['height'] + i_avg: float = data['i_avg'] + return dict( + width=data['width'], + height=height, + i_avg=i_avg, + fom=height / (np.sqrt(i_avg) * np.sqrt(radius)), + ) + + @staticmethod + def aggregate_results(res_list: List[Dict[str, Any]]) -> Dict[str, Any]: + ans = {} + for res in res_list: + for k, v in res.items(): + if k == 'sweep_params': + if k not in ans: + ans[k] = {} + ans[k].update(v) + elif k not in ans: + ans[k] = v + elif isinstance(v, np.ndarray): + assert np.all(ans[k] == v) + else: + assert ans[k] == v + return ans + + @classmethod + def get_dut_gen_specs(cls, is_lay: bool, base_gen_specs: Param, + gen_params: Mapping[str, Any]) -> Union[Param, Dict[str, Any]]: + base_gen_specs = base_gen_specs.to_yaml() + base_gen_specs['lay_mode'] = 'EXT' + base_gen_specs['gm_params']['seg_dict']['tail'] = int(gen_params['seg_tail']) + base_gen_specs['gm_params']['seg_dict']['gm'] = int(gen_params['seg_gm']) + base_gen_specs['ind_sh_params']['radius_x'] = int(gen_params['radius']) + base_gen_specs['ind_sh_params']['radius_y'] = int(gen_params['radius']) + return base_gen_specs + + @classmethod + def get_em_dut_gen_specs(cls, base_gen_specs: Param, + gen_params: Mapping[str, Any]) -> Union[Param, Dict[str, Any]]: + base_gen_specs = base_gen_specs.to_yaml() + base_gen_specs['lay_mode'] = 'EM' + base_gen_specs['gm_params']['seg_dict']['tail'] = int(gen_params['seg_tail']) + base_gen_specs['gm_params']['seg_dict']['gm'] = int(gen_params['seg_gm']) + base_gen_specs['ind_sh_params']['radius_x'] = int(gen_params['radius']) + base_gen_specs['ind_sh_params']['radius_y'] = int(gen_params['radius']) + return base_gen_specs diff --git a/src/bag3_analog/layout/drv_shunt_peak.py b/src/bag3_analog/layout/drv_shunt_peak.py new file mode 100644 index 0000000..247e9cb --- /dev/null +++ b/src/bag3_analog/layout/drv_shunt_peak.py @@ -0,0 +1,126 @@ +from typing import Mapping, Any, Optional, Type, Sequence, Tuple, List, Union + +from bag.util.immutable import Param +from bag.util.math import HalfInt +from bag.design.module import Module +from bag.layout.core import PyLayInstance +from bag.layout.template import TemplateDB, TemplateBase +from bag.layout.routing.base import TrackID, TrackManager, WDictType, SpDictType, WireArray + +from pybag.enum import PinMode, RoundMode, Direction, MinLenMode, Orientation +from pybag.core import Transform, BBox + +from xbase.layout.mos.top import GenericWrapper +from xbase.layout.array.top import ArrayBaseWrapper + +from bag3_magnetics.layout.inductor.ind_diff_wrap import IndDiffWrap + +from .gm_stage import GmStageGR +from .res_diff import ResDiff + +from ..schematic.drv_shunt_peak import bag3_analog__drv_shunt_peak, LayMode + + +class DrvShuntPeak(TemplateBase): + def __init__(self, temp_db: TemplateDB, params: Param, **kwargs: Any) -> None: + TemplateBase.__init__(self, temp_db, params, **kwargs) + tr_widths: WDictType = self.params['tr_widths'] + tr_spaces: SpDictType = self.params['tr_spaces'] + self._tr_manager = TrackManager(self.grid, tr_widths, tr_spaces) + + @classmethod + def get_schematic_class(cls) -> Optional[Type[Module]]: + return bag3_analog__drv_shunt_peak + + @classmethod + def get_params_info(cls) -> Mapping[str, str]: + return dict( + tr_widths='Track width dictionary for TrackManager', + tr_spaces='Track spaces dictionary for TrackManager', + gm_params='Parameters for gm cells', + res_params='Parameters for differential resistors', + ind_sh_params='Parameters for shunt differential inductor', + lay_mode='Layout mode, TOP by default.', + ) + + @classmethod + def get_default_param_values(cls) -> Mapping[str, Any]: + return dict(lay_mode=LayMode.TOP) + + def draw_layout(self) -> None: + # make masters + gm_params: Mapping[str, Any] = self.params['gm_params'] + gm_master = self.new_template(GenericWrapper, params=dict(cls_name=GmStageGR.get_qualified_name(), + params=gm_params, export_hidden=True)) + gm_bbox = gm_master.bound_box + + res_params: Mapping[str, Any] = self.params['res_params'] + res_master = self.new_template(ArrayBaseWrapper, params=dict(cls_name=ResDiff.get_qualified_name(), + params=res_params, export_hidden=True)) + res_bbox = res_master.bound_box + + ind_sh_params: Mapping[str, Any] = self.params['ind_sh_params'] + ind_sh_master: IndDiffWrap = self.new_template(IndDiffWrap, params=ind_sh_params) + ind_sh_bbox = ind_sh_master.actual_bbox + ind_layer: int = ind_sh_params['lay_id'] + + lay_mode: Union[str, LayMode] = self.params['lay_mode'] + if isinstance(lay_mode, str): + lay_mode = LayMode[lay_mode] + gen_gm = gen_res = lay_mode is LayMode.TOP or lay_mode is LayMode.EXT + gen_ind = lay_mode is LayMode.TOP or lay_mode is LayMode.EM + + # --- Placement --- # + w_tot = max(gm_bbox.w, res_bbox.w, ind_sh_bbox.w) + + x_gm = (w_tot - gm_bbox.w) // 2 + y_gm = gm_bbox.h + gm = self.add_instance(gm_master, xform=Transform(dx=x_gm, dy=y_gm, mode=Orientation.MX), commit=gen_gm) + + x_res = (w_tot + res_bbox.w) // 2 + y_res = y_gm + res = self.add_instance(res_master, xform=Transform(dx=x_res, dy=y_res, mode=Orientation.MY), commit=gen_res) + + x_ind = (w_tot - ind_sh_bbox.w) // 2 + y_ind = y_res + res_bbox.h + ind = self.add_instance(ind_sh_master, xform=Transform(dx=x_ind, dy=y_ind), commit=gen_ind) + + h_tot = ind.bound_box.yh + self.set_size_from_bound_box(ind_layer, BBox(0, 0, w_tot, h_tot), round_up=True) + + # --- Routing --- # + # gm cell + if gen_gm: + for pin in ('v_inp', 'v_inm', 'v_tail_g', 'v_tail'): + self.reexport(gm.get_port(pin)) + + for pin in ('i_outp', 'i_outm', 'VSS', 'VDD'): + # TODO: routing + self.reexport(gm.get_port(pin), connect=True) + + # res_diff + if gen_res: + for term, net in [('p_in', 'i_outp'), ('m_in', 'i_outm'), ('p_out', 'ind_p'), ('m_out', 'ind_m')]: + # TODO: routing + self.reexport(res.get_port(term), net_name=net, connect=True) + self.reexport(res.get_port('VDD'), connect=True) + + # ind + if gen_ind: + if lay_mode is LayMode.TOP: + for pin in ('P13_R', 'P2_R', 'P2'): + # TODO: routing + self.reexport(ind.get_port(pin), net_name='VDD', connect=True) + self.reexport(ind.get_port('P1'), net_name='ind_p', connect=True) + self.reexport(ind.get_port('P3'), net_name='ind_m', connect=True) + else: + for pin in ('P13_R', 'P2_R', 'P2', 'P1', 'P3'): + self.reexport(ind.get_port(pin)) + + # get schematic parameters + self.sch_params = dict( + gm=gm_master.sch_params, + res=res_master.sch_params, + ind=ind_sh_master.sch_params, + lay_mode=lay_mode, + ) diff --git a/src/bag3_analog/layout/gm_stage.py b/src/bag3_analog/layout/gm_stage.py new file mode 100644 index 0000000..d11cd31 --- /dev/null +++ b/src/bag3_analog/layout/gm_stage.py @@ -0,0 +1,319 @@ +"""This module contains layout generator for gm_stage.""" + +from typing import Any, Mapping, Type, Optional, Sequence + +from pybag.enum import MinLenMode, RoundMode + +from bag.util.immutable import Param +from bag.layout.template import TemplateDB +from bag.design.module import Module + +from xbase.layout.enum import MOSWireType, MOSPortType, SubPortMode +from xbase.layout.mos.base import MOSBasePlaceInfo, MOSBase +from xbase.layout.mos.guardring import GuardRing + +from ..schematic.gm_stage import bag3_analog__gm_stage + + +class GmStage(MOSBase): + def __init__(self, temp_db: TemplateDB, params: Param, **kwargs: Any) -> None: + MOSBase.__init__(self, temp_db, params, **kwargs) + + @classmethod + def get_schematic_class(cls) -> Optional[Type[Module]]: + return bag3_analog__gm_stage + + @classmethod + def get_params_info(cls) -> Mapping[str, str]: + return dict( + pinfo='The MOSBasePlaceInfo object.', + seg_dict='Dictionary of transistor segments', + w='transistor width.', + ridx_tail='index for mos row with tail transistor', + ridx_gm='index for mos row with gm transistors', + export_tail='True to export tail node; False by default', + is_dum='True if the gm stage is used as dummy load; False by default', + ) + + @classmethod + def get_default_param_values(cls) -> Mapping[str, Any]: + return dict(export_tail=False, w=0, ridx_tail=0, ridx_gm=1, is_dum=False) + + def draw_layout(self) -> None: + pinfo = MOSBasePlaceInfo.make_place_info(self.grid, self.params['pinfo']) + self.draw_base(pinfo) + + tile_tap = 0 + tile_logic = 1 + _pinfo = self.get_tile_pinfo(tile_idx=tile_logic) + + seg_dict: Mapping[str, int] = self.params['seg_dict'] + w: int = self.params['w'] + ridx_tail: int = self.params['ridx_tail'] + ridx_gm: int = self.params['ridx_gm'] + export_tail: bool = self.params['export_tail'] + is_dum: bool = self.params['is_dum'] + + # set number of columns + seg_gm = seg_dict['gm'] + seg_tail = seg_dict['tail'] + if seg_tail % 2: + raise ValueError(f'This generator requires seg_tail={seg_tail} to be even.') + seg_tot = max(seg_tail, 2 * seg_gm) + seg_tot2 = seg_tot // 2 + seg_tail2 = seg_tail // 2 + + # --- Placement --- # + if seg_tail2 % 2 == 1: + sup_term, share_term = MOSPortType.S, MOSPortType.D + g_on_s = False + else: + sup_term, share_term = MOSPortType.D, MOSPortType.S + g_on_s = True + + # tail + tail_inst = self.add_mos(ridx_tail, seg_tot2 - seg_tail2, seg_tail, tile_idx=tile_logic, w=w, g_on_s=g_on_s) + _row_info = _pinfo.get_row_place_info(ridx_tail).row_info + w_tail, th_tail = _row_info.width, _row_info.threshold + + # gm cells + gm_left_inst = self.add_mos(ridx_gm, seg_tot2, seg_gm, tile_idx=tile_logic, w=w, flip_lr=True) + gm_right_inst = self.add_mos(ridx_gm, seg_tot2, seg_gm, tile_idx=tile_logic, w=w) + _row_info = _pinfo.get_row_place_info(ridx_gm).row_info + w_gm, th_gm = _row_info.width, _row_info.threshold + + # tap cells + tap_conn = self.add_substrate_contact(0, 0, tile_idx=tile_tap, seg=seg_tot, port_mode=SubPortMode.ODD) + + self.set_mos_size() + + # --- Routing --- # + tr_manager = self.tr_manager + hm_layer = self.conn_layer + 1 + vm_layer = hm_layer + 1 + xm_layer = vm_layer + 1 + ym_layer = xm_layer + 1 + xxm_layer = ym_layer + 1 + + # 1. source terminals of tail transistor go to supplies + tap_tid = self.get_track_id(0, MOSWireType.DS, 'sup', tile_idx=tile_tap) + tap_hm = self.connect_to_tracks([tail_inst[sup_term], tap_conn], tap_tid) + tap_xxm = self.connect_via_stack(tr_manager, tap_hm, xxm_layer, 'sup', alternate_o=True) + self.add_pin('VSS', tap_xxm) + + # 2. source terminals of gm transistors connect to drain terminals of tail: connect on 2 hm_layer wires to + # improve connection + tail_tid0 = self.get_track_id(ridx_tail, MOSWireType.DS, 'sig_hs', tile_idx=tile_logic) + tail_tid1 = self.get_track_id(ridx_gm, MOSWireType.DS, 'sig_hs', wire_idx=-1, tile_idx=tile_logic) + tail0 = self.connect_to_tracks([gm_left_inst.s, gm_right_inst.s, tail_inst[share_term]], tail_tid0, + wire_lower=tail_inst[share_term].lower) + tail1 = self.connect_to_tracks([gm_left_inst.s, gm_right_inst.s, tail_inst[share_term]], tail_tid1) + self.add_pin('v_tail', [tail0, tail1], hide=is_dum or not export_tail) + + # 3. gate terminals of tail transistor + tail_g_tid = self.get_track_id(ridx_tail, MOSWireType.G, 'sig_hs', tile_idx=tile_logic) + tail_g = self.connect_to_tracks(tail_inst.g, tail_g_tid) + tail_g_xxm = self.connect_via_stack(tr_manager, tail_g, xxm_layer, 'sig_hs', + mlm_dict={vm_layer: MinLenMode.LOWER, ym_layer: MinLenMode.LOWER}) + if is_dum: + self.connect_wires([tail_inst.g, tail_inst[sup_term]]) + else: + self.add_pin('v_tail_g', tail_g_xxm) + + # 4. get gate connections of gm transistors + gate_tid = self.get_track_id(ridx_gm, MOSWireType.G, 'sig_hs', tile_idx=tile_logic) + gate_left = self.connect_to_tracks(gm_left_inst.g, gate_tid) + gate_right = self.connect_to_tracks(gm_right_inst.g, gate_tid) + mlm_gate = {vm_layer: MinLenMode.UPPER, ym_layer: MinLenMode.UPPER} + _, ym_locs_sig = tr_manager.place_wires(ym_layer, ['sig', 'sig', 'sig'], center_coord=seg_tot2 * self.sd_pitch) + l_coord = self.grid.track_to_coord(ym_layer, ym_locs_sig[0]) + r_coord = self.grid.track_to_coord(ym_layer, ym_locs_sig[-1]) + gate_left_hm = self.add_wires(hm_layer, gate_tid.base_index, gate_left.lower, + min(l_coord, gate_left.upper), width=gate_tid.width) + gate_right_hm = self.add_wires(hm_layer, gate_tid.base_index, max(r_coord, gate_right.lower), gate_right.upper, + width=gate_tid.width) + gate_left_xxm = self.connect_via_stack(tr_manager, gate_left_hm, xxm_layer, 'sig', 0, -1, mlm_gate) + gate_right_xxm = self.connect_via_stack(tr_manager, gate_right_hm, xxm_layer, 'sig', 0, 1, mlm_gate) + self.add_pin('v_inp', gate_left_xxm) + self.add_pin('v_inm', gate_right_xxm) + + # 5. get drain connections of gm transistors + drain_tid = self.get_track_id(ridx_gm, MOSWireType.DS, 'sig_hs', wire_idx=0, tile_idx=tile_logic) + drain_left = self.connect_to_tracks(gm_left_inst.d, drain_tid) + drain_right = self.connect_to_tracks(gm_right_inst.d, drain_tid) + mlm_drain = {vm_layer: MinLenMode.LOWER, ym_layer: MinLenMode.LOWER} + _, ym_locs_sig_hs = self.tr_manager.place_wires(ym_layer, ['sig_hs', 'sig_hs', 'sig_hs'], + center_coord=seg_tot2 * self.sd_pitch) + l_coord = self.grid.track_to_coord(ym_layer, ym_locs_sig_hs[0]) + r_coord = self.grid.track_to_coord(ym_layer, ym_locs_sig_hs[-1]) + drain_left_hm = self.add_wires(hm_layer, drain_tid.base_index, drain_left.lower, + min(l_coord, drain_left.upper), width=drain_tid.width) + drain_right_hm = self.add_wires(hm_layer, drain_tid.base_index, max(r_coord, drain_right.lower), + drain_right.upper, width=drain_tid.width) + drain_left_xxm = self.connect_via_stack(tr_manager, drain_left_hm, xxm_layer, 'sig_hs', 0, -1, mlm_drain) + drain_right_xxm = self.connect_via_stack(tr_manager, drain_right_hm, xxm_layer, 'sig_hs', 0, 1, mlm_drain) + self.add_pin('i_outm', drain_left_xxm, hide=is_dum) + self.add_pin('i_outp', drain_right_xxm, hide=is_dum) + + # get schematic parameters + self.sch_params = dict( + lch=_pinfo.lch, + w_dict=dict(tail=w_tail, gm=w_gm), + th_dict=dict(tail=th_tail, gm=th_gm), + seg_dict=seg_dict, + export_tail=export_tail, + is_dum=is_dum, + ) + + +class GmStageGR(GuardRing): + def __init__(self, temp_db: TemplateDB, params: Param, **kwargs: Any) -> None: + GuardRing.__init__(self, temp_db, params, **kwargs) + + @classmethod + def get_params_info(cls) -> Mapping[str, str]: + ans = dict(**GmStage.get_params_info()) + ans.update( + pmos_gr='pmos guard ring tile name.', + nmos_gr='nmos guard ring tile name.', + edge_ncol='Number of columns on guard ring edge. Use 0 for default.', + ) + return ans + + @classmethod + def get_default_param_values(cls) -> Mapping[str, Any]: + ans = dict(**GmStage.get_default_param_values()) + ans.update( + pmos_gr='pgr', + nmos_gr='ngr', + edge_ncol=0, + ) + return ans + + def get_layout_basename(self) -> str: + return self.__class__.__name__ + + def draw_layout(self) -> None: + params = self.params + pmos_gr: str = params['pmos_gr'] + nmos_gr: str = params['nmos_gr'] + edge_ncol: int = params['edge_ncol'] + + core_params = params.copy(remove=['pmos_gr', 'nmos_gr', 'edge_ncol']) + master = self.new_template(GmStage, params=core_params) + + sep_ncol_left = sep_ncol_right = master.gr_sub_sep_col + sep_ncol = (sep_ncol_left, sep_ncol_right) + + inst, sup_list = self.draw_guard_ring(master, pmos_gr, nmos_gr, sep_ncol, edge_ncol, export_pins=False) + + # --- Routing --- # + hm_layer = self.conn_layer + 1 + vm_layer = hm_layer + 1 + xm_layer = vm_layer + 1 + ym_layer = xm_layer + 1 + xxm_layer = ym_layer + 1 + yym_layer = xxm_layer + 1 + x3m_layer = yym_layer + 1 + + # guard ring supply connections + vdd_hm_list = [] + for (_, vdd_list) in sup_list: + if vdd_list: + vdd_hm_list.extend(vdd_list) + vdd_dict0, vdd_dict1 = {}, {} + mlm_dict0 = {vm_layer: MinLenMode.LOWER, ym_layer: MinLenMode.LOWER} + mlm_dict1 = {vm_layer: MinLenMode.UPPER, ym_layer: MinLenMode.UPPER} + vdd_xxm0 = self.connect_via_stack(self.tr_manager, vdd_hm_list[0], xxm_layer, 'guard', mlm_dict=mlm_dict0, + ret_warr_dict=vdd_dict0) + vdd_xxm1 = self.connect_via_stack(self.tr_manager, vdd_hm_list[-1], xxm_layer, 'guard', mlm_dict=mlm_dict1, + ret_warr_dict=vdd_dict1) + + for _layer in (vm_layer, ym_layer): + self.connect_wires([vdd_dict0[_layer][0], vdd_dict0[_layer][-1], + vdd_dict1[_layer][0], vdd_dict1[_layer][-1]]) + + # --- bring all signals to x3m_layer without colliding on yym_layer --- # + # get all yym_layer tracks so that alternate tracks can be used to go from xxm_layer to x3m_layer + tidx_l = self.grid.coord_to_track(yym_layer, vdd_xxm0.lower, RoundMode.GREATER_EQ) + tidx_r = self.grid.coord_to_track(yym_layer, vdd_xxm0.upper, RoundMode.LESS_EQ) + num_yym = self.tr_manager.get_num_wires_between(yym_layer, 'sig_hs', tidx_l, 'sig_hs', tidx_r, 'sig_hs') + 2 + if num_yym & 1 == 0: + num_yym -= 1 + yym_tidx_list = self.tr_manager.spread_wires(yym_layer, ['sig_hs'] * num_yym, tidx_l, tidx_r, + ('sig_hs', 'sig_hs')) + yym_coords = [self.grid.track_to_coord(yym_layer, _tidx) for _tidx in yym_tidx_list] + + # VDD on x3m_layer + vdd_x3m0 = self.connect_via_stack(self.tr_manager, vdd_xxm0, x3m_layer, 'guard', + mlm_dict={yym_layer: MinLenMode.LOWER}, coord_list_o_override=yym_coords[::2]) + vdd_x3m1 = self.connect_via_stack(self.tr_manager, vdd_xxm1, x3m_layer, 'guard', + mlm_dict={yym_layer: MinLenMode.UPPER}, coord_list_o_override=yym_coords[::2]) + self.add_pin('VDD', self.connect_wires([vdd_x3m0, vdd_x3m1])[0]) + + # x3m_layers between two VDD tracks + x3m_tidx_list = self.tr_manager.spread_wires(x3m_layer, ['sig_hs', 'sig_hs', 'sig_hs', 'sig_hs', 'sig_hs'], + vdd_x3m0.track_id.base_index, vdd_x3m1.track_id.base_index, + ('sig_hs', 'sig_hs')) + x3m_coords = [self.grid.track_to_coord(x3m_layer, _tidx) for _tidx in x3m_tidx_list] + + # VSS on x3m_layer + vss_x3m = self.connect_via_stack(self.tr_manager, inst.get_pin('VSS'), x3m_layer, 'sup', + coord_list_o_override=yym_coords[1::2], coord_list_p_override=[x3m_coords[1]]) + self.add_pin('VSS', vss_x3m) + + # left input and output on x3m_layer + v_inp = inst.get_pin('v_inp') + i_outm = inst.get_pin('i_outm') + _l0 = max(v_inp.lower, i_outm.lower) + _r0 = min(v_inp.upper, i_outm.upper) + _coords0 = get_sub_list(yym_coords, _l0, _r0) + + v_inp = self.connect_via_stack(self.tr_manager, v_inp, x3m_layer, 'sig_hs', + mlm_dict={yym_layer: MinLenMode.UPPER}, + coord_list_o_override=_coords0[1::2], coord_list_p_override=[x3m_coords[-2]]) + self.add_pin('v_inp', v_inp) + i_outm = self.connect_via_stack(self.tr_manager, i_outm, x3m_layer, 'sig_hs', + mlm_dict={yym_layer: MinLenMode.LOWER}, + coord_list_o_override=_coords0[::2], coord_list_p_override=[x3m_coords[-3]]) + self.add_pin('i_outm', i_outm) + + # right input and output on x3m_layer + v_inm = inst.get_pin('v_inm') + i_outp = inst.get_pin('i_outp') + _l1 = max(v_inm.lower, i_outp.lower) + _r1 = min(v_inm.upper, i_outp.upper) + _coords1 = get_sub_list(yym_coords, _l1, _r1) + + v_inm = self.connect_via_stack(self.tr_manager, v_inm, x3m_layer, 'sig_hs', + mlm_dict={yym_layer: MinLenMode.UPPER}, + coord_list_o_override=_coords1[-2::-2][::-1], + coord_list_p_override=[x3m_coords[-2]]) + self.add_pin('v_inm', v_inm) + i_outp = self.connect_via_stack(self.tr_manager, i_outp, x3m_layer, 'sig_hs', + mlm_dict={yym_layer: MinLenMode.LOWER}, + coord_list_o_override=_coords1[::-2][::-1], + coord_list_p_override=[x3m_coords[-3]]) + self.add_pin('i_outp', i_outp) + + # v_tail_g is DC and exported on xxm_layer + self.reexport(inst.get_port('v_tail_g')) + + # v_tail is exported for debugging + self.reexport(inst.get_port('v_tail')) + + # update schematic parameters + self.sch_params = dict( + **self.sch_params, + guard_ring=True, + ) + + +def get_sub_list(orig_list: Sequence[int], low: int, high: int) -> Sequence[int]: + new_list = [] + for ele in orig_list: + if ele >= low: + if ele > high: + break + new_list.append(ele) + return new_list diff --git a/src/bag3_analog/layout/res_diff.py b/src/bag3_analog/layout/res_diff.py new file mode 100644 index 0000000..5c4fa34 --- /dev/null +++ b/src/bag3_analog/layout/res_diff.py @@ -0,0 +1,102 @@ +"""This module defines differential resistors.""" + +from typing import Mapping, Any, Optional, Type, cast + +from bag.util.immutable import Param +from bag.design.module import Module +from bag.layout.template import TemplateDB +from bag.layout.routing.base import TrackManager, WireArray + +from xbase.layout.res.base import ResBasePlaceInfo, ResArrayBase + +from ..schematic.res_diff import bag3_analog__res_diff + + +class ResDiff(ResArrayBase): + def __init__(self, temp_db: TemplateDB, params: Param, **kwargs: Any) -> None: + ResArrayBase.__init__(self, temp_db, params, **kwargs) + + @classmethod + def get_schematic_class(cls) -> Optional[Type[Module]]: + return bag3_analog__res_diff + + @classmethod + def get_params_info(cls) -> Mapping[str, str]: + return dict( + pinfo='The ResBasePlaceInfo object.', + nx_dum='Number of dummies on each side, X direction', + ny_dum='Number of dummies on each side, Y direction', + ) + + @classmethod + def get_default_param_values(cls) -> Mapping[str, Any]: + return dict(nx_dum=0, ny_dum=0) + + def draw_layout(self) -> None: + pinfo = cast(ResBasePlaceInfo, ResBasePlaceInfo.make_place_info(self.grid, self.params['pinfo'])) + self.draw_base(pinfo) + + # Get hm_layer and vm_layer WireArrays + warrs, bulk_warrs = self.connect_hm_vm() + + # Connect all dummies + self.connect_dummies(warrs, bulk_warrs) + + unit_params = dict( + w=pinfo.w_res, + l=pinfo.l_res, + intent=pinfo.res_type, + ) + nx, ny = pinfo.nx, pinfo.ny + nx_dum: int = self.params['nx_dum'] + ny_dum: int = self.params['ny_dum'] + npar_tot = nx - 2 * nx_dum + nser = ny - 2 * ny_dum + assert npar_tot & 1 == 0, f'nx - 2 * nx_dum = {npar_tot} should be even.' + num_dum = nx * ny - npar_tot * nser + + # --- Routing of unit resistors --- # + hm_layer = self.conn_layer + 1 + vm_layer = hm_layer + 1 + xm_layer = vm_layer + 1 + ym_layer = xm_layer + 1 + xxm_layer = ym_layer + 1 + + # make 2 resistors out of all the resistor units + rp_bot, rp_top = self.connect_units(warrs, nx_dum, nx // 2, ny_dum, ny - ny_dum) + rm_bot, rm_top = self.connect_units(warrs, nx // 2, nx - nx_dum, ny_dum, ny - ny_dum) + + # Supply connections on xxm_layer + sub_type = cast(ResBasePlaceInfo, self.place_info).res_config['sub_type_default'] + sup_top0 = self.connect_via_stack(self.tr_manager, bulk_warrs[vm_layer][0], xxm_layer, 'sup') + sup_top1 = self.connect_via_stack(self.tr_manager, bulk_warrs[vm_layer][1], xxm_layer, 'sup') + sup_name = 'VDD' if sub_type == 'ntap' else 'VSS' + self.add_pin(sup_name, self.connect_wires([sup_top0, sup_top1])[0]) + + # connect XRP and XRM from vm_layer to xxm_layer + for _bot, _top, _suf in [(rp_bot, rp_top, 'p'), (rm_bot, rm_top, 'm')]: + _in = self.connect_stack(self.tr_manager, _bot, xxm_layer, 'sig') + _out = self.connect_stack(self.tr_manager, _top, xxm_layer, 'sig') + self.add_pin(f'{_suf}_in', _in) + self.add_pin(f'{_suf}_out', _out) + + self.sch_params = dict( + load_params=dict( + unit_params=unit_params, + nser=nser, + npar=npar_tot // 2, + ), + dum_params=dict( + unit_params=unit_params, + nser=1, + npar=num_dum, + ), + sub_type=sub_type, + ) + + def connect_stack(self, tr_manager: TrackManager, warr: WireArray, top_layer: int, w_type: str = 'sig'): + # this is different from connect_via_stack() as it does not connect the intermediate wires to reduce cap + top_warr = [] + for _warr in warr.warr_iter(): + top_warr.append(self.connect_via_stack(tr_manager, _warr, top_layer, w_type)) + return self.connect_wires(top_warr)[0] diff --git a/src/bag3_analog/measurement/drv_shunt_peak.py b/src/bag3_analog/measurement/drv_shunt_peak.py new file mode 100644 index 0000000..d7ad962 --- /dev/null +++ b/src/bag3_analog/measurement/drv_shunt_peak.py @@ -0,0 +1,283 @@ +from __future__ import annotations + +from typing import Any, Mapping, Optional, Union, Sequence +from pathlib import Path +from shutil import copy +import matplotlib.pyplot as plt +import numpy as np + +from bag.simulation.cache import SimulationDB, DesignInstance, SimResults +from bag.simulation.measure import MeasurementManager +from bag.simulation.data import SimData +from bag.concurrent.util import GatherHelper +from bag.math import float_to_si_string + +from bag3_testbenches.measurement.ac.base import ACTB +from bag3_testbenches.measurement.tran.digital import DigitalTranTB +from bag3_testbenches.measurement.tran.eye import EyeAnalysis, EyeResults +from bag3_testbenches.measurement.digital.util import setup_digital_tran + + +class DrvShuntPeakACMeas(MeasurementManager): + async def async_measure_performance(self, name: str, sim_dir: Path, sim_db: SimulationDB, + dut: Optional[DesignInstance], + harnesses: Optional[Sequence[DesignInstance]] = None) -> Mapping[str, Any]: + helper = GatherHelper() + sim_envs: Sequence[str] = self.specs['sim_envs'] + sweep_cases: Sequence[Mapping[str, Any]] = self.specs['sweep_cases'] + for sim_env in sim_envs: + for swidx, sweep_case in enumerate(sweep_cases): + helper.append(self.async_meas_pvt_case(name, sim_dir / sim_env / f'{swidx}', sim_db, dut, harnesses, + sim_env, sweep_case)) + + meas_results = await helper.gather_err() + results = {} + idx = 0 + for sim_env in sim_envs: + results[sim_env] = {} + for swidx, sweep_case in enumerate(sweep_cases): + results[sim_env][swidx] = {'data': meas_results[idx], 'sweep_case': sweep_case} + idx += 1 + + self.plot_results(results) + return results + + async def async_meas_pvt_case(self, name: str, sim_dir: Path, sim_db: SimulationDB, dut: Optional[DesignInstance], + harnesses: Optional[Sequence[DesignInstance]], pvt: str, + sweep_case: Mapping[str, Any]) -> SimData: + # outputs to be saved + save_outputs = ['i_outp', 'i_outm', 'v_inp', 'v_inm', 'v_tail_g', 'v_tail', 'ind_p', 'ind_m'] + + # create loads + load_list = [dict(pin='i_outp', type='cap', value='c_load'), + dict(pin='i_outp', nin='VDD', type='res', value='r_term'), + dict(pin='i_outm', type='cap', value='c_load'), + dict(pin='i_outm', nin='VDD', type='res', value='r_term')] + + # inductors + ind_specs: Optional[Mapping[str, Any]] = self.specs.get('ind_specs') + if ind_specs: + ideal: bool = ind_specs['ideal'] + if ideal: + load_list.extend([dict(pin='ind_p', nin='VDD', type='ind', value='l_shunt'), + dict(pin='ind_m', nin='VDD', type='ind', value='l_shunt')]) + else: + sp_file_specs: Mapping[str, Any] = ind_specs['sp_file_specs'] + sim_dir.mkdir(parents=True, exist_ok=True) + for key, _specs in sp_file_specs.items(): + file_name: Path = Path(_specs['file_name']) + _num = file_name.suffix[2:-1] + ind_sp = f'{key}.s{_num}p' + copy(Path(file_name), sim_dir / ind_sp) + conns: Sequence[Mapping[str, str]] = _specs['conns'] + for _idx, _conns in enumerate(conns): + load_list.append(dict(conns=_conns, type=f'n{_num}port', value=ind_sp, + name=f'NPORT_{key}_{_idx}')) + + # create sources + load_list.extend([dict(pin='v_tail_g', type='vdc', value='v_tail_g'), + dict(pin='v_inp', type='vdc', value={'vdc': 'v_incm', 'acm': 0.5}), + dict(pin='v_inm', type='vdc', value={'vdc': 'v_incm', 'acm': -0.5})]) + + # setup harness + if harnesses: + harnesses_list: Sequence[Mapping[str, Any]] = self.specs['harnesses_list'] + else: + harnesses_list = [] + + tb_params = dict( + load_list=load_list, + harnesses_list=harnesses_list, + sim_envs=[pvt], + ac_options={'oppoint': 'logfile'}, + save_outputs=save_outputs, + ) + tbm_specs, tb_params = setup_digital_tran(self.specs, dut, **tb_params) + tbm = self.make_tbm(ACTB, tbm_specs) + for key, val in sweep_case.items(): + tbm.sim_params[key] = val + sim_results = await sim_db.async_simulate_tbm_obj(f'{name}_{pvt}_{get_label(sweep_case)}', sim_dir, dut, tbm, + tb_params, harnesses=harnesses) + return sim_results.data + + @staticmethod + def plot_results(results: Mapping[str, Any]) -> None: + fig, ax_list = plt.subplots(1, len(results.keys())) + if not isinstance(ax_list, np.ndarray): + ax_list = np.array([ax_list]) + + aidx = 0 + for sim_env, sweeps in results.items(): + ax = ax_list[aidx] + for swidx, ans in results[sim_env].items(): + ac_data = ans['data'] + freq = ac_data['freq'] + out_d = ac_data['i_outp'][0] - ac_data['i_outm'][0] + sweep_case: Mapping[str, Any] = ans['sweep_case'] + ax.semilogx(freq, 20 * np.log10(np.abs(out_d)), label=get_label(sweep_case)) + ax.legend() + ax.grid() + ax.set_xlabel('Frequency (Hz)') + ax.set_ylabel('AC gain (dB)') + ax.set_title(sim_env) + aidx += 1 + + plt.tight_layout() + plt.show() + + +def get_label(sweep_case: Optional[Mapping[str, Any]]) -> str: + if sweep_case is None: + return '' + _label_list = [f'{key}_{float_to_si_string(val)}' for key, val in sweep_case.items()] + return '_'.join(_label_list) + + +class DrvShuntPeakTranMeas(MeasurementManager): + async def async_measure_performance(self, name: str, sim_dir: Path, sim_db: SimulationDB, + dut: Optional[DesignInstance], + harnesses: Optional[Sequence[DesignInstance]] = None) -> Mapping[str, Any]: + helper = GatherHelper() + sim_envs: Sequence[str] = self.specs['sim_envs'] + v_incm_swp: Union[np.ndarray, Sequence[float]] = self.specs['v_incm_swp'] + if isinstance(v_incm_swp, Sequence): + v_incm_swp = np.array(v_incm_swp) + v_tail_g_swp: Union[np.ndarray, Sequence[float]] = self.specs['v_tail_g_swp'] + if isinstance(v_tail_g_swp, Sequence): + v_tail_g_swp = np.array(v_tail_g_swp) + for sim_env in sim_envs: + for v_incm in v_incm_swp: + for v_tail_g in v_tail_g_swp: + _dir = f'v_incm_{float_to_si_string(v_incm)}_v_tail_g_{float_to_si_string(v_tail_g)}' + helper.append(self.async_meas_pvt_case(name, sim_dir / sim_env / _dir, sim_db, dut, harnesses, + sim_env, v_incm, v_tail_g)) + + meas_results = await helper.gather_err() + + # arrange meas_results in "results" for Designer and "plot_results" for plotting + results = {'sim_envs': np.array(sim_envs), 'v_incm': v_incm_swp, 'v_tail_g': v_tail_g_swp} + plot_results = {'sim_envs': np.array(sim_envs), 'v_incm': v_incm_swp, 'v_tail_g': v_tail_g_swp} + len_sim_envs = len(sim_envs) + len_v_incm = len(v_incm_swp) + len_v_tail_g = len(v_tail_g_swp) + results.update({'width': np.empty((len_sim_envs, len_v_incm, len_v_tail_g), dtype=float), + 'height': np.empty((len_sim_envs, len_v_incm, len_v_tail_g), dtype=float), + 'i_avg': np.empty((len_sim_envs, len_v_incm, len_v_tail_g), dtype=float)}) + plot_results['eye'] = [[] for _ in sim_envs] + idx = 0 + for jdx, _ in enumerate(sim_envs): + for kdx, _ in enumerate(v_incm_swp): + for ldx, _ in enumerate(v_tail_g_swp): + ans = meas_results[idx] + eye_res: EyeResults = ans['eye'] + results['width'][jdx, kdx, ldx] = eye_res.width + results['height'][jdx, kdx, ldx] = eye_res.height + results['i_avg'][jdx, kdx, ldx] = ans['i_avg'] + plot_results['eye'][jdx].append(eye_res) + idx += 1 + + # self.plot_results(plot_results) + return results + + async def async_meas_pvt_case(self, name: str, sim_dir: Path, sim_db: SimulationDB, dut: Optional[DesignInstance], + harnesses: Optional[Sequence[DesignInstance]], pvt: str, v_incm: float, + v_tail_g: float) -> Mapping[str, Any]: + # outputs to be saved + save_outputs = ['i_outp', 'i_outm', 'v_inp', 'v_inm', 'v_tail_g', 'v_tail', 'ind_p', 'ind_m', 'VDC_VDD:p'] + + # create loads + load_list = [dict(pin='i_outp', type='cap', value='c_load'), + dict(pin='i_outp', nin='VDD', type='res', value='r_term'), + dict(pin='i_outm', type='cap', value='c_load'), + dict(pin='i_outm', nin='VDD', type='res', value='r_term')] + + # inductors + ind_specs: Optional[Mapping[str, Any]] = self.specs.get('ind_specs') + if ind_specs: + ideal: bool = ind_specs['ideal'] + if ideal: + load_list.extend([dict(pin='ind_p', nin='VDD', type='ind', value='l_shunt'), + dict(pin='ind_m', nin='VDD', type='ind', value='l_shunt')]) + else: + sp_file_specs: Mapping[str, Any] = ind_specs['sp_file_specs'] + sim_dir.mkdir(parents=True, exist_ok=True) + for key, _specs in sp_file_specs.items(): + file_name: Path = Path(_specs['file_name']) + _num = file_name.suffix[2:-1] + ind_sp = f'{key}.s{_num}p' + copy(Path(file_name), sim_dir / ind_sp) + conns: Sequence[Mapping[str, str]] = _specs['conns'] + for _idx, _conns in enumerate(conns): + load_list.append(dict(conns=_conns, type=f'n{_num}port', value=ind_sp, + name=f'NPORT_{key}_{_idx}')) + + # create sources + load_list.extend([dict(pin='v_tail_g', type='vdc', value='v_tail_g'), + dict(conns={'vout': 'prbs_data'}, lib='ahdlLib', type='rand_bit_stream', + value={'tperiod': 't_per', 'vlogic_high': 'v_hi', 'vlogic_low': 'v_lo', + 'tdel': 't_delay', 'trise': 't_rf', 'tfall': 't_rf', 'seed': 101}), + dict(conns={'d': 'prbs_data', 'p': 'v_inp', 'n': 'v_inm', 'c': 'v_incm'}, type='ideal_balun', + value={}), + dict(pin='v_incm', type='vdc', value='v_incm')]) + + # setup harness + if harnesses: + harnesses_list: Sequence[Mapping[str, Any]] = self.specs['harnesses_list'] + else: + harnesses_list = [] + + tb_params = dict( + load_list=load_list, + harnesses_list=harnesses_list, + sim_envs=[pvt], + tran_options={'errpreset': 'conservative', 'noisefmax': 'fmax_noise'}, + save_outputs=save_outputs, + ) + tbm_specs, tb_params = setup_digital_tran(self.specs, dut, **tb_params) + tbm = self.make_tbm(DigitalTranTB, tbm_specs) + tbm.sim_params['v_incm'] = v_incm + tbm.sim_params['v_tail_g'] = v_tail_g + sim_results = await sim_db.async_simulate_tbm_obj(name, sim_dir, dut, tbm, tb_params, harnesses=harnesses) + return self.process_results(sim_results) + + @staticmethod + def process_results(sim_results: SimResults) -> Mapping[str, Any]: + sim_data = sim_results.data + time = sim_data['time'] + + # compute average current consumption + i_vdd = - sim_data['VDC_VDD:p'][0] + i_avg = np.trapz(i_vdd, time) / time[-1] + + # analyze eye + out_d = sim_data['i_outp'][0] - sim_data['i_outm'][0] + tbm = sim_results.tbm + t_per = tbm.sim_params['t_per'] + t_delay = tbm.sim_params['t_delay'] + eye_ana = EyeAnalysis(t_per, t_delay) + + return dict( + eye=eye_ana.analyze_eye(time, out_d), + i_avg=i_avg, + ) + + @staticmethod + def plot_results(results: Mapping[str, Any]) -> None: + sim_envs: Sequence[str] = results['sim_envs'] + v_incm_swp: np.ndarray = results['v_incm'] + v_tail_g_swp: np.ndarray = results['v_tail_g'] + fig, ax_list = plt.subplots(len(sim_envs), len(v_incm_swp) * len(v_tail_g_swp)) + if not isinstance(ax_list, np.ndarray): + ax_list = np.array([ax_list]) + + for jdx, sim_env in enumerate(sim_envs): + for kdx, v_incm in enumerate(v_incm_swp): + for ldx, v_tail_g in enumerate(v_tail_g_swp): + eidx = kdx * len(v_tail_g_swp) + ldx + ax = ax_list[jdx, eidx] + eye_results: EyeResults = results['eye'][jdx][eidx] + eye_results.plot(ax) + ax.set_title(f'{sim_env}; v_incm={v_incm}; v_tail_g={v_tail_g}') + + plt.tight_layout() + plt.show() diff --git a/src/bag3_analog/schematic/drv_shunt_peak.py b/src/bag3_analog/schematic/drv_shunt_peak.py new file mode 100644 index 0000000..2dbb7d6 --- /dev/null +++ b/src/bag3_analog/schematic/drv_shunt_peak.py @@ -0,0 +1,135 @@ +# BSD 3-Clause License +# +# Copyright (c) 2018, Regents of the University of California +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# -*- coding: utf-8 -*- + +from typing import Mapping, Any, Union + +import pkg_resources +from pathlib import Path +from enum import IntEnum + +from bag.design.module import Module +from bag.design.database import ModuleDB +from bag.util.immutable import Param + +from pybag.enum import TermType + + +class LayMode(IntEnum): + TOP = 0 # for top level DRC and LVS + EXT = 1 # for extraction + EM = 2 # for em simulation + + +# noinspection PyPep8Naming +class bag3_analog__drv_shunt_peak(Module): + """Module for library bag3_analog cell drv_shunt_peak. + + Fill in high level description here. + """ + + yaml_file = pkg_resources.resource_filename(__name__, + str(Path('netlist_info', + 'drv_shunt_peak.yaml'))) + + def __init__(self, database: ModuleDB, params: Param, **kwargs: Any) -> None: + Module.__init__(self, self.yaml_file, database, params, **kwargs) + + @classmethod + def get_params_info(cls) -> Mapping[str, str]: + """Returns a dictionary from parameter names to descriptions. + + Returns + ------- + param_info : Optional[Mapping[str, str]] + dictionary from parameter names to descriptions. + """ + return dict( + gm='Parameters for gm cells', + res='Parameters for differential resistors', + ind='Parameters for shunt differential inductor', + lay_mode='Layout mode, TOP by default.', + ) + + def design(self, gm: Mapping[str, Any], res: Mapping[str, Any], ind: Mapping[str, Any], + lay_mode: Union[LayMode, str]) -> None: + """To be overridden by subclasses to design this module. + + This method should fill in values for all parameters in + self.parameters. To design instances of this module, you can + call their design() method or any other ways you coded. + + To modify schematic structure, call: + + rename_pin() + delete_instance() + replace_instance_master() + reconnect_instance_terminal() + restore_instance() + array_instance() + """ + remove_pins = [] + + # gm cell + gen_gm = lay_mode is LayMode.TOP or lay_mode is LayMode.EXT + if gen_gm: + self.instances['XGM'].design(**gm) + else: + self.remove_instance('XGM') + remove_pins.extend(['v_inp', 'v_inm', 'v_tail_g', 'v_tail', 'i_outp', 'i_outm', 'VSS']) + + # resistors + gen_res = lay_mode is LayMode.TOP or lay_mode is LayMode.EXT + if gen_res: + self.instances['XRES'].design(**res) + else: + self.remove_instance('XRES') + remove_pins.extend(['VDD']) + + # shunt inductors + gen_ind = lay_mode is LayMode.TOP or lay_mode is LayMode.EM + if gen_ind: + self.instances['XIND'].design(**ind) + if lay_mode is LayMode.TOP: + self.reconnect_instance_terminal('XIND', 'P2_R', 'VDD') + else: + # lay_mode is LayMode.EM + self.reconnect_instance('XIND', [('P1', 'P1'), ('P3', 'P3'), ('P2', 'P2'), + ('P13_R', 'P13_R'), ('P2_R', 'P2_R')]) + self.rename_pin('ind_p', 'P1') + self.rename_pin('ind_m', 'P3') + for pin in ('P2', 'P13_R', 'P2_R'): + self.add_pin(pin, TermType.inout) + else: + self.remove_instance('XIND') + + for pin in remove_pins: + self.remove_pin(pin) diff --git a/src/bag3_analog/schematic/gm_stage.py b/src/bag3_analog/schematic/gm_stage.py new file mode 100644 index 0000000..b5066cc --- /dev/null +++ b/src/bag3_analog/schematic/gm_stage.py @@ -0,0 +1,109 @@ +# BSD 3-Clause License +# +# Copyright (c) 2018, Regents of the University of California +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# -*- coding: utf-8 -*- + +from typing import Mapping, Any + +import pkg_resources +from pathlib import Path + +from bag.design.module import Module +from bag.design.database import ModuleDB +from bag.util.immutable import Param + + +# noinspection PyPep8Naming +class bag3_analog__gm_stage(Module): + """Module for library bag3_analog cell gm_stage. + + Fill in high level description here. + """ + + yaml_file = pkg_resources.resource_filename(__name__, + str(Path('netlist_info', + 'gm_stage.yaml'))) + + def __init__(self, database: ModuleDB, params: Param, **kwargs: Any) -> None: + Module.__init__(self, self.yaml_file, database, params, **kwargs) + + @classmethod + def get_params_info(cls) -> Mapping[str, str]: + """Returns a dictionary from parameter names to descriptions. + + Returns + ------- + param_info : Optional[Mapping[str, str]] + dictionary from parameter names to descriptions. + """ + return dict( + lch='Channel length, in resolution units', + w_dict='Dictionary of transistor widths, in resolution units', + th_dict='Dictionary of transistor thresholds', + seg_dict='Dictionary of transistor segments', + export_tail='True to export tail node; False by default', + is_dum='True if the gm stage is used as dummy load; False by default', + guard_ring='True if gm_stage is in guard ring; False by default', + ) + + @classmethod + def get_default_param_values(cls) -> Mapping[str, Any]: + return dict(export_tail=False, is_dum=False, guard_ring=False) + + def design(self, lch: int, w_dict: Mapping[str, int], th_dict: Mapping[str, str], seg_dict: Mapping[str, int], + export_tail: bool, is_dum: bool, guard_ring: bool) -> None: + """To be overridden by subclasses to design this module. + + This method should fill in values for all parameters in + self.parameters. To design instances of this module, you can + call their design() method or any other ways you coded. + + To modify schematic structure, call: + + rename_pin() + delete_instance() + replace_instance_master() + reconnect_instance_terminal() + restore_instance() + array_instance() + """ + for name, key in [('XTAIL', 'tail'), ('XP', 'gm'), ('XM', 'gm')]: + self.design_transistor(name, w_dict[key], lch, seg_dict[key], th_dict[key]) + + if is_dum or not export_tail: + self.remove_pin('v_tail') + + if is_dum: + for pin in ('v_tail_g', 'v_outp', 'v_outm'): + self.remove_pin(pin) + self.reconnect_instance_terminal('XTAIL', 'G', 'VSS') + + if not guard_ring: + self.remove_pin('VDD') diff --git a/src/bag3_analog/schematic/netlist_info/drv_shunt_peak.symbol.yaml b/src/bag3_analog/schematic/netlist_info/drv_shunt_peak.symbol.yaml new file mode 100644 index 0000000..9fb365b --- /dev/null +++ b/src/bag3_analog/schematic/netlist_info/drv_shunt_peak.symbol.yaml @@ -0,0 +1,503 @@ +lib_name: bag3_analog +cell_name: drv_shunt_peak +view_name: symbol +bbox: + - -4 + - -4 + - 344 + - 284 +terminals: + VDD: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 176 + - 276 + - 184 + - 284 + stype: 1 + ttype: 2 + VSS: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 176 + - -4 + - 184 + - 4 + stype: 2 + ttype: 2 + i_outm: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 336 + - 176 + - 344 + - 184 + stype: 0 + ttype: 1 + i_outp: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 336 + - 196 + - 344 + - 204 + stype: 0 + ttype: 1 + ind_m: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 336 + - 116 + - 344 + - 124 + stype: 0 + ttype: 2 + ind_p: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 336 + - 136 + - 344 + - 144 + stype: 0 + ttype: 2 + v_inm: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - -4 + - 176 + - 4 + - 184 + stype: 0 + ttype: 0 + v_inp: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - -4 + - 196 + - 4 + - 204 + stype: 0 + ttype: 0 + v_tail: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 336 + - 76 + - 344 + - 84 + stype: 0 + ttype: 1 + v_tail_g: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - -4 + - 76 + - 4 + - 84 + stype: 0 + ttype: 0 +shapes: + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 0 + - 80 + - + - 40 + - 80 + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 6 + - 90 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_tail_g + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 0 + - 180 + - + - 40 + - 180 + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 6 + - 210 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_inp + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 0 + - 200 + - + - 40 + - 200 + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 6 + - 170 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_inm + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 340 + - 140 + - + - 300 + - 140 + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 334 + - 110 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: ind_m + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 340 + - 120 + - + - 300 + - 120 + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 334 + - 150 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: ind_p + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 340 + - 80 + - + - 300 + - 80 + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 334 + - 90 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_tail + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 340 + - 180 + - + - 300 + - 180 + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 334 + - 210 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: i_outp + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 340 + - 200 + - + - 300 + - 200 + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 334 + - 170 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: i_outm + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 180 + - 280 + - + - 180 + - 240 + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 170 + - 274 + alignment: 1 + orient: R270 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 180 + - 0 + - + - 180 + - 40 + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 170 + - 6 + alignment: 7 + orient: R270 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VSS + - + - 0 + - layer: 236 + purpose: 4294967295 + net: "" + bbox: + - 0 + - 0 + - 340 + - 280 + - + - 8 + - layer: 236 + purpose: 237 + net: "" + origin: + - 200 + - 250 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: "[@instanceName]" + evaluator: cdsNLPEvalText + - + - 8 + - layer: 231 + purpose: 237 + net: "" + origin: + - 105 + - 225 + alignment: 4 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: "[@partName]" + evaluator: cdsNLPEvalText + - + - 0 + - layer: 231 + purpose: 4294967295 + net: "" + bbox: + - 40 + - 40 + - 300 + - 240 +instances: + {} +props: + interfaceLastChanged: + - 4 + - time_val: 1676499642 + partName: + - 3 + - drv_shunt_peak + pin#: + - 0 + - 10 + portOrder: + - 5 + - name: ILList + bin_val: ("i_outm" "i_outp" "v_tail" "VDD" "VSS" "ind_m" "ind_p" "v_inm" "v_inp" "v_tail_g") + vendorName: + - 3 + - "" +app_defs: + _dbLastSavedCounter: + - 0 + - 260 + _dbvCvTimeStamp: + - 0 + - 260 + cdbRevision: + - 0 + - 227612 diff --git a/src/bag3_analog/schematic/netlist_info/drv_shunt_peak.yaml b/src/bag3_analog/schematic/netlist_info/drv_shunt_peak.yaml new file mode 100644 index 0000000..da0c482 --- /dev/null +++ b/src/bag3_analog/schematic/netlist_info/drv_shunt_peak.yaml @@ -0,0 +1,1029 @@ +lib_name: bag3_analog +cell_name: drv_shunt_peak +view_name: schematic +bbox: + - -769 + - -241 + - 268 + - 450 +terminals: + VDD: + obj: + - 1 + - inst: + lib_name: basic + cell_name: iopin + view_name: symbolr + xform: + - -620 + - 260 + - R0 + bbox: + - -681 + - 234 + - -610 + - 270 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -645 + - 260 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 1 + ttype: 2 + VSS: + obj: + - 1 + - inst: + lib_name: basic + cell_name: iopin + view_name: symbolr + xform: + - -620 + - 50 + - R0 + bbox: + - -681 + - 24 + - -610 + - 60 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -645 + - 50 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 2 + ttype: 2 + i_outm: + obj: + - 1 + - inst: + lib_name: basic + cell_name: opin + view_name: symbol + xform: + - -570 + - 160 + - R0 + bbox: + - -570 + - 134 + - -513 + - 170 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -545 + - 160 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 1 + i_outp: + obj: + - 1 + - inst: + lib_name: basic + cell_name: opin + view_name: symbol + xform: + - -570 + - 190 + - R0 + bbox: + - -570 + - 164 + - -513 + - 200 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -545 + - 190 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 1 + ind_m: + obj: + - 1 + - inst: + lib_name: basic + cell_name: iopin + view_name: symbolr + xform: + - -560 + - -40 + - R0 + bbox: + - -621 + - -66 + - -550 + - -30 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -585 + - -40 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 2 + ind_p: + obj: + - 1 + - inst: + lib_name: basic + cell_name: iopin + view_name: symbolr + xform: + - -560 + - -10 + - R0 + bbox: + - -621 + - -36 + - -550 + - 0 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -585 + - -10 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 2 + v_inm: + obj: + - 1 + - inst: + lib_name: basic + cell_name: ipin + view_name: symbol + xform: + - -680 + - 160 + - R0 + bbox: + - -737 + - 134 + - -680 + - 170 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -710 + - 160 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 0 + v_inp: + obj: + - 1 + - inst: + lib_name: basic + cell_name: ipin + view_name: symbol + xform: + - -680 + - 190 + - R0 + bbox: + - -737 + - 164 + - -680 + - 200 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -710 + - 190 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 0 + v_tail: + obj: + - 1 + - inst: + lib_name: basic + cell_name: opin + view_name: symbol + xform: + - -570 + - 120 + - R0 + bbox: + - -570 + - 94 + - -513 + - 130 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -545 + - 120 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 1 + v_tail_g: + obj: + - 1 + - inst: + lib_name: basic + cell_name: ipin + view_name: symbol + xform: + - -680 + - 120 + - R0 + bbox: + - -737 + - 94 + - -680 + - 130 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -710 + - 120 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 0 +shapes: + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VDD + points: + - + - 0 + - 140 + - + - 0 + - 180 + - + - 7 + - layer: 228 + purpose: 237 + net: VDD + origin: + - -7 + - 176 + alignment: 8 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 5 + - layer: 228 + purpose: 4294967295 + net: ind_m + points: + - + - -40 + - 140 + - + - -40 + - 180 + - + - 7 + - layer: 228 + purpose: 237 + net: ind_m + origin: + - -47 + - 176 + alignment: 8 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: ind_m + - + - 5 + - layer: 228 + purpose: 4294967295 + net: ind_p + points: + - + - -60 + - 140 + - + - -60 + - 180 + - + - 7 + - layer: 228 + purpose: 237 + net: ind_p + origin: + - -67 + - 176 + alignment: 8 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: ind_p + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VDD + points: + - + - 0 + - 410 + - + - 0 + - 450 + - + - 7 + - layer: 228 + purpose: 237 + net: VDD + origin: + - -7 + - 414 + alignment: 2 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VDD + points: + - + - -40 + - 410 + - + - -40 + - 450 + - + - 7 + - layer: 228 + purpose: 237 + net: VDD + origin: + - -47 + - 414 + alignment: 2 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VDD + points: + - + - -60 + - 410 + - + - -60 + - 450 + - + - 7 + - layer: 228 + purpose: 237 + net: VDD + origin: + - -67 + - 414 + alignment: 2 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 5 + - layer: 228 + purpose: 4294967295 + net: i_outp + points: + - + - 10 + - -10 + - + - 50 + - -10 + - + - 7 + - layer: 228 + purpose: 237 + net: i_outp + origin: + - 46 + - -3 + alignment: 8 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: i_outp + - + - 5 + - layer: 228 + purpose: 4294967295 + net: ind_m + points: + - + - 130 + - -230 + - + - 130 + - -190 + - + - 7 + - layer: 228 + purpose: 237 + net: ind_m + origin: + - 123 + - -194 + alignment: 8 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: ind_m + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VDD + points: + - + - 210 + - -10 + - + - 250 + - -10 + - + - 7 + - layer: 228 + purpose: 237 + net: VDD + origin: + - 214 + - -3 + alignment: 2 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 5 + - layer: 228 + purpose: 4294967295 + net: ind_p + points: + - + - 130 + - 150 + - + - 130 + - 190 + - + - 7 + - layer: 228 + purpose: 237 + net: ind_p + origin: + - 123 + - 154 + alignment: 2 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: ind_p + - + - 5 + - layer: 228 + purpose: 4294967295 + net: i_outm + points: + - + - 10 + - -30 + - + - 50 + - -30 + - + - 7 + - layer: 228 + purpose: 237 + net: i_outm + origin: + - 46 + - -23 + alignment: 8 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: i_outm + - + - 5 + - layer: 228 + purpose: 4294967295 + net: i_outp + points: + - + - -90 + - -40 + - + - -50 + - -40 + - + - 7 + - layer: 228 + purpose: 237 + net: i_outp + origin: + - -86 + - -33 + alignment: 2 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: i_outp + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VSS + points: + - + - -190 + - -180 + - + - -190 + - -140 + - + - 7 + - layer: 228 + purpose: 237 + net: VSS + origin: + - -197 + - -144 + alignment: 8 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VSS + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VDD + points: + - + - -190 + - 100 + - + - -190 + - 140 + - + - 7 + - layer: 228 + purpose: 237 + net: VDD + origin: + - -197 + - 104 + alignment: 2 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 5 + - layer: 228 + purpose: 4294967295 + net: i_outm + points: + - + - -90 + - 0 + - + - -50 + - 0 + - + - 7 + - layer: 228 + purpose: 237 + net: i_outm + origin: + - -86 + - 7 + alignment: 2 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: i_outm + - + - 5 + - layer: 228 + purpose: 4294967295 + net: v_tail + points: + - + - -90 + - -20 + - + - -50 + - -20 + - + - 7 + - layer: 228 + purpose: 237 + net: v_tail + origin: + - -86 + - -13 + alignment: 2 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_tail + - + - 5 + - layer: 228 + purpose: 4294967295 + net: v_inm + points: + - + - -310 + - -60 + - + - -270 + - -60 + - + - 7 + - layer: 228 + purpose: 237 + net: v_inm + origin: + - -274 + - -53 + alignment: 8 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_inm + - + - 5 + - layer: 228 + purpose: 4294967295 + net: v_inp + points: + - + - -310 + - 20 + - + - -270 + - 20 + - + - 7 + - layer: 228 + purpose: 237 + net: v_inp + origin: + - -274 + - 27 + alignment: 8 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_inp + - + - 5 + - layer: 228 + purpose: 4294967295 + net: v_tail_g + points: + - + - -310 + - -20 + - + - -270 + - -20 + - + - 7 + - layer: 228 + purpose: 237 + net: v_tail_g + origin: + - -274 + - -13 + alignment: 8 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_tail_g +instances: + XGM: + lib_name: bag3_analog + cell_name: gm_stage + view_name: symbol + xform: + - -270 + - -140 + - R0 + bbox: + - -283 + - -144 + - -42 + - 104 + connections: + VDD: VDD + VSS: VSS + i_outm: i_outm + i_outp: i_outp + v_inm: v_inm + v_inp: v_inp + v_tail: v_tail + v_tail_g: v_tail_g + params: + {} + is_primitive: false + XIND: + lib_name: bag3_magnetics + cell_name: ind_diff_wrap + view_name: symbol + xform: + - -100 + - 180 + - R0 + bbox: + - -100 + - 176 + - 68 + - 414 + connections: + P1: ind_p + P13_R: VDD + P2: VDD + P24_R: VDD + P3: ind_m + P4: VDD + params: + {} + is_primitive: false + XRES: + lib_name: bag3_analog + cell_name: res_diff + view_name: symbol + xform: + - 50 + - -190 + - R0 + bbox: + - 12 + - -194 + - 268 + - 154 + connections: + VDD: VDD + m_in: i_outm + m_out: ind_m + p_in: i_outp + p_out: ind_p + params: + {} + is_primitive: false +props: + connectivityLastUpdated: + - 0 + - 609 + lastSchematicExtraction: + - 4 + - time_val: 1676499794 + pin#: + - 0 + - 10 + schGeometryLastUpdated: + - 0 + - 609 + schGeometryVersion: + - 3 + - sch.ds.gm.1.4 +app_defs: + _dbLastSavedCounter: + - 0 + - 609 + _dbvCvTimeStamp: + - 0 + - 609 + cdbRevision: + - 0 + - 227612 diff --git a/src/bag3_analog/schematic/netlist_info/gm_stage.symbol.yaml b/src/bag3_analog/schematic/netlist_info/gm_stage.symbol.yaml new file mode 100644 index 0000000..e4a2b8a --- /dev/null +++ b/src/bag3_analog/schematic/netlist_info/gm_stage.symbol.yaml @@ -0,0 +1,433 @@ +lib_name: bag3_analog +cell_name: gm_stage +view_name: symbol +bbox: + - -13 + - -4 + - 228 + - 244 +terminals: + VDD: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 76 + - 236 + - 84 + - 244 + stype: 1 + ttype: 2 + VSS: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 76 + - -4 + - 84 + - 4 + stype: 2 + ttype: 2 + i_outm: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 176 + - 136 + - 184 + - 144 + stype: 0 + ttype: 1 + i_outp: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 176 + - 96 + - 184 + - 104 + stype: 0 + ttype: 1 + v_inm: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - -4 + - 76 + - 4 + - 84 + stype: 0 + ttype: 0 + v_inp: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - -4 + - 156 + - 4 + - 164 + stype: 0 + ttype: 0 + v_tail: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 176 + - 116 + - 184 + - 124 + stype: 0 + ttype: 1 + v_tail_g: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - -4 + - 116 + - 4 + - 124 + stype: 0 + ttype: 0 +shapes: + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 80 + - 240 + - + - 80 + - 220 + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 90 + - 234 + alignment: 1 + orient: R270 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 0 + - layer: 236 + purpose: 4294967295 + net: "" + bbox: + - 0 + - 0 + - 180 + - 240 + - + - 8 + - layer: 236 + purpose: 237 + net: "" + origin: + - 100 + - 230 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: "[@instanceName]" + evaluator: cdsNLPEvalText + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 0 + - 80 + - + - 60 + - 80 + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 0 + - 160 + - + - 60 + - 160 + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 0 + - 120 + - + - 60 + - 120 + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 80 + - 0 + - + - 80 + - 50 + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 60 + - 160 + - + - 60 + - 40 + - + - 120 + - 80 + - + - 120 + - 160 + - + - 60 + - 200 + - + - 60 + - 150 + - + - 0 + - layer: 231 + purpose: 4294967295 + net: "" + bbox: + - 20 + - 20 + - 160 + - 220 + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 180 + - 140 + - + - 120 + - 140 + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 180 + - 100 + - + - 120 + - 100 + - + - 8 + - layer: 231 + purpose: 237 + net: "" + origin: + - 35 + - 210 + alignment: 4 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: "[@partName]" + evaluator: cdsNLPEvalText + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 6 + - 90 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_inm + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 6 + - 170 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_inp + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 6 + - 130 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_tail_g + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 90 + - 6 + alignment: 7 + orient: R270 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VSS + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 174 + - 130 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_tail + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 174 + - 150 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: i_outm + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 174 + - 110 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: i_outp +instances: + {} +props: + interfaceLastChanged: + - 4 + - time_val: 1648515456 + partName: + - 3 + - gm_stage + pin#: + - 0 + - 15 + portOrder: + - 5 + - name: ILList + bin_val: ("i_outm" "i_outp" "v_tail" "VDD" "VSS" "v_inm" "v_inp" "v_tail_g") + vendorName: + - 3 + - "" +app_defs: + _dbLastSavedCounter: + - 0 + - 344 + _dbvCvTimeStamp: + - 0 + - 344 + cdbRevision: + - 0 + - 227612 diff --git a/src/bag3_analog/schematic/netlist_info/gm_stage.yaml b/src/bag3_analog/schematic/netlist_info/gm_stage.yaml new file mode 100644 index 0000000..d65884a --- /dev/null +++ b/src/bag3_analog/schematic/netlist_info/gm_stage.yaml @@ -0,0 +1,736 @@ +lib_name: bag3_analog +cell_name: gm_stage +view_name: schematic +bbox: + - -439 + - -195 + - 188 + - 180 +terminals: + VDD: + obj: + - 1 + - inst: + lib_name: basic + cell_name: iopin + view_name: symbolr + xform: + - -300 + - 170 + - R0 + bbox: + - -361 + - 144 + - -290 + - 180 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -325 + - 170 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 1 + ttype: 2 + VSS: + obj: + - 1 + - inst: + lib_name: basic + cell_name: iopin + view_name: symbolr + xform: + - -300 + - -20 + - R0 + bbox: + - -361 + - -46 + - -290 + - -10 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -325 + - -20 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 2 + ttype: 2 + i_outm: + obj: + - 1 + - inst: + lib_name: basic + cell_name: opin + view_name: symbol + xform: + - -260 + - 80 + - R0 + bbox: + - -260 + - 54 + - -203 + - 90 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -235 + - 80 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 1 + i_outp: + obj: + - 1 + - inst: + lib_name: basic + cell_name: opin + view_name: symbol + xform: + - -260 + - 120 + - R0 + bbox: + - -260 + - 94 + - -203 + - 130 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -235 + - 120 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 1 + v_inm: + obj: + - 1 + - inst: + lib_name: basic + cell_name: ipin + view_name: symbol + xform: + - -350 + - 80 + - R0 + bbox: + - -407 + - 54 + - -350 + - 90 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -380 + - 80 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 0 + v_inp: + obj: + - 1 + - inst: + lib_name: basic + cell_name: ipin + view_name: symbol + xform: + - -350 + - 120 + - R0 + bbox: + - -407 + - 94 + - -350 + - 130 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -380 + - 120 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 0 + v_tail: + obj: + - 1 + - inst: + lib_name: basic + cell_name: opin + view_name: symbol + xform: + - -260 + - 40 + - R0 + bbox: + - -260 + - 14 + - -203 + - 50 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -235 + - 40 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 1 + v_tail_g: + obj: + - 1 + - inst: + lib_name: basic + cell_name: ipin + view_name: symbol + xform: + - -350 + - 40 + - R0 + bbox: + - -407 + - 14 + - -350 + - 50 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -380 + - 40 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 0 +shapes: + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VSS + points: + - + - 0 + - -160 + - + - 0 + - -130 + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VSS + points: + - + - 0 + - -190 + - + - 0 + - -160 + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VSS + points: + - + - -80 + - -10 + - + - 80 + - -10 + - + - 7 + - layer: 228 + purpose: 237 + net: VSS + origin: + - -6 + - -3 + alignment: 2 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VSS + - + - 5 + - layer: 228 + purpose: 4294967295 + net: v_tail + points: + - + - -80 + - -80 + - + - -80 + - -40 + - + - 5 + - layer: 228 + purpose: 4294967295 + net: i_outm + points: + - + - -80 + - 20 + - + - -80 + - 60 + - + - 5 + - layer: 228 + purpose: 4294967295 + net: v_tail + points: + - + - -80 + - -80 + - + - 0 + - -80 + - + - 5 + - layer: 228 + purpose: 4294967295 + net: v_tail + points: + - + - 0 + - -100 + - + - 0 + - -80 + - + - 5 + - layer: 228 + purpose: 4294967295 + net: v_tail + points: + - + - 80 + - -80 + - + - 80 + - -40 + - + - 5 + - layer: 228 + purpose: 4294967295 + net: v_tail + points: + - + - 0 + - -80 + - + - 80 + - -80 + - + - 4 + - layer: 228 + purpose: 4294967295 + net: "" + bbox: + - -5 + - -85 + - 5 + - -75 + - + - 7 + - layer: 228 + purpose: 237 + net: i_outm + origin: + - -87 + - 24 + alignment: 2 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: i_outm + - + - 5 + - layer: 228 + purpose: 4294967295 + net: v_inp + points: + - + - -160 + - -10 + - + - -120 + - -10 + - + - 7 + - layer: 228 + purpose: 237 + net: v_inp + origin: + - -124 + - -3 + alignment: 8 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_inp + - + - 5 + - layer: 228 + purpose: 4294967295 + net: i_outp + points: + - + - 80 + - 20 + - + - 80 + - 60 + - + - 7 + - layer: 228 + purpose: 237 + net: i_outp + origin: + - 73 + - 24 + alignment: 2 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: i_outp + - + - 5 + - layer: 228 + purpose: 4294967295 + net: v_inm + points: + - + - 120 + - -10 + - + - 160 + - -10 + - + - 7 + - layer: 228 + purpose: 237 + net: v_inm + origin: + - 124 + - -3 + alignment: 2 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_inm + - + - 5 + - layer: 228 + purpose: 4294967295 + net: v_tail_g + points: + - + - -80 + - -130 + - + - -40 + - -130 + - + - 7 + - layer: 228 + purpose: 237 + net: v_tail_g + origin: + - -44 + - -123 + alignment: 8 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_tail_g + - + - 7 + - layer: 228 + purpose: 237 + net: VSS + origin: + - -7 + - -180 + alignment: 5 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VSS + - + - 7 + - layer: 228 + purpose: 237 + net: v_tail + origin: + - 20 + - -73 + alignment: 5 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: v_tail +instances: + XM: + lib_name: BAG_prim + cell_name: nmos4_standard + view_name: symbol + xform: + - 120 + - -10 + - MY + bbox: + - -12 + - -44 + - 188 + - 35 + connections: + B: VSS + D: i_outp + G: v_inm + S: v_tail + params: + l: + - 3 + - 18n + nf: + - 3 + - 1 + w: + - 3 + - 4 + is_primitive: true + XP: + lib_name: BAG_prim + cell_name: nmos4_standard + view_name: symbol + xform: + - -120 + - -10 + - R0 + bbox: + - -188 + - -44 + - 12 + - 35 + connections: + B: VSS + D: i_outm + G: v_inp + S: v_tail + params: + l: + - 3 + - 18n + nf: + - 3 + - 1 + w: + - 3 + - 4 + is_primitive: true + XTAIL: + lib_name: BAG_prim + cell_name: nmos4_standard + view_name: symbol + xform: + - -40 + - -130 + - R0 + bbox: + - -108 + - -164 + - 92 + - -85 + connections: + B: VSS + D: v_tail + G: v_tail_g + S: VSS + params: + l: + - 3 + - 18n + nf: + - 3 + - 1 + w: + - 3 + - 4 + is_primitive: true +props: + connectivityLastUpdated: + - 0 + - 1736 + lastSchematicExtraction: + - 4 + - time_val: 1648515470 + net#: + - 0 + - 3 + pin#: + - 0 + - 8 + schGeometryLastUpdated: + - 0 + - 1736 + schGeometryVersion: + - 3 + - sch.ds.gm.1.4 + schXtrVersion: + - 3 + - sch.10.0 +app_defs: + _dbLastSavedCounter: + - 0 + - 1736 + _dbvCvTimeStamp: + - 0 + - 1736 + cdbRevision: + - 0 + - 227612 diff --git a/src/bag3_analog/schematic/netlist_info/res_diff.symbol.yaml b/src/bag3_analog/schematic/netlist_info/res_diff.symbol.yaml new file mode 100644 index 0000000..cf7a1dc --- /dev/null +++ b/src/bag3_analog/schematic/netlist_info/res_diff.symbol.yaml @@ -0,0 +1,358 @@ +lib_name: bag3_analog +cell_name: res_diff +view_name: symbol +bbox: + - -38 + - -4 + - 218 + - 344 +terminals: + VDD: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 156 + - 176 + - 164 + - 184 + stype: 1 + ttype: 2 + m_in: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - -4 + - 156 + - 4 + - 164 + stype: 1 + ttype: 2 + m_out: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 76 + - -4 + - 84 + - 4 + stype: 0 + ttype: 2 + p_in: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - -4 + - 176 + - 4 + - 184 + stype: 0 + ttype: 2 + p_out: + obj: + - 0 + - layer: 229 + purpose: 4294967295 + net: "" + bbox: + - 76 + - 336 + - 84 + - 344 + stype: 1 + ttype: 2 +shapes: + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 6 + - 150 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: m_in + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 6 + - 190 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: p_in + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 140 + - 180 + - + - 160 + - 180 + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 154 + - 190 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 70 + - 334 + alignment: 1 + orient: R270 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: p_out + - + - 7 + - layer: 229 + purpose: 237 + net: "" + origin: + - 90 + - 6 + alignment: 7 + orient: R270 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: m_out + - + - 0 + - layer: 236 + purpose: 4294967295 + net: "" + bbox: + - 0 + - 0 + - 160 + - 340 + - + - 8 + - layer: 236 + purpose: 237 + net: "" + origin: + - 90 + - 330 + alignment: 1 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: "[@instanceName]" + evaluator: cdsNLPEvalText + - + - 8 + - layer: 231 + purpose: 237 + net: "" + origin: + - 10 + - 305 + alignment: 4 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: "[@partName]" + evaluator: cdsNLPEvalText + - + - 0 + - layer: 231 + purpose: 4294967295 + net: "" + bbox: + - 20 + - 20 + - 140 + - 320 + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 80 + - 0 + - + - 80 + - 0 + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 80 + - 180 + - + - 80 + - 180 + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 80 + - 0 + - + - 80 + - 40 + - + - 60 + - 60 + - + - 100 + - 80 + - + - 60 + - 100 + - + - 100 + - 120 + - + - 80 + - 140 + - + - 80 + - 160 + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 80 + - 180 + - + - 80 + - 200 + - + - 60 + - 220 + - + - 100 + - 240 + - + - 60 + - 260 + - + - 100 + - 280 + - + - 80 + - 300 + - + - 80 + - 340 + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 80 + - 180 + - + - 0 + - 180 + - + - 5 + - layer: 231 + purpose: 4294967295 + net: "" + points: + - + - 80 + - 160 + - + - 0 + - 160 +instances: + {} +props: + interfaceLastChanged: + - 4 + - time_val: 1676499327 + partName: + - 3 + - res_diff + pin#: + - 0 + - 9 + portOrder: + - 5 + - name: ILList + bin_val: ("VDD" "m_in" "p_in" "m_out" "p_out") + vendorName: + - 3 + - "" +app_defs: + _dbLastSavedCounter: + - 0 + - 364 + _dbvCvTimeStamp: + - 0 + - 364 + cdbRevision: + - 0 + - 227612 diff --git a/src/bag3_analog/schematic/netlist_info/res_diff.yaml b/src/bag3_analog/schematic/netlist_info/res_diff.yaml new file mode 100644 index 0000000..8d92c4f --- /dev/null +++ b/src/bag3_analog/schematic/netlist_info/res_diff.yaml @@ -0,0 +1,565 @@ +lib_name: bag3_analog +cell_name: res_diff +view_name: schematic +bbox: + - -383 + - -113 + - 180 + - 430 +terminals: + VDD: + obj: + - 1 + - inst: + lib_name: basic + cell_name: iopin + view_name: symbolr + xform: + - -270 + - 340 + - R0 + bbox: + - -331 + - 314 + - -260 + - 350 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -295 + - 340 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 1 + ttype: 2 + m_in: + obj: + - 1 + - inst: + lib_name: basic + cell_name: iopin + view_name: symbolr + xform: + - -320 + - 230 + - R0 + bbox: + - -381 + - 204 + - -310 + - 240 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -345 + - 230 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 1 + ttype: 2 + m_out: + obj: + - 1 + - inst: + lib_name: basic + cell_name: iopin + view_name: symbolr + xform: + - -200 + - 230 + - R0 + bbox: + - -261 + - 204 + - -190 + - 240 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -225 + - 230 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 2 + p_in: + obj: + - 1 + - inst: + lib_name: basic + cell_name: iopin + view_name: symbolr + xform: + - -320 + - 290 + - R0 + bbox: + - -381 + - 264 + - -310 + - 300 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -345 + - 290 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 0 + ttype: 2 + p_out: + obj: + - 1 + - inst: + lib_name: basic + cell_name: iopin + view_name: symbolr + xform: + - -200 + - 290 + - R0 + bbox: + - -261 + - 264 + - -190 + - 300 + connections: + {} + params: + {} + is_primitive: true + attr: + layer: 229 + purpose: 237 + net: "" + origin: + - -225 + - 290 + alignment: 7 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + attr_type: 0 + format: 1 + stype: 1 + ttype: 2 +shapes: + - + - 5 + - layer: 228 + purpose: 4294967295 + net: p_in + points: + - + - 50 + - 100 + - + - 50 + - 140 + - + - 7 + - layer: 228 + purpose: 237 + net: p_in + origin: + - 43 + - 136 + alignment: 8 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: p_in + - + - 5 + - layer: 228 + purpose: 4294967295 + net: p_out + points: + - + - 50 + - 200 + - + - 50 + - 240 + - + - 7 + - layer: 228 + purpose: 237 + net: p_out + origin: + - 43 + - 204 + alignment: 2 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: p_out + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VDD + points: + - + - 70 + - 160 + - + - 110 + - 160 + - + - 7 + - layer: 228 + purpose: 237 + net: VDD + origin: + - 74 + - 167 + alignment: 2 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 5 + - layer: 228 + purpose: 4294967295 + net: m_out + points: + - + - 50 + - -100 + - + - 50 + - -60 + - + - 7 + - layer: 228 + purpose: 237 + net: m_out + origin: + - 43 + - -64 + alignment: 8 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: m_out + - + - 5 + - layer: 228 + purpose: 4294967295 + net: m_in + points: + - + - 50 + - 0 + - + - 50 + - 40 + - + - 7 + - layer: 228 + purpose: 237 + net: m_in + origin: + - 43 + - 4 + alignment: 2 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: m_in + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VDD + points: + - + - 70 + - -40 + - + - 110 + - -40 + - + - 7 + - layer: 228 + purpose: 237 + net: VDD + origin: + - 74 + - -33 + alignment: 2 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VDD + points: + - + - 50 + - 290 + - + - 50 + - 330 + - + - 7 + - layer: 228 + purpose: 237 + net: VDD + origin: + - 43 + - 326 + alignment: 8 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VDD + points: + - + - 50 + - 390 + - + - 50 + - 430 + - + - 7 + - layer: 228 + purpose: 237 + net: VDD + origin: + - 43 + - 394 + alignment: 2 + orient: R90 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD + - + - 5 + - layer: 228 + purpose: 4294967295 + net: VDD + points: + - + - 70 + - 350 + - + - 110 + - 350 + - + - 7 + - layer: 228 + purpose: 237 + net: VDD + origin: + - 74 + - 357 + alignment: 2 + orient: R0 + font: 5 + height: 10 + overbar: false + visible: true + drafting: true + text: VDD +instances: + XRDUM: + lib_name: BAG_prim + cell_name: res_standard + view_name: symbol + xform: + - 10 + - 400 + - R0 + bbox: + - -82 + - 326 + - 180 + - 400 + connections: + BULK: VDD + MINUS: VDD + PLUS: VDD + params: + l: + - 3 + - 400n + w: + - 3 + - 400n + is_primitive: true + XRM: + lib_name: BAG_prim + cell_name: res_standard + view_name: symbol + xform: + - 10 + - 10 + - R0 + bbox: + - -82 + - -64 + - 180 + - 10 + connections: + BULK: VDD + MINUS: m_out + PLUS: m_in + params: + l: + - 3 + - 400n + w: + - 3 + - 400n + is_primitive: true + XRP: + lib_name: BAG_prim + cell_name: res_standard + view_name: symbol + xform: + - 10 + - 210 + - R0 + bbox: + - -82 + - 136 + - 180 + - 210 + connections: + BULK: VDD + MINUS: p_in + PLUS: p_out + params: + l: + - 3 + - 400n + w: + - 3 + - 400n + is_primitive: true +props: + connectivityLastUpdated: + - 0 + - 692 + lastSchematicExtraction: + - 4 + - time_val: 1676499343 + net#: + - 0 + - 0 + pin#: + - 0 + - 5 + schGeometryLastUpdated: + - 0 + - 692 + schGeometryVersion: + - 3 + - sch.ds.gm.1.4 + schXtrVersion: + - 3 + - sch.10.0 +app_defs: + _dbLastSavedCounter: + - 0 + - 692 + _dbvCvTimeStamp: + - 0 + - 692 + cdbRevision: + - 0 + - 227612 diff --git a/src/bag3_analog/schematic/res_diff.py b/src/bag3_analog/schematic/res_diff.py new file mode 100644 index 0000000..e4b377e --- /dev/null +++ b/src/bag3_analog/schematic/res_diff.py @@ -0,0 +1,106 @@ +# BSD 3-Clause License +# +# Copyright (c) 2018, Regents of the University of California +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# -*- coding: utf-8 -*- + +from typing import Mapping, Any, Optional + +import pkg_resources +from pathlib import Path + +from bag.design.module import Module +from bag.design.database import ModuleDB +from bag.util.immutable import Param + + +# noinspection PyPep8Naming +class bag3_analog__res_diff(Module): + """Module for library bag3_analog cell res_diff. + + Fill in high level description here. + """ + + yaml_file = pkg_resources.resource_filename(__name__, + str(Path('netlist_info', + 'res_diff.yaml'))) + + def __init__(self, database: ModuleDB, params: Param, **kwargs: Any) -> None: + Module.__init__(self, self.yaml_file, database, params, **kwargs) + + @classmethod + def get_params_info(cls) -> Mapping[str, str]: + """Returns a dictionary from parameter names to descriptions. + + Returns + ------- + param_info : Optional[Mapping[str, str]] + dictionary from parameter names to descriptions. + """ + return dict( + load_params='Parameters for load resistors', + dum_params='Optional Parameters for dummy resistors', + sub_type='"ntap" or "ptap"', + ) + + @classmethod + def get_default_param_values(cls) -> Mapping[str, Any]: + return dict(dum_params=None) + + def design(self, load_params: Mapping[str, Any], dum_params: Optional[Mapping[str, Any]], sub_type: str) -> None: + """To be overridden by subclasses to design this module. + + This method should fill in values for all parameters in + self.parameters. To design instances of this module, you can + call their design() method or any other ways you coded. + + To modify schematic structure, call: + + rename_pin() + delete_instance() + replace_instance_master() + reconnect_instance_terminal() + restore_instance() + array_instance() + """ + if sub_type == 'ntap': + sub_name = 'VDD' + else: + sub_name = 'VSS' + self.rename_pin('VDD', 'VSS') + + # design dummy resistors + if dum_params: + self.design_resistor('XRDUM', **dum_params, mid='dum', plus=sub_name, minus=sub_name, bulk=sub_name) + else: + self.remove_instance('XRDUM') + + # design core resistors + self.design_resistor('XRP', **load_params, mid='p', bulk=sub_name) + self.design_resistor('XRM', **load_params, mid='m', bulk=sub_name) From 00e132b70bbbc42b8cd423c7694fdb661414e446 Mon Sep 17 00:00:00 2001 From: Ayan Biswas Date: Wed, 22 Feb 2023 17:53:18 -0800 Subject: [PATCH 2/8] update drv_shunt_peak related generators for new MOSBase and TemplateBase properties --- src/bag3_analog/layout/drv_shunt_peak.py | 14 ++++-- src/bag3_analog/layout/gm_stage.py | 52 +++++++++++++++++---- src/bag3_analog/layout/res_diff.py | 10 ++-- src/bag3_analog/schematic/drv_shunt_peak.py | 3 ++ 4 files changed, 62 insertions(+), 17 deletions(-) diff --git a/src/bag3_analog/layout/drv_shunt_peak.py b/src/bag3_analog/layout/drv_shunt_peak.py index 247e9cb..1f6996f 100644 --- a/src/bag3_analog/layout/drv_shunt_peak.py +++ b/src/bag3_analog/layout/drv_shunt_peak.py @@ -15,7 +15,7 @@ from bag3_magnetics.layout.inductor.ind_diff_wrap import IndDiffWrap -from .gm_stage import GmStageGR +from .gm_stage import GmStageGR, GmStage from .res_diff import ResDiff from ..schematic.drv_shunt_peak import bag3_analog__drv_shunt_peak, LayMode @@ -50,7 +50,8 @@ def get_default_param_values(cls) -> Mapping[str, Any]: def draw_layout(self) -> None: # make masters gm_params: Mapping[str, Any] = self.params['gm_params'] - gm_master = self.new_template(GenericWrapper, params=dict(cls_name=GmStageGR.get_qualified_name(), + gm_cls = GmStageGR if self.has_guard_ring else GmStage + gm_master = self.new_template(GenericWrapper, params=dict(cls_name=gm_cls.get_qualified_name(), params=gm_params, export_hidden=True)) gm_bbox = gm_master.bound_box @@ -94,16 +95,21 @@ def draw_layout(self) -> None: for pin in ('v_inp', 'v_inm', 'v_tail_g', 'v_tail'): self.reexport(gm.get_port(pin)) - for pin in ('i_outp', 'i_outm', 'VSS', 'VDD'): + for pin in ('i_outp', 'i_outm', 'VSS'): # TODO: routing self.reexport(gm.get_port(pin), connect=True) + if gm.has_port('VDD'): + # TODO: routing + self.reexport(gm.get_port('VDD'), connect=True) # res_diff if gen_res: for term, net in [('p_in', 'i_outp'), ('m_in', 'i_outm'), ('p_out', 'ind_p'), ('m_out', 'ind_m')]: # TODO: routing self.reexport(res.get_port(term), net_name=net, connect=True) - self.reexport(res.get_port('VDD'), connect=True) + for pin in ('VDD', 'VSS'): + if res.has_port(pin): + self.reexport(res.get_port(pin), connect=True) # ind if gen_ind: diff --git a/src/bag3_analog/layout/gm_stage.py b/src/bag3_analog/layout/gm_stage.py index d11cd31..4cece91 100644 --- a/src/bag3_analog/layout/gm_stage.py +++ b/src/bag3_analog/layout/gm_stage.py @@ -59,9 +59,14 @@ def draw_layout(self) -> None: seg_tail = seg_dict['tail'] if seg_tail % 2: raise ValueError(f'This generator requires seg_tail={seg_tail} to be even.') - seg_tot = max(seg_tail, 2 * seg_gm) + if self.can_abut_mos: + seg_sep = 0 + else: + seg_sep = 4 + seg_tot = max(seg_tail, 2 * seg_gm + seg_sep) seg_tot2 = seg_tot // 2 seg_tail2 = seg_tail // 2 + seg_sep2 = seg_sep // 2 # --- Placement --- # if seg_tail2 % 2 == 1: @@ -77,8 +82,8 @@ def draw_layout(self) -> None: w_tail, th_tail = _row_info.width, _row_info.threshold # gm cells - gm_left_inst = self.add_mos(ridx_gm, seg_tot2, seg_gm, tile_idx=tile_logic, w=w, flip_lr=True) - gm_right_inst = self.add_mos(ridx_gm, seg_tot2, seg_gm, tile_idx=tile_logic, w=w) + gm_left_inst = self.add_mos(ridx_gm, seg_tot2 - seg_sep2, seg_gm, tile_idx=tile_logic, w=w, flip_lr=True) + gm_right_inst = self.add_mos(ridx_gm, seg_tot2 + seg_sep2, seg_gm, tile_idx=tile_logic, w=w) _row_info = _pinfo.get_row_place_info(ridx_gm).row_info w_gm, th_gm = _row_info.width, _row_info.threshold @@ -97,7 +102,10 @@ def draw_layout(self) -> None: # 1. source terminals of tail transistor go to supplies tap_tid = self.get_track_id(0, MOSWireType.DS, 'sup', tile_idx=tile_tap) - tap_hm = self.connect_to_tracks([tail_inst[sup_term], tap_conn], tap_tid) + if self.can_extend_ds_conn(g_side=True, threshold=th_tail): + tap_hm = self.connect_to_tracks([tail_inst[sup_term], tap_conn], tap_tid) + else: + raise NotImplementedError('Redo routing.') tap_xxm = self.connect_via_stack(tr_manager, tap_hm, xxm_layer, 'sup', alternate_o=True) self.add_pin('VSS', tap_xxm) @@ -105,9 +113,18 @@ def draw_layout(self) -> None: # improve connection tail_tid0 = self.get_track_id(ridx_tail, MOSWireType.DS, 'sig_hs', tile_idx=tile_logic) tail_tid1 = self.get_track_id(ridx_gm, MOSWireType.DS, 'sig_hs', wire_idx=-1, tile_idx=tile_logic) - tail0 = self.connect_to_tracks([gm_left_inst.s, gm_right_inst.s, tail_inst[share_term]], tail_tid0, - wire_lower=tail_inst[share_term].lower) - tail1 = self.connect_to_tracks([gm_left_inst.s, gm_right_inst.s, tail_inst[share_term]], tail_tid1) + tail1_vm = None + if self.can_extend_ds_conn(g_side=False, threshold=th_gm): + tail0 = self.connect_to_tracks([gm_left_inst.s, gm_right_inst.s, tail_inst[share_term]], tail_tid0, + wire_lower=tail_inst[share_term].lower) + tail1 = self.connect_to_tracks([gm_left_inst.s, gm_right_inst.s, tail_inst[share_term]], tail_tid1) + else: + tail0 = self.connect_to_tracks(tail_inst[share_term], tail_tid0, wire_lower=tail_inst[share_term].lower) + tail1 = self.connect_to_tracks([gm_left_inst.s, gm_right_inst.s], tail_tid1) + # connect on vm_layer + tail1_vm = self.connect_via_stack(self.tr_manager, tail1, vm_layer, 'sig_hs', + mlm_dict={vm_layer: MinLenMode.LOWER}) + self.connect_to_track_wires(tail0, tail1_vm) self.add_pin('v_tail', [tail0, tail1], hide=is_dum or not export_tail) # 3. gate terminals of tail transistor @@ -150,8 +167,25 @@ def draw_layout(self) -> None: min(l_coord, drain_left.upper), width=drain_tid.width) drain_right_hm = self.add_wires(hm_layer, drain_tid.base_index, max(r_coord, drain_right.lower), drain_right.upper, width=drain_tid.width) - drain_left_xxm = self.connect_via_stack(tr_manager, drain_left_hm, xxm_layer, 'sig_hs', 0, -1, mlm_drain) - drain_right_xxm = self.connect_via_stack(tr_manager, drain_right_hm, xxm_layer, 'sig_hs', 0, 1, mlm_drain) + if self.can_extend_ds_conn(g_side=False, threshold=th_gm): + drain_left_xxm = self.connect_via_stack(tr_manager, drain_left_hm, xxm_layer, 'sig_hs', 0, -1, mlm_drain) + drain_right_xxm = self.connect_via_stack(tr_manager, drain_right_hm, xxm_layer, 'sig_hs', 0, 1, mlm_drain) + else: + # don't collide with vm_layer for tail connection + coords_l, coords_r = [], [] + for _widx in range((tail1_vm.track_id.num - 1) // 2): + _tidx0 = self.tr_manager.get_next_track(vm_layer, tail1_vm[_widx].track_id.base_index, + 'sig_hs', 'sig_hs', 1) + coords_l.append(self.grid.track_to_coord(vm_layer, _tidx0)) + _tidx1 = self.tr_manager.get_next_track(vm_layer, tail1_vm[-1 - _widx].track_id.base_index, + 'sig_hs', 'sig_hs', -1) + coords_r.insert(0, self.grid.track_to_coord(vm_layer, _tidx1)) + drain_left_xm = self.connect_via_stack(tr_manager, drain_left_hm, xm_layer, 'sig_hs', 0, -1, mlm_drain, + coord_list_o_override=coords_l) + drain_right_xm = self.connect_via_stack(tr_manager, drain_right_hm, xm_layer, 'sig_hs', 0, 1, mlm_drain, + coord_list_o_override=coords_r) + drain_left_xxm = self.connect_via_stack(tr_manager, drain_left_xm, xxm_layer, 'sig_hs', 0, -1, mlm_drain) + drain_right_xxm = self.connect_via_stack(tr_manager, drain_right_xm, xxm_layer, 'sig_hs', 0, 1, mlm_drain) self.add_pin('i_outm', drain_left_xxm, hide=is_dum) self.add_pin('i_outp', drain_right_xxm, hide=is_dum) diff --git a/src/bag3_analog/layout/res_diff.py b/src/bag3_analog/layout/res_diff.py index 5c4fa34..fff1eb9 100644 --- a/src/bag3_analog/layout/res_diff.py +++ b/src/bag3_analog/layout/res_diff.py @@ -75,8 +75,8 @@ def draw_layout(self) -> None: # connect XRP and XRM from vm_layer to xxm_layer for _bot, _top, _suf in [(rp_bot, rp_top, 'p'), (rm_bot, rm_top, 'm')]: - _in = self.connect_stack(self.tr_manager, _bot, xxm_layer, 'sig') - _out = self.connect_stack(self.tr_manager, _top, xxm_layer, 'sig') + _in = self.connect_stack(self.tr_manager, _bot, xxm_layer, 'sig', xm_layer) + _out = self.connect_stack(self.tr_manager, _top, xxm_layer, 'sig', xm_layer) self.add_pin(f'{_suf}_in', _in) self.add_pin(f'{_suf}_out', _out) @@ -94,9 +94,11 @@ def draw_layout(self) -> None: sub_type=sub_type, ) - def connect_stack(self, tr_manager: TrackManager, warr: WireArray, top_layer: int, w_type: str = 'sig'): + def connect_stack(self, tr_manager: TrackManager, warr: WireArray, top_layer: int, w_type: str = 'sig', + mid_layer: int = -1): # this is different from connect_via_stack() as it does not connect the intermediate wires to reduce cap top_warr = [] for _warr in warr.warr_iter(): - top_warr.append(self.connect_via_stack(tr_manager, _warr, top_layer, w_type)) + _mid = self.connect_via_stack(tr_manager, _warr, mid_layer, w_type) + top_warr.append(self.connect_via_stack(tr_manager, _mid, top_layer, w_type)) return self.connect_wires(top_warr)[0] diff --git a/src/bag3_analog/schematic/drv_shunt_peak.py b/src/bag3_analog/schematic/drv_shunt_peak.py index 2dbb7d6..59c698d 100644 --- a/src/bag3_analog/schematic/drv_shunt_peak.py +++ b/src/bag3_analog/schematic/drv_shunt_peak.py @@ -110,6 +110,9 @@ def design(self, gm: Mapping[str, Any], res: Mapping[str, Any], ind: Mapping[str gen_res = lay_mode is LayMode.TOP or lay_mode is LayMode.EXT if gen_res: self.instances['XRES'].design(**res) + sub_type: str = res['sub_type'] + if sub_type == 'ptap': + self.reconnect_instance_terminal('XRES', 'VSS', 'VSS') else: self.remove_instance('XRES') remove_pins.extend(['VDD']) From cd30d37066d262f393c1009b5a2be07732edb504 Mon Sep 17 00:00:00 2001 From: Ayan Biswas Date: Wed, 22 Feb 2023 18:35:29 -0800 Subject: [PATCH 3/8] minor fix in drv_shunt_peak measurement --- src/bag3_analog/measurement/drv_shunt_peak.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bag3_analog/measurement/drv_shunt_peak.py b/src/bag3_analog/measurement/drv_shunt_peak.py index d7ad962..7df1038 100644 --- a/src/bag3_analog/measurement/drv_shunt_peak.py +++ b/src/bag3_analog/measurement/drv_shunt_peak.py @@ -268,7 +268,7 @@ def plot_results(results: Mapping[str, Any]) -> None: v_tail_g_swp: np.ndarray = results['v_tail_g'] fig, ax_list = plt.subplots(len(sim_envs), len(v_incm_swp) * len(v_tail_g_swp)) if not isinstance(ax_list, np.ndarray): - ax_list = np.array([ax_list]) + ax_list = np.array([ax_list]).reshape((1, 1)) for jdx, sim_env in enumerate(sim_envs): for kdx, v_incm in enumerate(v_incm_swp): From 8776272852e100408957daafff9036f81626c5d7 Mon Sep 17 00:00:00 2001 From: Ayan Biswas Date: Fri, 24 Feb 2023 11:02:15 -0800 Subject: [PATCH 4/8] drv_shunt_peak: updates in layout and measurement --- src/bag3_analog/layout/drv_shunt_peak.py | 4 ++-- src/bag3_analog/measurement/drv_shunt_peak.py | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/bag3_analog/layout/drv_shunt_peak.py b/src/bag3_analog/layout/drv_shunt_peak.py index 1f6996f..f5bceef 100644 --- a/src/bag3_analog/layout/drv_shunt_peak.py +++ b/src/bag3_analog/layout/drv_shunt_peak.py @@ -82,9 +82,9 @@ def draw_layout(self) -> None: y_res = y_gm res = self.add_instance(res_master, xform=Transform(dx=x_res, dy=y_res, mode=Orientation.MY), commit=gen_res) - x_ind = (w_tot - ind_sh_bbox.w) // 2 + x_ind = (w_tot + ind_sh_bbox.w) // 2 y_ind = y_res + res_bbox.h - ind = self.add_instance(ind_sh_master, xform=Transform(dx=x_ind, dy=y_ind), commit=gen_ind) + ind = self.add_instance(ind_sh_master, xform=Transform(dx=x_ind, dy=y_ind, mode=Orientation.MY), commit=gen_ind) h_tot = ind.bound_box.yh self.set_size_from_bound_box(ind_layer, BBox(0, 0, w_tot, h_tot), round_up=True) diff --git a/src/bag3_analog/measurement/drv_shunt_peak.py b/src/bag3_analog/measurement/drv_shunt_peak.py index 7df1038..37a9186 100644 --- a/src/bag3_analog/measurement/drv_shunt_peak.py +++ b/src/bag3_analog/measurement/drv_shunt_peak.py @@ -269,6 +269,8 @@ def plot_results(results: Mapping[str, Any]) -> None: fig, ax_list = plt.subplots(len(sim_envs), len(v_incm_swp) * len(v_tail_g_swp)) if not isinstance(ax_list, np.ndarray): ax_list = np.array([ax_list]).reshape((1, 1)) + if len(v_incm_swp) * len(v_tail_g_swp) == 1: + ax_list = ax_list.reshape(len(sim_envs), 1) for jdx, sim_env in enumerate(sim_envs): for kdx, v_incm in enumerate(v_incm_swp): From 7d89da89ac455feba8ff2b96c9c4089e7e7ab46d Mon Sep 17 00:00:00 2001 From: Ayan Biswas Date: Sat, 25 Feb 2023 19:33:24 -0800 Subject: [PATCH 5/8] top level routing in drv_shunt_peak --- src/bag3_analog/layout/drv_shunt_peak.py | 96 +++++++++++++++++++----- 1 file changed, 79 insertions(+), 17 deletions(-) diff --git a/src/bag3_analog/layout/drv_shunt_peak.py b/src/bag3_analog/layout/drv_shunt_peak.py index f5bceef..5250e5a 100644 --- a/src/bag3_analog/layout/drv_shunt_peak.py +++ b/src/bag3_analog/layout/drv_shunt_peak.py @@ -1,13 +1,11 @@ -from typing import Mapping, Any, Optional, Type, Sequence, Tuple, List, Union +from typing import Mapping, Any, Optional, Type, Union from bag.util.immutable import Param -from bag.util.math import HalfInt from bag.design.module import Module -from bag.layout.core import PyLayInstance from bag.layout.template import TemplateDB, TemplateBase -from bag.layout.routing.base import TrackID, TrackManager, WDictType, SpDictType, WireArray +from bag.layout.routing.base import TrackManager, WDictType, SpDictType -from pybag.enum import PinMode, RoundMode, Direction, MinLenMode, Orientation +from pybag.enum import RoundMode, MinLenMode, Orientation from pybag.core import Transform, BBox from xbase.layout.mos.top import GenericWrapper @@ -40,12 +38,13 @@ def get_params_info(cls) -> Mapping[str, str]: gm_params='Parameters for gm cells', res_params='Parameters for differential resistors', ind_sh_params='Parameters for shunt differential inductor', + ind_v_sp='Vertical spacing between resistor and inductor', lay_mode='Layout mode, TOP by default.', ) @classmethod def get_default_param_values(cls) -> Mapping[str, Any]: - return dict(lay_mode=LayMode.TOP) + return dict(lay_mode=LayMode.TOP, ind_v_sp=0) def draw_layout(self) -> None: # make masters @@ -82,8 +81,9 @@ def draw_layout(self) -> None: y_res = y_gm res = self.add_instance(res_master, xform=Transform(dx=x_res, dy=y_res, mode=Orientation.MY), commit=gen_res) + ind_v_sp: int = self.params['ind_v_sp'] x_ind = (w_tot + ind_sh_bbox.w) // 2 - y_ind = y_res + res_bbox.h + y_ind = y_res + res_bbox.h + ind_v_sp ind = self.add_instance(ind_sh_master, xform=Transform(dx=x_ind, dy=y_ind, mode=Orientation.MY), commit=gen_ind) h_tot = ind.bound_box.yh @@ -95,30 +95,92 @@ def draw_layout(self) -> None: for pin in ('v_inp', 'v_inm', 'v_tail_g', 'v_tail'): self.reexport(gm.get_port(pin)) - for pin in ('i_outp', 'i_outm', 'VSS'): - # TODO: routing - self.reexport(gm.get_port(pin), connect=True) + self.reexport(gm.get_port('VSS'), connect=True) if gm.has_port('VDD'): - # TODO: routing + # TODO: routing supply self.reexport(gm.get_port('VDD'), connect=True) # res_diff if gen_res: - for term, net in [('p_in', 'i_outp'), ('m_in', 'i_outm'), ('p_out', 'ind_p'), ('m_out', 'ind_m')]: - # TODO: routing - self.reexport(res.get_port(term), net_name=net, connect=True) for pin in ('VDD', 'VSS'): if res.has_port(pin): self.reexport(res.get_port(pin), connect=True) + # routing from gm cell to res_diff + i_outp = gm.get_pin('i_outp') + i_outm = gm.get_pin('i_outm') + gm_top_layer = i_outp.layer_id + + p_in = res.get_pin('p_in') + p_out = res.get_pin('p_out') + m_in = res.get_pin('m_in') + m_out = res.get_pin('m_out') + + if gm_top_layer < p_in.layer_id: + raise NotImplementedError + elif gm_top_layer > p_in.layer_id: + _tidx0 = self.grid.coord_to_track(gm_top_layer, p_in.bound_box.ym, RoundMode.NEAREST) + _tidx1 = self.grid.coord_to_track(gm_top_layer, p_out.bound_box.ym, RoundMode.NEAREST) + if self._tr_manager.get_next_track(gm_top_layer, _tidx0, 'sig_hs', 'sig_hs', 2) > _tidx1: + # compute new _tidx0 and _tidx1 + _, _locs = self._tr_manager.place_wires(gm_top_layer, ['sig_hs', 'sig_hs', 'sig_hs'], + center_coord=(p_in.bound_box.ym + p_out.bound_box.ym) // 2) + _tidx0, _tidx1 = _locs[0], _locs[-1] + alternate_o = True + else: + alternate_o = False + _coord0 = self.grid.track_to_coord(gm_top_layer, _tidx0) + _coord1 = self.grid.track_to_coord(gm_top_layer, _tidx1) + p_0, p_1 = p_in.lower, p_in.upper + m_0, m_1 = m_in.lower, m_in.upper + p_in = self.connect_via_stack(self._tr_manager, p_in, gm_top_layer, 'sig_hs', + coord_list_p_override=[_coord0]) + p_in = self.extend_wires(p_in, lower=p_0, upper=p_1)[0] + m_in = self.connect_via_stack(self._tr_manager, m_in, gm_top_layer, 'sig_hs', + coord_list_p_override=[_coord0]) + m_in = self.extend_wires(m_in, lower=m_0, upper=m_1)[0] + p_out = self.connect_via_stack(self._tr_manager, p_out, gm_top_layer, 'sig_hs', + coord_list_p_override=[_coord1], alternate_o=alternate_o) + p_out = self.extend_wires(p_out, lower=p_0, upper=p_1)[0] + m_out = self.connect_via_stack(self._tr_manager, m_out, gm_top_layer, 'sig_hs', + coord_list_p_override=[_coord1], alternate_o=alternate_o) + m_out = self.extend_wires(m_out, lower=m_0, upper=m_1)[0] + + # now i_outp and p_in are on the same layer + _conn_layer = gm_top_layer + 1 + p_in = self.connect_via_stack(self._tr_manager, p_in, _conn_layer, 'sig_hs', + mlm_dict={_conn_layer: MinLenMode.LOWER}) + m_in = self.connect_via_stack(self._tr_manager, m_in, _conn_layer, 'sig_hs', + mlm_dict={_conn_layer: MinLenMode.LOWER}) + i_outp = self.connect_to_track_wires(i_outp, p_in) + i_outm = self.connect_to_track_wires(i_outm, m_in) + if gen_gm and gen_res: + self.add_pin('i_outp', i_outp) + self.add_pin('i_outm', i_outm) + + # routing from res_diff to inductors + p_out = self.connect_via_stack(self._tr_manager, p_out, _conn_layer + 1, 'sig_hs', + mlm_dict={_conn_layer: MinLenMode.UPPER}) + m_out = self.connect_via_stack(self._tr_manager, m_out, _conn_layer + 1, 'sig_hs', + mlm_dict={_conn_layer: MinLenMode.UPPER}) + ind_p: BBox = ind.get_pin('P1') + ind_m: BBox = ind.get_pin('P3') + ind_lp = self.grid.tech_info.get_lay_purp_list(ind_layer)[0] + if _conn_layer + 1 == ind_layer: + self.add_rect(ind_lp, BBox(ind_p.xl, p_out.bound_box.yl, ind_p.xh, ind_p.yh)) + self.add_rect(ind_lp, BBox(ind_m.xl, m_out.bound_box.yl, ind_m.xh, ind_m.yh)) + else: + raise NotImplementedError + # ind + if gen_res: + self.reexport(ind.get_port('P1'), net_name='ind_p') + self.reexport(ind.get_port('P3'), net_name='ind_m') if gen_ind: if lay_mode is LayMode.TOP: for pin in ('P13_R', 'P2_R', 'P2'): - # TODO: routing + # TODO: routing supplies self.reexport(ind.get_port(pin), net_name='VDD', connect=True) - self.reexport(ind.get_port('P1'), net_name='ind_p', connect=True) - self.reexport(ind.get_port('P3'), net_name='ind_m', connect=True) else: for pin in ('P13_R', 'P2_R', 'P2', 'P1', 'P3'): self.reexport(ind.get_port(pin)) From f26a786b1e6d35540e667ef909ea9c35dd2e7f13 Mon Sep 17 00:00:00 2001 From: Ayan Biswas Date: Sat, 25 Feb 2023 19:53:54 -0800 Subject: [PATCH 6/8] update drv_shunt_peak top level routing --- src/bag3_analog/layout/drv_shunt_peak.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/bag3_analog/layout/drv_shunt_peak.py b/src/bag3_analog/layout/drv_shunt_peak.py index 5250e5a..fd8b96a 100644 --- a/src/bag3_analog/layout/drv_shunt_peak.py +++ b/src/bag3_analog/layout/drv_shunt_peak.py @@ -134,16 +134,16 @@ def draw_layout(self) -> None: p_0, p_1 = p_in.lower, p_in.upper m_0, m_1 = m_in.lower, m_in.upper p_in = self.connect_via_stack(self._tr_manager, p_in, gm_top_layer, 'sig_hs', - coord_list_p_override=[_coord0]) + coord_list_p_override=[_coord0], alignment_o=1) p_in = self.extend_wires(p_in, lower=p_0, upper=p_1)[0] m_in = self.connect_via_stack(self._tr_manager, m_in, gm_top_layer, 'sig_hs', - coord_list_p_override=[_coord0]) + coord_list_p_override=[_coord0], alignment_o=-1) m_in = self.extend_wires(m_in, lower=m_0, upper=m_1)[0] p_out = self.connect_via_stack(self._tr_manager, p_out, gm_top_layer, 'sig_hs', - coord_list_p_override=[_coord1], alternate_o=alternate_o) + coord_list_p_override=[_coord1], alternate_o=alternate_o, alignment_o=1) p_out = self.extend_wires(p_out, lower=p_0, upper=p_1)[0] m_out = self.connect_via_stack(self._tr_manager, m_out, gm_top_layer, 'sig_hs', - coord_list_p_override=[_coord1], alternate_o=alternate_o) + coord_list_p_override=[_coord1], alternate_o=alternate_o, alignment_o=-1) m_out = self.extend_wires(m_out, lower=m_0, upper=m_1)[0] # now i_outp and p_in are on the same layer @@ -159,10 +159,12 @@ def draw_layout(self) -> None: self.add_pin('i_outm', i_outm) # routing from res_diff to inductors + _tidx = self.grid.coord_to_track(_conn_layer + 1, p_out.bound_box.ym, RoundMode.GREATER) + _coord = self.grid.track_to_coord(_conn_layer + 1, _tidx) p_out = self.connect_via_stack(self._tr_manager, p_out, _conn_layer + 1, 'sig_hs', - mlm_dict={_conn_layer: MinLenMode.UPPER}) + coord_list_p_override=[_coord], mlm_dict={_conn_layer: MinLenMode.UPPER}) m_out = self.connect_via_stack(self._tr_manager, m_out, _conn_layer + 1, 'sig_hs', - mlm_dict={_conn_layer: MinLenMode.UPPER}) + coord_list_p_override=[_coord], mlm_dict={_conn_layer: MinLenMode.UPPER}) ind_p: BBox = ind.get_pin('P1') ind_m: BBox = ind.get_pin('P3') ind_lp = self.grid.tech_info.get_lay_purp_list(ind_layer)[0] From 55f8a7e9a3b73d8ac8ab87d8a263fbc3c166d568 Mon Sep 17 00:00:00 2001 From: Ayan Biswas Date: Wed, 12 Apr 2023 23:08:30 -0700 Subject: [PATCH 7/8] minor update in drv_shunt_peak measurement --- src/bag3_analog/measurement/drv_shunt_peak.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/bag3_analog/measurement/drv_shunt_peak.py b/src/bag3_analog/measurement/drv_shunt_peak.py index 37a9186..895fcf6 100644 --- a/src/bag3_analog/measurement/drv_shunt_peak.py +++ b/src/bag3_analog/measurement/drv_shunt_peak.py @@ -176,7 +176,9 @@ async def async_measure_performance(self, name: str, sim_dir: Path, sim_db: Simu plot_results['eye'][jdx].append(eye_res) idx += 1 - # self.plot_results(plot_results) + plot_eye: bool = self.specs.get('plot_eye', False) + if plot_eye: + self.plot_results(plot_results) return results async def async_meas_pvt_case(self, name: str, sim_dir: Path, sim_db: SimulationDB, dut: Optional[DesignInstance], @@ -279,7 +281,7 @@ def plot_results(results: Mapping[str, Any]) -> None: ax = ax_list[jdx, eidx] eye_results: EyeResults = results['eye'][jdx][eidx] eye_results.plot(ax) - ax.set_title(f'{sim_env}; v_incm={v_incm}; v_tail_g={v_tail_g}') + ax.set_title(f'{sim_env}; v_incm={v_incm} V; v_tail_g={v_tail_g} V') plt.tight_layout() plt.show() From 49042ca316e280c8c50d3a1c89434a9a7b4c445f Mon Sep 17 00:00:00 2001 From: sehuang Date: Tue, 9 May 2023 12:36:00 -0700 Subject: [PATCH 8/8] add dummy assertion and a TODO --- src/bag3_analog/layout/res/ladder.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bag3_analog/layout/res/ladder.py b/src/bag3_analog/layout/res/ladder.py index a532295..0528fc1 100644 --- a/src/bag3_analog/layout/res/ladder.py +++ b/src/bag3_analog/layout/res/ladder.py @@ -289,6 +289,11 @@ def _connect_ladder(self, nx_dum = self.params['nx_dum'] ny_dum = self.params['ny_dum'] + #TODO: Add support for clean no-dummy generation. For now these assertions + # are here to ensure clean ResLadder generation + + assert(nx_dum > 0 and ny_dum > 0, "ResLadder generation without dummies is not currently supported.") + nx_core = nx - 2 * nx_dum ny_core = ny - 2 * ny_dum