Created
August 24, 2022 16:27
-
-
Save mithro/f00b3f5effe576a0493e2e221420df18 to your computer and use it in GitHub Desktop.
VerilogA model for varactor on SkyWater 130nm (SKY130)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// VerilogA model for varactor | |
`include "discipline.h" | |
`include "constants.h" | |
module xcnwvc_va(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 | |
// VerilogA model for varactor | |
`include "discipline.h" | |
`include "constants.h" | |
module xcnwvc2_va(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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment