Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial attempt at adding the varactor Verilog-A models. #4

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 159 additions & 0 deletions cells/cap_var_hvt/sky130_fd_pr__cap_var_hvt.model.va
Original file line number Diff line number Diff line change
@@ -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
135 changes: 135 additions & 0 deletions cells/cap_var_lvt/sky130_fd_pr__cap_var_lvt.model.va
Original file line number Diff line number Diff line change
@@ -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