diff --git a/cells/cap_var_hvt/sky130_fd_pr__cap_var_hvt.model.va b/cells/cap_var_hvt/sky130_fd_pr__cap_var_hvt.model.va new file mode 100644 index 00000000..15cb3a98 --- /dev/null +++ b/cells/cap_var_hvt/sky130_fd_pr__cap_var_hvt.model.va @@ -0,0 +1,159 @@ +// Copyright 2020 The SkyWater PDK Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +`include "discipline.h" +`include "constants.h" + +// VerilogA model for varactor +module sky130_fd_pr__cap_var_hvt(poly, nwell, sub); + +inout nwell; +electrical nwell; + +inout poly; +electrical poly; + +inout sub; +electrical sub; + +parameter real w = 1; +parameter real l = 1; +parameter real vm = 1; //vm passed from subckt, if higher level subckt used will not receive this mult factor. +parameter real cnwvc2_tox = 41.7642; +parameter real cnwvc2_cdepmult=1; +parameter real cnwvc2_cintmult=1; +parameter real cnwvc2_vt1=0.2; +parameter real cnwvc2_vt2=0.33; +parameter real cnwvc2_vtr=0.14; +parameter real cnwvc2_dwc=0.0; +parameter real cnwvc2_dlc=0.0; +parameter real cnwvc2_dld=0.0; +parameter real rp1 = 48.2; +parameter real rcp1 = 150; +parameter real rnw = 1800; +parameter real rcn = 182; +parameter real cm0=5.828e-16*cnwvc2_cintmult; +parameter real cm1=4.596e-16; +parameter real cm2=1.614e-16; +parameter real cm3=1.541e-15*cnwvc2_cdepmult; +parameter real cx0=6.778e-16; +parameter real cx1=6.461e-16; +parameter real cx2=1.517e-16; +parameter real cx3=8.854e-14*3.9/cnwvc2_tox; +parameter real slope_0=1.808e-17; +parameter real slope_0_tc1=7.2181e-20; +parameter real slope_0_tc2=-1.9745e-21; +parameter real slope_w=-3.169e-17; +parameter real slope_w_tc1=-1.4465e-19; +parameter real slope_w_tc2=3.5187e-21; +parameter real slope_l=-7.435e-17; +parameter real slope_l_tc1=-4.4474e-19; +parameter real slope_l_tc2=7.3824e-21; +parameter real slope_wl=2.509e-16; +parameter real slope_wl_tc1=-1.0793e-18; +parameter real slope_wl_tc2=-2.2625e-20; + +real cnwvc_ldiff; +real wc,lc,wd,ld,ldd,dwr,dwp,dlr,wl,wlwdiff; +real cnwvc_slope1,cnwvc_slope2; +real cmin,cmax,cval1,cval2; +real con_sp; +real n_pocon,n_con; +real cnwvc_n1,cnwvc_n2; +real cPolySub,cNwellSub; +real cnwvc_k; +real cnwvc_a,cnwvc_b1,cnwvc_c; +real acon,apoly,apolyc; +real anwell,bnwell,cnwell; +real c0,c1,q; +real tc1,tc2; +real rgvalue,rg_nominal; +real v; +real treference; +real temp_celcius; +real cmin_slope_0; +real cmin_slope_w; +real cmin_slope_l; +real cmin_slope_wl; +real cmin_slope; + +// Internal nodes +electrical v1 ; + +analog begin + treference=30.0; + cnwvc_ldiff=0.15; + wc=1*w; + lc=1*l; + wd=wc+2*cnwvc2_dwc; + ld=lc+2*cnwvc2_dlc; + ldd=0.015+2*cnwvc2_dld; + dwr=0.0; + dwp=0.0; + dlr=0.03; + wl=(wd-2*dwr)/(ld-2*dlr); + wlwdiff=((0.5*(ld-2*dlr))+cnwvc_ldiff)/(2*(wd-2*dwr)); + cnwvc_slope1=0.15; + cnwvc_slope2=0.35; + cmin=cm0+cm1*ld+cm2*wd+cm3*wd*(ld-ldd)+cx3*wd*ldd; + cmax=cx0+cx1*ld+cx2*wd+cx3*wd*ld; + cval1=0.5*(cmax+cmin); + cval2=0.5*(cmax-cmin); + con_sp=0.17; + cnwvc_k=12; + cnwvc_n1=0.2; + cnwvc_n2=0.35; + apoly=1.1; + apolyc=1.1; + acon=1; + anwell=1; + bnwell=0.5; + cnwell=0.3; + n_pocon=max((l-0.14)/(2*con_sp),1); //numbers of poly contact + n_con=(w-2*0.06+con_sp)/(2*con_sp); + cPolySub=0.15e-15; + cNwellSub=0.15e-15; + + cnwvc_a=apoly*rp1*wl/cnwvc_k+apolyc*rcp1/n_pocon+acon*rcn/n_con+anwell*rnw*wlwdiff; + cnwvc_b1=bnwell*rnw*cnwvc_ldiff/(2*(wd-2*dwr)); + cnwvc_c=cnwell*rnw*cnwvc_ldiff/(2*(wd-2*dwp)); + + v=V(v1,nwell); + + tc1=9.611e-4; + tc2=5.523e-6; + + temp_celcius= $temperature-273.15; //$temperature is in Kelvin + + cmin_slope_0 = slope_0+(temp_celcius-treference)*slope_0_tc1+(temp_celcius-treference)*(temp_celcius-treference)*slope_0_tc2; + cmin_slope_w = slope_w+(temp_celcius-treference)*slope_w_tc1+(temp_celcius-treference)*(temp_celcius-treference)*slope_w_tc2; + cmin_slope_l = slope_l+(temp_celcius-treference)*slope_l_tc1+(temp_celcius-treference)*(temp_celcius-treference)*slope_l_tc2; + cmin_slope_wl = slope_wl+(temp_celcius-treference)*slope_wl_tc1+(temp_celcius-treference)*(temp_celcius-treference)*slope_wl_tc2; + cmin_slope = cmin_slope_0+cmin_slope_w*wd+cmin_slope_l*ld+cmin_slope_wl*wd*ld; + + rg_nominal =(cnwvc_a+cnwvc_b1*(0.5*tanh((v-cnwvc2_vtr)/cnwvc_n1)+0.5)+20*cnwvc_c*(0.5*tanh((v-cnwvc2_vtr)/cnwvc_n1)+0.5)*exp(-abs((v-cnwvc2_vtr)/cnwvc_n2))); + rgvalue = rg_nominal*(1+tc1*(temp_celcius-treference)+tc2*(temp_celcius-treference)*(temp_celcius-treference)); + + q = cmin_slope*min(v+0.8,0)*min(v+0.8,0)+cval1*v + (cval2/1.9) * (cnwvc_slope1*ln(0.5*((limexp((v-cnwvc2_vt1)/cnwvc_slope1))+limexp(-(v-cnwvc2_vt1)/cnwvc_slope1))) + 0.9*cnwvc_slope2*ln(0.5*((limexp((v-cnwvc2_vt2)/cnwvc_slope2))+limexp(-(v-cnwvc2_vt2)/cnwvc_slope2)))); + I(v1,nwell) <+ vm*ddt(q); + + V(poly,v1) <+ I(poly,v1)*rgvalue/vm; + V(poly,v1) <+ white_noise( 4*1.38e-23*$temperature*rgvalue/vm, "rg_noise"); + + //c1 and c2 are the tuning capacitors + I(poly,sub)<+ vm*cPolySub*ddt(V(poly,sub)); // c1 poly sub c=0.15e-15 + I(nwell,sub)<+ vm*cNwellSub*ddt(V(nwell,sub)); // c2 nwell sub c=0.15e-15 +end + +endmodule diff --git a/cells/cap_var_lvt/sky130_fd_pr__cap_var_lvt.model.va b/cells/cap_var_lvt/sky130_fd_pr__cap_var_lvt.model.va new file mode 100644 index 00000000..4878ca2a --- /dev/null +++ b/cells/cap_var_lvt/sky130_fd_pr__cap_var_lvt.model.va @@ -0,0 +1,135 @@ +// Copyright 2020 The SkyWater PDK Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +`include "discipline.h" +`include "constants.h" + +// VerilogA model for varactor +module sky130_fd_pr__cap_var_lvt(poly, nwell, sub); + +inout nwell; +electrical nwell; + +inout poly; +electrical poly; + +inout sub; +electrical sub; + +parameter real w = 1; +parameter real l = 1; +parameter real vm = 1; //vm passed from subckt, if higher level subckt used will not receive this mult factor. +parameter real cnwvc_tox = 41.6503; +parameter real cnwvc_cdepmult=1; +parameter real cnwvc_cintmult=1; +parameter real cnwvc_vt1=0.3333; +parameter real cnwvc_vt2=0.2380952; +parameter real cnwvc_vtr=0.16; +parameter real cnwvc_dwc=0.0; +parameter real cnwvc_dlc=0.0; +parameter real cnwvc_dld=0.0; +parameter real rp1 = 48.2; +parameter real rcp1 = 150; +parameter real rnw = 1800; +parameter real rcn = 182; +parameter real cm0=5.571e-16*cnwvc_cintmult; +parameter real cm1=4.775e-16; +parameter real cm2=2.019e-16; +parameter real cm3=6.529e-16*cnwvc_cdepmult; +parameter real cx0=6.261e-16; +parameter real cx1=5.75e-16; +parameter real cx2=1.712e-16; +parameter real cx3=8.854e-14*3.9/cnwvc_tox; + +real cnwvc_ldiff; +real wc,lc,wd,ld,ldd,dwr,dwp,dlr,wl,wlwdiff; +real cnwvc_slope1,cnwvc_slope2; +real cmin,cmax,cval1,cval2; +real con_sp; +real n_pocon,n_con; +real cnwvc_n1,cnwvc_n2; +real cPolySub,cNwellSub; +real cnwvc_k; +real cnwvc_a,cnwvc_b1,cnwvc_c; +real acon,apoly,apolyc; +real anwell,bnwell,cnwell; +real c0,c1,q; +real tc1,tc2; +real rgvalue,rg_nominal; +real v; +real treference; +real temp_celcius; + +// Internal nodes +electrical v1; + +analog begin + treference=30.0; + cnwvc_ldiff=0.15; + wc=1*w; + lc=1*l; + wd=wc+2*cnwvc_dwc; + ld=lc+2*cnwvc_dlc; + ldd=0.018+2*cnwvc_dld; + dwr=-0.02; + dwp=-0.5; + dlr=0.02; + wl=(wd-2*dwr)/(ld-2*dlr); + wlwdiff=((0.5*(ld-2*dlr))+cnwvc_ldiff)/(2*(wd-2*dwr)); + cnwvc_slope1=0.21875; + cnwvc_slope2=0.125; + cmin=cm0+cm1*ld+cm2*wd+cm3*wd*(ld-ldd)+cx3*wd*ldd; + cmax=cx0+cx1*ld+cx2*wd+cx3*wd*ld; + cval1=0.5*(cmax+cmin); + cval2=0.5*(cmax-cmin); + con_sp=0.17; + cnwvc_k=12; + cnwvc_n1=0.1; + cnwvc_n2=0.28; + apoly=1.15; + apolyc=1; + acon=1; + anwell=1; + bnwell=0.6; + cnwell=2; + n_pocon=max((l-0.14)/(2*con_sp),1); //numbers of poly contact + n_con=(w-2*0.06+con_sp)/(2*con_sp); + cPolySub=0.15e-15; + cNwellSub=0.15e-15; + + cnwvc_a=apoly*rp1*wl/cnwvc_k+apolyc*rcp1/n_pocon+acon*rcn/n_con+anwell*rnw*wlwdiff; + cnwvc_b1=bnwell*rnw*wlwdiff; + cnwvc_c=cnwell*rnw*((0.5*(ld-2*dlr))+cnwvc_ldiff)/(2*(wd-2*dwp)); + + v=V(v1,nwell); + + tc1=3e-3; + tc2=0; + + temp_celcius= $temperature-273.15; //$temperature is in Kelvin + rg_nominal =(cnwvc_a+cnwvc_b1*(0.5*tanh((v-cnwvc_vtr)/cnwvc_n1)+0.5)+20*cnwvc_c*(0.5*tanh((v-cnwvc_vtr)/cnwvc_n1)+0.5)*exp(-abs((v-cnwvc_vtr)/cnwvc_n2))); + rgvalue = rg_nominal*(1+tc1*(temp_celcius-treference)+tc2*(temp_celcius-treference)*(temp_celcius-treference)); + + q = cval1*v + (cval2/1.9) * (cnwvc_slope1*ln(0.5*((limexp((v-cnwvc_vt1)/cnwvc_slope1))+limexp(-(v-cnwvc_vt1)/cnwvc_slope1))) + 0.9*cnwvc_slope2*ln(0.5*((limexp((v-cnwvc_vt2)/cnwvc_slope2))+limexp(-(v-cnwvc_vt2)/cnwvc_slope2)))); + I(v1,nwell) <+ vm*ddt(q); + + V(poly,v1) <+ I(poly,v1)*rgvalue/vm; + V(poly,v1) <+ white_noise( 4*1.38e-23*$temperature*rgvalue/vm, "rg_noise"); + + //c1 and c2 are the tuning capacitors + I(poly,sub)<+ vm*cPolySub*ddt(V(poly,sub)); // c1 poly sub c=0.15e-15 + I(nwell,sub)<+ vm*cNwellSub*ddt(V(nwell,sub)); // c2 nwell sub c=0.15e-15 +end + +endmodule