committed by
rlar
27 changed files with 26467 additions and 0 deletions
-
33src/spicelib/devices/bsim4v7/B4TERMS_OF_USE
-
39src/spicelib/devices/bsim4v7/Makefile.am
-
1057src/spicelib/devices/bsim4v7/b4v7.c
-
673src/spicelib/devices/bsim4v7/b4v7acld.c
-
405src/spicelib/devices/bsim4v7/b4v7ask.c
-
899src/spicelib/devices/bsim4v7/b4v7check.c
-
200src/spicelib/devices/bsim4v7/b4v7cvtest.c
-
43src/spicelib/devices/bsim4v7/b4v7del.c
-
63src/spicelib/devices/bsim4v7/b4v7dest.c
-
395src/spicelib/devices/bsim4v7/b4v7geo.c
-
46src/spicelib/devices/bsim4v7/b4v7getic.c
-
5545src/spicelib/devices/bsim4v7/b4v7ld.c
-
2723src/spicelib/devices/bsim4v7/b4v7mask.c
-
48src/spicelib/devices/bsim4v7/b4v7mdel.c
-
3649src/spicelib/devices/bsim4v7/b4v7mpar.c
-
648src/spicelib/devices/bsim4v7/b4v7noi.c
-
204src/spicelib/devices/bsim4v7/b4v7par.c
-
759src/spicelib/devices/bsim4v7/b4v7pzld.c
-
2640src/spicelib/devices/bsim4v7/b4v7set.c
-
110src/spicelib/devices/bsim4v7/b4v7soachk.c
-
2312src/spicelib/devices/bsim4v7/b4v7temp.c
-
60src/spicelib/devices/bsim4v7/b4v7trunc.c
-
3775src/spicelib/devices/bsim4v7/bsim4v7def.h
-
31src/spicelib/devices/bsim4v7/bsim4v7ext.h
-
84src/spicelib/devices/bsim4v7/bsim4v7init.c
-
13src/spicelib/devices/bsim4v7/bsim4v7init.h
-
13src/spicelib/devices/bsim4v7/bsim4v7itf.h
@ -0,0 +1,33 @@ |
|||
|
|||
The terms under which the software is provided are as the following. |
|||
|
|||
Software is distributed as is, completely without warranty or service |
|||
support. The University of California and its employees are not liable |
|||
for the condition or performance of the software. |
|||
|
|||
The University owns the copyright but shall not be liable for any |
|||
infringement of copyright or other proprietary rights brought by third |
|||
parties against the users of the software. |
|||
|
|||
The University of California hereby disclaims all implied warranties. |
|||
|
|||
The University of California grants the users the right to modify, copy, |
|||
and redistribute the software and documentation, both within the user's |
|||
organization and externally, subject to the following restrictions: |
|||
|
|||
1. The users agree not to charge for the University of California code |
|||
itself but may charge for additions, extensions, or support. |
|||
|
|||
2. In any product based on the software, the users agree to acknowledge |
|||
the UC Berkeley BSIM Research Group that developed the software. This |
|||
acknowledgment shall appear in the product documentation. |
|||
|
|||
3. The users agree to obey all U.S. Government restrictions governing |
|||
redistribution or export of the software. |
|||
|
|||
4. The users agree to reproduce any copyright notice which appears on |
|||
the software on any copy or modification of such made available |
|||
to others. |
|||
|
|||
Chenming Hu, and Weidong Liu |
|||
Mar. 2000 |
|||
@ -0,0 +1,39 @@ |
|||
## Process this file with automake to produce Makefile.in
|
|||
|
|||
noinst_LTLIBRARIES = libbsim4.la |
|||
|
|||
libbsim4_la_SOURCES = \
|
|||
b4.c \
|
|||
b4acld.c \
|
|||
b4ask.c \
|
|||
b4check.c \
|
|||
b4cvtest.c \
|
|||
b4del.c \
|
|||
b4dest.c \
|
|||
b4geo.c \
|
|||
b4getic.c \
|
|||
b4ld.c \
|
|||
b4mask.c \
|
|||
b4mdel.c \
|
|||
b4mpar.c \
|
|||
b4noi.c \
|
|||
b4par.c \
|
|||
b4pzld.c \
|
|||
b4set.c \
|
|||
b4soachk.c \
|
|||
b4temp.c \
|
|||
b4trunc.c \
|
|||
bsim4def.h \
|
|||
bsim4ext.h \
|
|||
bsim4init.c \
|
|||
bsim4init.h \
|
|||
bsim4itf.h |
|||
|
|||
|
|||
|
|||
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include |
|||
AM_CFLAGS = $(STATIC) |
|||
|
|||
MAINTAINERCLEANFILES = Makefile.in |
|||
|
|||
EXTRA_DIST = B4TERMS_OF_USE |
|||
1057
src/spicelib/devices/bsim4v7/b4v7.c
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,673 @@ |
|||
/**** BSIM4.7.0 Released by Darsen Lu 04/08/2011 ****/ |
|||
|
|||
/********** |
|||
* Copyright 2006 Regents of the University of California. All rights reserved. |
|||
* File: b4acld.c of BSIM4.7.0. |
|||
* Author: 2000 Weidong Liu |
|||
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu. |
|||
* Authors: 2006- Mohan Dunga, Ali Niknejad, Chenming Hu |
|||
* Authors: 2007- Mohan Dunga, Wenwei Yang, Ali Niknejad, Chenming Hu |
|||
* Project Director: Prof. Chenming Hu. |
|||
* Modified by Xuemei Xi, 10/05/2001. |
|||
**********/ |
|||
|
|||
#include "ngspice/ngspice.h" |
|||
#include "ngspice/cktdefs.h" |
|||
#include "bsim4def.h" |
|||
#include "ngspice/sperror.h" |
|||
#include "ngspice/suffix.h" |
|||
|
|||
|
|||
int |
|||
BSIM4acLoad( |
|||
GENmodel *inModel, |
|||
CKTcircuit *ckt) |
|||
{ |
|||
BSIM4model *model = (BSIM4model*)inModel; |
|||
BSIM4instance *here; |
|||
|
|||
double gjbd, gjbs, geltd, gcrg, gcrgg, gcrgd, gcrgs, gcrgb; |
|||
double xcbgb, xcbdb, xcbsb, xcbbb; |
|||
double xcggbr, xcgdbr, xcgsbr, xcgbbr, xcggbi, xcgdbi, xcgsbi, xcgbbi; |
|||
double Cggr, Cgdr, Cgsr, Cgbr, Cggi, Cgdi, Cgsi, Cgbi; |
|||
double xcddbr, xcdgbr, xcdsbr, xcdbbr, xcsdbr, xcsgbr, xcssbr, xcsbbr; |
|||
double xcddbi, xcdgbi, xcdsbi, xcdbbi, xcsdbi, xcsgbi, xcssbi, xcsbbi; |
|||
double xcdbdb, xcsbsb=0.0, xcgmgmb=0.0, xcgmdb=0.0, xcgmsb=0.0, xcdgmb, xcsgmb; |
|||
double xcgmbb=0.0, xcbgmb; |
|||
double capbd, capbs, omega; |
|||
double gstot, gstotd, gstotg, gstots, gstotb, gspr; |
|||
double gdtot, gdtotd, gdtotg, gdtots, gdtotb, gdpr; |
|||
double gIstotg, gIstotd, gIstots, gIstotb; |
|||
double gIdtotg, gIdtotd, gIdtots, gIdtotb; |
|||
double gIbtotg, gIbtotd, gIbtots, gIbtotb; |
|||
double gIgtotg, gIgtotd, gIgtots, gIgtotb; |
|||
double cgso, cgdo, cgbo; |
|||
double gbspsp, gbbdp, gbbsp, gbspg, gbspb; |
|||
double gbspdp, gbdpdp, gbdpg, gbdpb, gbdpsp; |
|||
double T0=0.0, T1, T2, T3; |
|||
double Csg, Csd, Css; |
|||
double Cdgr, Cddr, Cdsr, Cdbr, Csgr, Csdr, Cssr, Csbr; |
|||
double Cdgi, Cddi, Cdsi, Cdbi, Csgi, Csdi, Cssi, Csbi; |
|||
double gmr, gmi, gmbsr, gmbsi, gdsr, gdsi; |
|||
double FwdSumr, RevSumr, Gmr, Gmbsr; |
|||
double FwdSumi, RevSumi, Gmi, Gmbsi; |
|||
struct bsim4SizeDependParam *pParam; |
|||
double ggidld, ggidlg, ggidlb, ggislg, ggislb, ggisls; |
|||
|
|||
double m; |
|||
|
|||
omega = ckt->CKTomega; |
|||
for (; model != NULL; model = model->BSIM4nextModel) |
|||
{ for (here = model->BSIM4instances; here!= NULL; |
|||
here = here->BSIM4nextInstance) |
|||
{ |
|||
pParam = here->pParam; |
|||
capbd = here->BSIM4capbd; |
|||
capbs = here->BSIM4capbs; |
|||
cgso = here->BSIM4cgso; |
|||
cgdo = here->BSIM4cgdo; |
|||
cgbo = pParam->BSIM4cgbo; |
|||
|
|||
Csd = -(here->BSIM4cddb + here->BSIM4cgdb + here->BSIM4cbdb); |
|||
Csg = -(here->BSIM4cdgb + here->BSIM4cggb + here->BSIM4cbgb); |
|||
Css = -(here->BSIM4cdsb + here->BSIM4cgsb + here->BSIM4cbsb); |
|||
|
|||
if (here->BSIM4acnqsMod) |
|||
{ T0 = omega * here->BSIM4taunet; |
|||
T1 = T0 * T0; |
|||
T2 = 1.0 / (1.0 + T1); |
|||
T3 = T0 * T2; |
|||
|
|||
gmr = here->BSIM4gm * T2; |
|||
gmbsr = here->BSIM4gmbs * T2; |
|||
gdsr = here->BSIM4gds * T2; |
|||
|
|||
gmi = -here->BSIM4gm * T3; |
|||
gmbsi = -here->BSIM4gmbs * T3; |
|||
gdsi = -here->BSIM4gds * T3; |
|||
|
|||
Cddr = here->BSIM4cddb * T2; |
|||
Cdgr = here->BSIM4cdgb * T2; |
|||
Cdsr = here->BSIM4cdsb * T2; |
|||
Cdbr = -(Cddr + Cdgr + Cdsr); |
|||
|
|||
/* WDLiu: Cxyi mulitplied by jomega below, and actually to be of conductance */ |
|||
Cddi = here->BSIM4cddb * T3 * omega; |
|||
Cdgi = here->BSIM4cdgb * T3 * omega; |
|||
Cdsi = here->BSIM4cdsb * T3 * omega; |
|||
Cdbi = -(Cddi + Cdgi + Cdsi); |
|||
|
|||
Csdr = Csd * T2; |
|||
Csgr = Csg * T2; |
|||
Cssr = Css * T2; |
|||
Csbr = -(Csdr + Csgr + Cssr); |
|||
|
|||
Csdi = Csd * T3 * omega; |
|||
Csgi = Csg * T3 * omega; |
|||
Cssi = Css * T3 * omega; |
|||
Csbi = -(Csdi + Csgi + Cssi); |
|||
|
|||
Cgdr = -(Cddr + Csdr + here->BSIM4cbdb); |
|||
Cggr = -(Cdgr + Csgr + here->BSIM4cbgb); |
|||
Cgsr = -(Cdsr + Cssr + here->BSIM4cbsb); |
|||
Cgbr = -(Cgdr + Cggr + Cgsr); |
|||
|
|||
Cgdi = -(Cddi + Csdi); |
|||
Cggi = -(Cdgi + Csgi); |
|||
Cgsi = -(Cdsi + Cssi); |
|||
Cgbi = -(Cgdi + Cggi + Cgsi); |
|||
} |
|||
else /* QS */ |
|||
{ gmr = here->BSIM4gm; |
|||
gmbsr = here->BSIM4gmbs; |
|||
gdsr = here->BSIM4gds; |
|||
gmi = gmbsi = gdsi = 0.0; |
|||
|
|||
Cddr = here->BSIM4cddb; |
|||
Cdgr = here->BSIM4cdgb; |
|||
Cdsr = here->BSIM4cdsb; |
|||
Cdbr = -(Cddr + Cdgr + Cdsr); |
|||
Cddi = Cdgi = Cdsi = Cdbi = 0.0; |
|||
|
|||
Csdr = Csd; |
|||
Csgr = Csg; |
|||
Cssr = Css; |
|||
Csbr = -(Csdr + Csgr + Cssr); |
|||
Csdi = Csgi = Cssi = Csbi = 0.0; |
|||
|
|||
Cgdr = here->BSIM4cgdb; |
|||
Cggr = here->BSIM4cggb; |
|||
Cgsr = here->BSIM4cgsb; |
|||
Cgbr = -(Cgdr + Cggr + Cgsr); |
|||
Cgdi = Cggi = Cgsi = Cgbi = 0.0; |
|||
} |
|||
|
|||
|
|||
if (here->BSIM4mode >= 0) |
|||
{ Gmr = gmr; |
|||
Gmbsr = gmbsr; |
|||
FwdSumr = Gmr + Gmbsr; |
|||
RevSumr = 0.0; |
|||
Gmi = gmi; |
|||
Gmbsi = gmbsi; |
|||
FwdSumi = Gmi + Gmbsi; |
|||
RevSumi = 0.0; |
|||
|
|||
gbbdp = -(here->BSIM4gbds); |
|||
gbbsp = here->BSIM4gbds + here->BSIM4gbgs + here->BSIM4gbbs; |
|||
gbdpg = here->BSIM4gbgs; |
|||
gbdpdp = here->BSIM4gbds; |
|||
gbdpb = here->BSIM4gbbs; |
|||
gbdpsp = -(gbdpg + gbdpdp + gbdpb); |
|||
|
|||
gbspdp = 0.0; |
|||
gbspg = 0.0; |
|||
gbspb = 0.0; |
|||
gbspsp = 0.0; |
|||
|
|||
if (model->BSIM4igcMod) |
|||
{ gIstotg = here->BSIM4gIgsg + here->BSIM4gIgcsg; |
|||
gIstotd = here->BSIM4gIgcsd; |
|||
gIstots = here->BSIM4gIgss + here->BSIM4gIgcss; |
|||
gIstotb = here->BSIM4gIgcsb; |
|||
|
|||
gIdtotg = here->BSIM4gIgdg + here->BSIM4gIgcdg; |
|||
gIdtotd = here->BSIM4gIgdd + here->BSIM4gIgcdd; |
|||
gIdtots = here->BSIM4gIgcds; |
|||
gIdtotb = here->BSIM4gIgcdb; |
|||
} |
|||
else |
|||
{ gIstotg = gIstotd = gIstots = gIstotb = 0.0; |
|||
gIdtotg = gIdtotd = gIdtots = gIdtotb = 0.0; |
|||
} |
|||
|
|||
if (model->BSIM4igbMod) |
|||
{ gIbtotg = here->BSIM4gIgbg; |
|||
gIbtotd = here->BSIM4gIgbd; |
|||
gIbtots = here->BSIM4gIgbs; |
|||
gIbtotb = here->BSIM4gIgbb; |
|||
} |
|||
else |
|||
gIbtotg = gIbtotd = gIbtots = gIbtotb = 0.0; |
|||
|
|||
if ((model->BSIM4igcMod != 0) || (model->BSIM4igbMod != 0)) |
|||
{ gIgtotg = gIstotg + gIdtotg + gIbtotg; |
|||
gIgtotd = gIstotd + gIdtotd + gIbtotd ; |
|||
gIgtots = gIstots + gIdtots + gIbtots; |
|||
gIgtotb = gIstotb + gIdtotb + gIbtotb; |
|||
} |
|||
else |
|||
gIgtotg = gIgtotd = gIgtots = gIgtotb = 0.0; |
|||
|
|||
if (here->BSIM4rgateMod == 2) |
|||
T0 = *(ckt->CKTstates[0] + here->BSIM4vges) |
|||
- *(ckt->CKTstates[0] + here->BSIM4vgs); |
|||
else if (here->BSIM4rgateMod == 3) |
|||
T0 = *(ckt->CKTstates[0] + here->BSIM4vgms) |
|||
- *(ckt->CKTstates[0] + here->BSIM4vgs); |
|||
if (here->BSIM4rgateMod > 1) |
|||
{ gcrgd = here->BSIM4gcrgd * T0; |
|||
gcrgg = here->BSIM4gcrgg * T0; |
|||
gcrgs = here->BSIM4gcrgs * T0; |
|||
gcrgb = here->BSIM4gcrgb * T0; |
|||
gcrgg -= here->BSIM4gcrg; |
|||
gcrg = here->BSIM4gcrg; |
|||
} |
|||
else |
|||
gcrg = gcrgd = gcrgg = gcrgs = gcrgb = 0.0; |
|||
|
|||
if (here->BSIM4rgateMod == 3) |
|||
{ xcgmgmb = (cgdo + cgso + pParam->BSIM4cgbo) * omega; |
|||
xcgmdb = -cgdo * omega; |
|||
xcgmsb = -cgso * omega; |
|||
xcgmbb = -pParam->BSIM4cgbo * omega; |
|||
|
|||
xcdgmb = xcgmdb; |
|||
xcsgmb = xcgmsb; |
|||
xcbgmb = xcgmbb; |
|||
|
|||
xcggbr = Cggr * omega; |
|||
xcgdbr = Cgdr * omega; |
|||
xcgsbr = Cgsr * omega; |
|||
xcgbbr = -(xcggbr + xcgdbr + xcgsbr); |
|||
|
|||
xcdgbr = Cdgr * omega; |
|||
xcsgbr = Csgr * omega; |
|||
xcbgb = here->BSIM4cbgb * omega; |
|||
} |
|||
else |
|||
{ xcggbr = (Cggr + cgdo + cgso + pParam->BSIM4cgbo ) * omega; |
|||
xcgdbr = (Cgdr - cgdo) * omega; |
|||
xcgsbr = (Cgsr - cgso) * omega; |
|||
xcgbbr = -(xcggbr + xcgdbr + xcgsbr); |
|||
|
|||
xcdgbr = (Cdgr - cgdo) * omega; |
|||
xcsgbr = (Csgr - cgso) * omega; |
|||
xcbgb = (here->BSIM4cbgb - pParam->BSIM4cgbo) * omega; |
|||
|
|||
xcdgmb = xcsgmb = xcbgmb = 0.0; |
|||
} |
|||
xcddbr = (Cddr + here->BSIM4capbd + cgdo) * omega; |
|||
xcdsbr = Cdsr * omega; |
|||
xcsdbr = Csdr * omega; |
|||
xcssbr = (here->BSIM4capbs + cgso + Cssr) * omega; |
|||
|
|||
if (!here->BSIM4rbodyMod) |
|||
{ xcdbbr = -(xcdgbr + xcddbr + xcdsbr + xcdgmb); |
|||
xcsbbr = -(xcsgbr + xcsdbr + xcssbr + xcsgmb); |
|||
|
|||
xcbdb = (here->BSIM4cbdb - here->BSIM4capbd) * omega; |
|||
xcbsb = (here->BSIM4cbsb - here->BSIM4capbs) * omega; |
|||
xcdbdb = 0.0; |
|||
} |
|||
else |
|||
{ xcdbbr = Cdbr * omega; |
|||
xcsbbr = -(xcsgbr + xcsdbr + xcssbr + xcsgmb) |
|||
+ here->BSIM4capbs * omega; |
|||
|
|||
xcbdb = here->BSIM4cbdb * omega; |
|||
xcbsb = here->BSIM4cbsb * omega; |
|||
|
|||
xcdbdb = -here->BSIM4capbd * omega; |
|||
xcsbsb = -here->BSIM4capbs * omega; |
|||
} |
|||
xcbbb = -(xcbdb + xcbgb + xcbsb + xcbgmb); |
|||
|
|||
xcdgbi = Cdgi; |
|||
xcsgbi = Csgi; |
|||
xcddbi = Cddi; |
|||
xcdsbi = Cdsi; |
|||
xcsdbi = Csdi; |
|||
xcssbi = Cssi; |
|||
xcdbbi = Cdbi; |
|||
xcsbbi = Csbi; |
|||
xcggbi = Cggi; |
|||
xcgdbi = Cgdi; |
|||
xcgsbi = Cgsi; |
|||
xcgbbi = Cgbi; |
|||
} |
|||
else /* Reverse mode */ |
|||
{ Gmr = -gmr; |
|||
Gmbsr = -gmbsr; |
|||
FwdSumr = 0.0; |
|||
RevSumr = -(Gmr + Gmbsr); |
|||
Gmi = -gmi; |
|||
Gmbsi = -gmbsi; |
|||
FwdSumi = 0.0; |
|||
RevSumi = -(Gmi + Gmbsi); |
|||
|
|||
gbbsp = -(here->BSIM4gbds); |
|||
gbbdp = here->BSIM4gbds + here->BSIM4gbgs + here->BSIM4gbbs; |
|||
|
|||
gbdpg = 0.0; |
|||
gbdpsp = 0.0; |
|||
gbdpb = 0.0; |
|||
gbdpdp = 0.0; |
|||
|
|||
gbspg = here->BSIM4gbgs; |
|||
gbspsp = here->BSIM4gbds; |
|||
gbspb = here->BSIM4gbbs; |
|||
gbspdp = -(gbspg + gbspsp + gbspb); |
|||
|
|||
if (model->BSIM4igcMod) |
|||
{ gIstotg = here->BSIM4gIgsg + here->BSIM4gIgcdg; |
|||
gIstotd = here->BSIM4gIgcds; |
|||
gIstots = here->BSIM4gIgss + here->BSIM4gIgcdd; |
|||
gIstotb = here->BSIM4gIgcdb; |
|||
|
|||
gIdtotg = here->BSIM4gIgdg + here->BSIM4gIgcsg; |
|||
gIdtotd = here->BSIM4gIgdd + here->BSIM4gIgcss; |
|||
gIdtots = here->BSIM4gIgcsd; |
|||
gIdtotb = here->BSIM4gIgcsb; |
|||
} |
|||
else |
|||
{ gIstotg = gIstotd = gIstots = gIstotb = 0.0; |
|||
gIdtotg = gIdtotd = gIdtots = gIdtotb = 0.0; |
|||
} |
|||
|
|||
if (model->BSIM4igbMod) |
|||
{ gIbtotg = here->BSIM4gIgbg; |
|||
gIbtotd = here->BSIM4gIgbs; |
|||
gIbtots = here->BSIM4gIgbd; |
|||
gIbtotb = here->BSIM4gIgbb; |
|||
} |
|||
else |
|||
gIbtotg = gIbtotd = gIbtots = gIbtotb = 0.0; |
|||
|
|||
if ((model->BSIM4igcMod != 0) || (model->BSIM4igbMod != 0)) |
|||
{ gIgtotg = gIstotg + gIdtotg + gIbtotg; |
|||
gIgtotd = gIstotd + gIdtotd + gIbtotd ; |
|||
gIgtots = gIstots + gIdtots + gIbtots; |
|||
gIgtotb = gIstotb + gIdtotb + gIbtotb; |
|||
} |
|||
else |
|||
gIgtotg = gIgtotd = gIgtots = gIgtotb = 0.0; |
|||
|
|||
if (here->BSIM4rgateMod == 2) |
|||
T0 = *(ckt->CKTstates[0] + here->BSIM4vges) |
|||
- *(ckt->CKTstates[0] + here->BSIM4vgs); |
|||
else if (here->BSIM4rgateMod == 3) |
|||
T0 = *(ckt->CKTstates[0] + here->BSIM4vgms) |
|||
- *(ckt->CKTstates[0] + here->BSIM4vgs); |
|||
if (here->BSIM4rgateMod > 1) |
|||
{ gcrgd = here->BSIM4gcrgs * T0; |
|||
gcrgg = here->BSIM4gcrgg * T0; |
|||
gcrgs = here->BSIM4gcrgd * T0; |
|||
gcrgb = here->BSIM4gcrgb * T0; |
|||
gcrgg -= here->BSIM4gcrg; |
|||
gcrg = here->BSIM4gcrg; |
|||
} |
|||
else |
|||
gcrg = gcrgd = gcrgg = gcrgs = gcrgb = 0.0; |
|||
|
|||
if (here->BSIM4rgateMod == 3) |
|||
{ xcgmgmb = (cgdo + cgso + pParam->BSIM4cgbo) * omega; |
|||
xcgmdb = -cgdo * omega; |
|||
xcgmsb = -cgso * omega; |
|||
xcgmbb = -pParam->BSIM4cgbo * omega; |
|||
|
|||
xcdgmb = xcgmdb; |
|||
xcsgmb = xcgmsb; |
|||
xcbgmb = xcgmbb; |
|||
|
|||
xcggbr = Cggr * omega; |
|||
xcgdbr = Cgsr * omega; |
|||
xcgsbr = Cgdr * omega; |
|||
xcgbbr = -(xcggbr + xcgdbr + xcgsbr); |
|||
|
|||
xcdgbr = Csgr * omega; |
|||
xcsgbr = Cdgr * omega; |
|||
xcbgb = here->BSIM4cbgb * omega; |
|||
} |
|||
else |
|||
{ xcggbr = (Cggr + cgdo + cgso + pParam->BSIM4cgbo ) * omega; |
|||
xcgdbr = (Cgsr - cgdo) * omega; |
|||
xcgsbr = (Cgdr - cgso) * omega; |
|||
xcgbbr = -(xcggbr + xcgdbr + xcgsbr); |
|||
|
|||
xcdgbr = (Csgr - cgdo) * omega; |
|||
xcsgbr = (Cdgr - cgso) * omega; |
|||
xcbgb = (here->BSIM4cbgb - pParam->BSIM4cgbo) * omega; |
|||
|
|||
xcdgmb = xcsgmb = xcbgmb = 0.0; |
|||
} |
|||
xcddbr = (here->BSIM4capbd + cgdo + Cssr) * omega; |
|||
xcdsbr = Csdr * omega; |
|||
xcsdbr = Cdsr * omega; |
|||
xcssbr = (Cddr + here->BSIM4capbs + cgso) * omega; |
|||
|
|||
if (!here->BSIM4rbodyMod) |
|||
{ xcdbbr = -(xcdgbr + xcddbr + xcdsbr + xcdgmb); |
|||
xcsbbr = -(xcsgbr + xcsdbr + xcssbr + xcsgmb); |
|||
|
|||
xcbdb = (here->BSIM4cbsb - here->BSIM4capbd) * omega; |
|||
xcbsb = (here->BSIM4cbdb - here->BSIM4capbs) * omega; |
|||
xcdbdb = 0.0; |
|||
} |
|||
else |
|||
{ xcdbbr = -(xcdgbr + xcddbr + xcdsbr + xcdgmb) |
|||
+ here->BSIM4capbd * omega; |
|||
xcsbbr = Cdbr * omega; |
|||
|
|||
xcbdb = here->BSIM4cbsb * omega; |
|||
xcbsb = here->BSIM4cbdb * omega; |
|||
xcdbdb = -here->BSIM4capbd * omega; |
|||
xcsbsb = -here->BSIM4capbs * omega; |
|||
} |
|||
xcbbb = -(xcbgb + xcbdb + xcbsb + xcbgmb); |
|||
|
|||
xcdgbi = Csgi; |
|||
xcsgbi = Cdgi; |
|||
xcddbi = Cssi; |
|||
xcdsbi = Csdi; |
|||
xcsdbi = Cdsi; |
|||
xcssbi = Cddi; |
|||
xcdbbi = Csbi; |
|||
xcsbbi = Cdbi; |
|||
xcggbi = Cggi; |
|||
xcgdbi = Cgsi; |
|||
xcgsbi = Cgdi; |
|||
xcgbbi = Cgbi; |
|||
} |
|||
|
|||
if (model->BSIM4rdsMod == 1) |
|||
{ gstot = here->BSIM4gstot; |
|||
gstotd = here->BSIM4gstotd; |
|||
gstotg = here->BSIM4gstotg; |
|||
gstots = here->BSIM4gstots - gstot; |
|||
gstotb = here->BSIM4gstotb; |
|||
|
|||
gdtot = here->BSIM4gdtot; |
|||
gdtotd = here->BSIM4gdtotd - gdtot; |
|||
gdtotg = here->BSIM4gdtotg; |
|||
gdtots = here->BSIM4gdtots; |
|||
gdtotb = here->BSIM4gdtotb; |
|||
} |
|||
else |
|||
{ gstot = gstotd = gstotg = gstots = gstotb = 0.0; |
|||
gdtot = gdtotd = gdtotg = gdtots = gdtotb = 0.0; |
|||
} |
|||
|
|||
|
|||
/* |
|||
* Loading AC matrix |
|||
*/ |
|||
m = here->BSIM4m; |
|||
|
|||
if (!model->BSIM4rdsMod) |
|||
{ gdpr = here->BSIM4drainConductance; |
|||
gspr = here->BSIM4sourceConductance; |
|||
} |
|||
else |
|||
gdpr = gspr = 0.0; |
|||
|
|||
if (!here->BSIM4rbodyMod) |
|||
{ gjbd = here->BSIM4gbd; |
|||
gjbs = here->BSIM4gbs; |
|||
} |
|||
else |
|||
gjbd = gjbs = 0.0; |
|||
|
|||
geltd = here->BSIM4grgeltd; |
|||
|
|||
if (here->BSIM4rgateMod == 1) |
|||
{ *(here->BSIM4GEgePtr) += m * geltd; |
|||
*(here->BSIM4GPgePtr) -= m * geltd; |
|||
*(here->BSIM4GEgpPtr) -= m * geltd; |
|||
|
|||
*(here->BSIM4GPgpPtr +1) += m * xcggbr; |
|||
*(here->BSIM4GPgpPtr) += m * (geltd + xcggbi + gIgtotg); |
|||
*(here->BSIM4GPdpPtr +1) += m * xcgdbr; |
|||
*(here->BSIM4GPdpPtr) += m * (xcgdbi + gIgtotd); |
|||
*(here->BSIM4GPspPtr +1) += m * xcgsbr; |
|||
*(here->BSIM4GPspPtr) += m * (xcgsbi + gIgtots); |
|||
*(here->BSIM4GPbpPtr +1) += m * xcgbbr; |
|||
*(here->BSIM4GPbpPtr) += m * (xcgbbi + gIgtotb); |
|||
} /* WDLiu: gcrg already subtracted from all gcrgg below */ |
|||
else if (here->BSIM4rgateMod == 2) |
|||
{ *(here->BSIM4GEgePtr) += m * gcrg; |
|||
*(here->BSIM4GEgpPtr) += m * gcrgg; |
|||
*(here->BSIM4GEdpPtr) += m * gcrgd; |
|||
*(here->BSIM4GEspPtr) += m * gcrgs; |
|||
*(here->BSIM4GEbpPtr) += m * gcrgb; |
|||
|
|||
*(here->BSIM4GPgePtr) -= m * gcrg; |
|||
*(here->BSIM4GPgpPtr +1) += m * xcggbr; |
|||
*(here->BSIM4GPgpPtr) -= m * (gcrgg - xcggbi - gIgtotg); |
|||
*(here->BSIM4GPdpPtr +1) += m * xcgdbr; |
|||
*(here->BSIM4GPdpPtr) -= m * (gcrgd - xcgdbi - gIgtotd); |
|||
*(here->BSIM4GPspPtr +1) += m * xcgsbr; |
|||
*(here->BSIM4GPspPtr) -= m * (gcrgs - xcgsbi - gIgtots); |
|||
*(here->BSIM4GPbpPtr +1) += m * xcgbbr; |
|||
*(here->BSIM4GPbpPtr) -= m * (gcrgb - xcgbbi - gIgtotb); |
|||
} |
|||
else if (here->BSIM4rgateMod == 3) |
|||
{ *(here->BSIM4GEgePtr) += m * geltd; |
|||
*(here->BSIM4GEgmPtr) -= m * geltd; |
|||
*(here->BSIM4GMgePtr) -= m * geltd; |
|||
*(here->BSIM4GMgmPtr) += m * (geltd + gcrg); |
|||
*(here->BSIM4GMgmPtr +1) += m * xcgmgmb; |
|||
|
|||
*(here->BSIM4GMdpPtr) += m * gcrgd; |
|||
*(here->BSIM4GMdpPtr +1) += m * xcgmdb; |
|||
*(here->BSIM4GMgpPtr) += m * gcrgg; |
|||
*(here->BSIM4GMspPtr) += m * gcrgs; |
|||
*(here->BSIM4GMspPtr +1) += m * xcgmsb; |
|||
*(here->BSIM4GMbpPtr) += m * gcrgb; |
|||
*(here->BSIM4GMbpPtr +1) += m * xcgmbb; |
|||
|
|||
*(here->BSIM4DPgmPtr +1) += m * xcdgmb; |
|||
*(here->BSIM4GPgmPtr) -= m * gcrg; |
|||
*(here->BSIM4SPgmPtr +1) += m * xcsgmb; |
|||
*(here->BSIM4BPgmPtr +1) += m * xcbgmb; |
|||
|
|||
*(here->BSIM4GPgpPtr) -= m * (gcrgg - xcggbi - gIgtotg); |
|||
*(here->BSIM4GPgpPtr +1) += m * xcggbr; |
|||
*(here->BSIM4GPdpPtr) -= m * (gcrgd - xcgdbi - gIgtotd); |
|||
*(here->BSIM4GPdpPtr +1) += m * xcgdbr; |
|||
*(here->BSIM4GPspPtr) -= m * (gcrgs - xcgsbi - gIgtots); |
|||
*(here->BSIM4GPspPtr +1) += m * xcgsbr; |
|||
*(here->BSIM4GPbpPtr) -= m * (gcrgb - xcgbbi - gIgtotb); |
|||
*(here->BSIM4GPbpPtr +1) += m * xcgbbr; |
|||
} |
|||
else |
|||
{ *(here->BSIM4GPgpPtr +1) += m * xcggbr; |
|||
*(here->BSIM4GPgpPtr) += m * (xcggbi + gIgtotg); |
|||
*(here->BSIM4GPdpPtr +1) += m * xcgdbr; |
|||
*(here->BSIM4GPdpPtr) += m * (xcgdbi + gIgtotd); |
|||
*(here->BSIM4GPspPtr +1) += m * xcgsbr; |
|||
*(here->BSIM4GPspPtr) += m * (xcgsbi + gIgtots); |
|||
*(here->BSIM4GPbpPtr +1) += m * xcgbbr; |
|||
*(here->BSIM4GPbpPtr) += m * (xcgbbi + gIgtotb); |
|||
} |
|||
|
|||
if (model->BSIM4rdsMod) |
|||
{ (*(here->BSIM4DgpPtr) += m * gdtotg); |
|||
(*(here->BSIM4DspPtr) += m * gdtots); |
|||
(*(here->BSIM4DbpPtr) += m * gdtotb); |
|||
(*(here->BSIM4SdpPtr) += m * gstotd); |
|||
(*(here->BSIM4SgpPtr) += m * gstotg); |
|||
(*(here->BSIM4SbpPtr) += m * gstotb); |
|||
} |
|||
|
|||
*(here->BSIM4DPdpPtr +1) += m * (xcddbr + gdsi + RevSumi); |
|||
*(here->BSIM4DPdpPtr) += m * (gdpr + xcddbi + gdsr + here->BSIM4gbd |
|||
- gdtotd + RevSumr + gbdpdp - gIdtotd); |
|||
*(here->BSIM4DPdPtr) -= m * (gdpr + gdtot); |
|||
*(here->BSIM4DPgpPtr +1) += m * (xcdgbr + Gmi); |
|||
*(here->BSIM4DPgpPtr) += m * (Gmr + xcdgbi - gdtotg + gbdpg - gIdtotg); |
|||
*(here->BSIM4DPspPtr +1) += m * (xcdsbr - gdsi - FwdSumi); |
|||
*(here->BSIM4DPspPtr) -= m * (gdsr - xcdsbi + FwdSumr + gdtots - gbdpsp + gIdtots); |
|||
*(here->BSIM4DPbpPtr +1) += m * (xcdbbr + Gmbsi); |
|||
*(here->BSIM4DPbpPtr) -= m * (gjbd + gdtotb - xcdbbi - Gmbsr - gbdpb + gIdtotb); |
|||
|
|||
*(here->BSIM4DdpPtr) -= m * (gdpr - gdtotd); |
|||
*(here->BSIM4DdPtr) += m * (gdpr + gdtot); |
|||
|
|||
*(here->BSIM4SPdpPtr +1) += m * (xcsdbr - gdsi - RevSumi); |
|||
*(here->BSIM4SPdpPtr) -= m * (gdsr - xcsdbi + gstotd + RevSumr - gbspdp + gIstotd); |
|||
*(here->BSIM4SPgpPtr +1) += m * (xcsgbr - Gmi); |
|||
*(here->BSIM4SPgpPtr) -= m * (Gmr - xcsgbi + gstotg - gbspg + gIstotg); |
|||
*(here->BSIM4SPspPtr +1) += m * (xcssbr + gdsi + FwdSumi); |
|||
*(here->BSIM4SPspPtr) += m * (gspr + xcssbi + gdsr + here->BSIM4gbs |
|||
- gstots + FwdSumr + gbspsp - gIstots); |
|||
*(here->BSIM4SPsPtr) -= m * (gspr + gstot); |
|||
*(here->BSIM4SPbpPtr +1) += m * (xcsbbr - Gmbsi); |
|||
*(here->BSIM4SPbpPtr) -= m * (gjbs + gstotb - xcsbbi + Gmbsr - gbspb + gIstotb); |
|||
|
|||
*(here->BSIM4SspPtr) -= m * (gspr - gstots); |
|||
*(here->BSIM4SsPtr) += m * (gspr + gstot); |
|||
|
|||
*(here->BSIM4BPdpPtr +1) += m * xcbdb; |
|||
*(here->BSIM4BPdpPtr) -= m * (gjbd - gbbdp + gIbtotd); |
|||
*(here->BSIM4BPgpPtr +1) += m * xcbgb; |
|||
*(here->BSIM4BPgpPtr) -= m * (here->BSIM4gbgs + gIbtotg); |
|||
*(here->BSIM4BPspPtr +1) += m * xcbsb; |
|||
*(here->BSIM4BPspPtr) -= m * (gjbs - gbbsp + gIbtots); |
|||
*(here->BSIM4BPbpPtr +1) += m * xcbbb; |
|||
*(here->BSIM4BPbpPtr) += m * (gjbd + gjbs - here->BSIM4gbbs |
|||
- gIbtotb); |
|||
ggidld = here->BSIM4ggidld; |
|||
ggidlg = here->BSIM4ggidlg; |
|||
ggidlb = here->BSIM4ggidlb; |
|||
ggislg = here->BSIM4ggislg; |
|||
ggisls = here->BSIM4ggisls; |
|||
ggislb = here->BSIM4ggislb; |
|||
|
|||
/* stamp gidl */ |
|||
(*(here->BSIM4DPdpPtr) += m * ggidld); |
|||
(*(here->BSIM4DPgpPtr) += m * ggidlg); |
|||
(*(here->BSIM4DPspPtr) -= m * ((ggidlg + ggidld) + ggidlb)); |
|||
(*(here->BSIM4DPbpPtr) += m * ggidlb); |
|||
(*(here->BSIM4BPdpPtr) -= m * ggidld); |
|||
(*(here->BSIM4BPgpPtr) -= m * ggidlg); |
|||
(*(here->BSIM4BPspPtr) += m * ((ggidlg + ggidld) + ggidlb)); |
|||
(*(here->BSIM4BPbpPtr) -= m * ggidlb); |
|||
/* stamp gisl */ |
|||
(*(here->BSIM4SPdpPtr) -= m * ((ggisls + ggislg) + ggislb)); |
|||
(*(here->BSIM4SPgpPtr) += m * ggislg); |
|||
(*(here->BSIM4SPspPtr) += m * ggisls); |
|||
(*(here->BSIM4SPbpPtr) += m * ggislb); |
|||
(*(here->BSIM4BPdpPtr) += m * ((ggislg + ggisls) + ggislb)); |
|||
(*(here->BSIM4BPgpPtr) -= m * ggislg); |
|||
(*(here->BSIM4BPspPtr) -= m * ggisls); |
|||
(*(here->BSIM4BPbpPtr) -= m * ggislb); |
|||
|
|||
if (here->BSIM4rbodyMod) |
|||
{ (*(here->BSIM4DPdbPtr +1) += m * xcdbdb); |
|||
(*(here->BSIM4DPdbPtr) -= m * here->BSIM4gbd); |
|||
(*(here->BSIM4SPsbPtr +1) += m * xcsbsb); |
|||
(*(here->BSIM4SPsbPtr) -= m * here->BSIM4gbs); |
|||
|
|||
(*(here->BSIM4DBdpPtr +1) += m * xcdbdb); |
|||
(*(here->BSIM4DBdpPtr) -= m * here->BSIM4gbd); |
|||
(*(here->BSIM4DBdbPtr +1) -= m * xcdbdb); |
|||
(*(here->BSIM4DBdbPtr) += m * (here->BSIM4gbd + here->BSIM4grbpd |
|||
+ here->BSIM4grbdb)); |
|||
(*(here->BSIM4DBbpPtr) -= m * here->BSIM4grbpd); |
|||
(*(here->BSIM4DBbPtr) -= m * here->BSIM4grbdb); |
|||
|
|||
(*(here->BSIM4BPdbPtr) -= m * here->BSIM4grbpd); |
|||
(*(here->BSIM4BPbPtr) -= m * here->BSIM4grbpb); |
|||
(*(here->BSIM4BPsbPtr) -= m * here->BSIM4grbps); |
|||
(*(here->BSIM4BPbpPtr) += m * (here->BSIM4grbpd + here->BSIM4grbps |
|||
+ here->BSIM4grbpb)); |
|||
/* WDLiu: (-here->BSIM4gbbs) already added to BPbpPtr */ |
|||
|
|||
(*(here->BSIM4SBspPtr +1) += m * xcsbsb); |
|||
(*(here->BSIM4SBspPtr) -= m * here->BSIM4gbs); |
|||
(*(here->BSIM4SBbpPtr) -= m * here->BSIM4grbps); |
|||
(*(here->BSIM4SBbPtr) -= m * here->BSIM4grbsb); |
|||
(*(here->BSIM4SBsbPtr +1) -= m * xcsbsb); |
|||
(*(here->BSIM4SBsbPtr) += m * (here->BSIM4gbs |
|||
+ here->BSIM4grbps + here->BSIM4grbsb)); |
|||
|
|||
(*(here->BSIM4BdbPtr) -= m * here->BSIM4grbdb); |
|||
(*(here->BSIM4BbpPtr) -= m * here->BSIM4grbpb); |
|||
(*(here->BSIM4BsbPtr) -= m * here->BSIM4grbsb); |
|||
(*(here->BSIM4BbPtr) += m * (here->BSIM4grbsb + here->BSIM4grbdb |
|||
+ here->BSIM4grbpb)); |
|||
} |
|||
|
|||
|
|||
/* |
|||
* WDLiu: The internal charge node generated for transient NQS is not needed for |
|||
* AC NQS. The following is not doing a real job, but we have to keep it; |
|||
* otherwise a singular AC NQS matrix may occur if the transient NQS is on. |
|||
* The charge node is isolated from the instance. |
|||
*/ |
|||
if (here->BSIM4trnqsMod) |
|||
{ (*(here->BSIM4QqPtr) += m * 1.0); |
|||
(*(here->BSIM4QgpPtr) += 0.0); |
|||
(*(here->BSIM4QdpPtr) += 0.0); |
|||
(*(here->BSIM4QspPtr) += 0.0); |
|||
(*(here->BSIM4QbpPtr) += 0.0); |
|||
|
|||
(*(here->BSIM4DPqPtr) += 0.0); |
|||
(*(here->BSIM4SPqPtr) += 0.0); |
|||
(*(here->BSIM4GPqPtr) += 0.0); |
|||
} |
|||
} |
|||
} |
|||
return(OK); |
|||
} |
|||
@ -0,0 +1,405 @@ |
|||
/**** BSIM4.7.0 Released by Darsen Lu 04/08/2011 ****/ |
|||
|
|||
/********** |
|||
* Copyright 2006 Regents of the University of California. All rights reserved. |
|||
* File: b4ask.c of BSIM4.7.0. |
|||
* Author: 2000 Weidong Liu |
|||
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu. |
|||
* Authors: 2006- Mohan Dunga, Ali Niknejad, Chenming Hu |
|||
* Authors: 2007- Mohan Dunga, Wenwei Yang, Ali Niknejad, Chenming Hu |
|||
* Project Director: Prof. Chenming Hu. |
|||
* Modified by Xuemei Xi, 04/06/2001. |
|||
* Modified by Xuemei Xi, 10/05/2001. |
|||
* Modified by Xuemei Xi, 05/09/2003. |
|||
* Modified by Xuemei Xi, Mohan Dunga, 07/29/2005. |
|||
**********/ |
|||
|
|||
#include "ngspice/ngspice.h" |
|||
#include "ngspice/ifsim.h" |
|||
#include "ngspice/cktdefs.h" |
|||
#include "ngspice/devdefs.h" |
|||
#include "bsim4def.h" |
|||
#include "ngspice/sperror.h" |
|||
#include "ngspice/suffix.h" |
|||
|
|||
int |
|||
BSIM4ask( |
|||
CKTcircuit *ckt, |
|||
GENinstance *inst, |
|||
int which, |
|||
IFvalue *value, |
|||
IFvalue *select) |
|||
{ |
|||
BSIM4instance *here = (BSIM4instance*)inst; |
|||
|
|||
NG_IGNORE(select); |
|||
|
|||
switch(which) |
|||
{ case BSIM4_L: |
|||
value->rValue = here->BSIM4l; |
|||
return(OK); |
|||
case BSIM4_W: |
|||
value->rValue = here->BSIM4w; |
|||
return(OK); |
|||
case BSIM4_M: |
|||
value->rValue = here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_NF: |
|||
value->rValue = here->BSIM4nf; |
|||
return(OK); |
|||
case BSIM4_MIN: |
|||
value->iValue = here->BSIM4min; |
|||
return(OK); |
|||
case BSIM4_AS: |
|||
value->rValue = here->BSIM4sourceArea; |
|||
return(OK); |
|||
case BSIM4_AD: |
|||
value->rValue = here->BSIM4drainArea; |
|||
return(OK); |
|||
case BSIM4_PS: |
|||
value->rValue = here->BSIM4sourcePerimeter; |
|||
return(OK); |
|||
case BSIM4_PD: |
|||
value->rValue = here->BSIM4drainPerimeter; |
|||
return(OK); |
|||
case BSIM4_NRS: |
|||
value->rValue = here->BSIM4sourceSquares; |
|||
return(OK); |
|||
case BSIM4_NRD: |
|||
value->rValue = here->BSIM4drainSquares; |
|||
return(OK); |
|||
case BSIM4_OFF: |
|||
value->rValue = here->BSIM4off; |
|||
return(OK); |
|||
case BSIM4_SA: |
|||
value->rValue = here->BSIM4sa ; |
|||
return(OK); |
|||
case BSIM4_SB: |
|||
value->rValue = here->BSIM4sb ; |
|||
return(OK); |
|||
case BSIM4_SD: |
|||
value->rValue = here->BSIM4sd ; |
|||
return(OK); |
|||
case BSIM4_SCA: |
|||
value->rValue = here->BSIM4sca ; |
|||
return(OK); |
|||
case BSIM4_SCB: |
|||
value->rValue = here->BSIM4scb ; |
|||
return(OK); |
|||
case BSIM4_SCC: |
|||
value->rValue = here->BSIM4scc ; |
|||
return(OK); |
|||
case BSIM4_SC: |
|||
value->rValue = here->BSIM4sc ; |
|||
return(OK); |
|||
|
|||
case BSIM4_RBSB: |
|||
value->rValue = here->BSIM4rbsb; |
|||
return(OK); |
|||
case BSIM4_RBDB: |
|||
value->rValue = here->BSIM4rbdb; |
|||
return(OK); |
|||
case BSIM4_RBPB: |
|||
value->rValue = here->BSIM4rbpb; |
|||
return(OK); |
|||
case BSIM4_RBPS: |
|||
value->rValue = here->BSIM4rbps; |
|||
return(OK); |
|||
case BSIM4_RBPD: |
|||
value->rValue = here->BSIM4rbpd; |
|||
return(OK); |
|||
case BSIM4_DELVTO: |
|||
value->rValue = here->BSIM4delvto; |
|||
return(OK); |
|||
case BSIM4_XGW: |
|||
value->rValue = here->BSIM4xgw; |
|||
return(OK); |
|||
case BSIM4_NGCON: |
|||
value->rValue = here->BSIM4ngcon; |
|||
return(OK); |
|||
case BSIM4_TRNQSMOD: |
|||
value->iValue = here->BSIM4trnqsMod; |
|||
return(OK); |
|||
case BSIM4_ACNQSMOD: |
|||
value->iValue = here->BSIM4acnqsMod; |
|||
return(OK); |
|||
case BSIM4_RBODYMOD: |
|||
value->iValue = here->BSIM4rbodyMod; |
|||
return(OK); |
|||
case BSIM4_RGATEMOD: |
|||
value->iValue = here->BSIM4rgateMod; |
|||
return(OK); |
|||
case BSIM4_GEOMOD: |
|||
value->iValue = here->BSIM4geoMod; |
|||
return(OK); |
|||
case BSIM4_RGEOMOD: |
|||
value->iValue = here->BSIM4rgeoMod; |
|||
return(OK); |
|||
case BSIM4_IC_VDS: |
|||
value->rValue = here->BSIM4icVDS; |
|||
return(OK); |
|||
case BSIM4_IC_VGS: |
|||
value->rValue = here->BSIM4icVGS; |
|||
return(OK); |
|||
case BSIM4_IC_VBS: |
|||
value->rValue = here->BSIM4icVBS; |
|||
return(OK); |
|||
case BSIM4_DNODE: |
|||
value->iValue = here->BSIM4dNode; |
|||
return(OK); |
|||
case BSIM4_GNODEEXT: |
|||
value->iValue = here->BSIM4gNodeExt; |
|||
return(OK); |
|||
case BSIM4_SNODE: |
|||
value->iValue = here->BSIM4sNode; |
|||
return(OK); |
|||
case BSIM4_BNODE: |
|||
value->iValue = here->BSIM4bNode; |
|||
return(OK); |
|||
case BSIM4_DNODEPRIME: |
|||
value->iValue = here->BSIM4dNodePrime; |
|||
return(OK); |
|||
case BSIM4_GNODEPRIME: |
|||
value->iValue = here->BSIM4gNodePrime; |
|||
return(OK); |
|||
case BSIM4_GNODEMID: |
|||
value->iValue = here->BSIM4gNodeMid; |
|||
return(OK); |
|||
case BSIM4_SNODEPRIME: |
|||
value->iValue = here->BSIM4sNodePrime; |
|||
return(OK); |
|||
case BSIM4_DBNODE: |
|||
value->iValue = here->BSIM4dbNode; |
|||
return(OK); |
|||
case BSIM4_BNODEPRIME: |
|||
value->iValue = here->BSIM4bNodePrime; |
|||
return(OK); |
|||
case BSIM4_SBNODE: |
|||
value->iValue = here->BSIM4sbNode; |
|||
return(OK); |
|||
case BSIM4_SOURCECONDUCT: |
|||
value->rValue = here->BSIM4sourceConductance; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_DRAINCONDUCT: |
|||
value->rValue = here->BSIM4drainConductance; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_VBD: |
|||
value->rValue = *(ckt->CKTstate0 + here->BSIM4vbd); |
|||
return(OK); |
|||
case BSIM4_VBS: |
|||
value->rValue = *(ckt->CKTstate0 + here->BSIM4vbs); |
|||
return(OK); |
|||
case BSIM4_VGS: |
|||
value->rValue = *(ckt->CKTstate0 + here->BSIM4vgs); |
|||
return(OK); |
|||
case BSIM4_VDS: |
|||
value->rValue = *(ckt->CKTstate0 + here->BSIM4vds); |
|||
return(OK); |
|||
case BSIM4_CD: |
|||
value->rValue = here->BSIM4cd; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_CBS: |
|||
value->rValue = here->BSIM4cbs; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_CBD: |
|||
value->rValue = here->BSIM4cbd; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_CSUB: |
|||
value->rValue = here->BSIM4csub; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_QINV: |
|||
value->rValue = here-> BSIM4qinv; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_IGIDL: |
|||
value->rValue = here->BSIM4Igidl; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_IGISL: |
|||
value->rValue = here->BSIM4Igisl; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_IGS: |
|||
value->rValue = here->BSIM4Igs; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_IGD: |
|||
value->rValue = here->BSIM4Igd; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_IGB: |
|||
value->rValue = here->BSIM4Igb; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_IGCS: |
|||
value->rValue = here->BSIM4Igcs; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_IGCD: |
|||
value->rValue = here->BSIM4Igcd; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_GM: |
|||
value->rValue = here->BSIM4gm; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_GDS: |
|||
value->rValue = here->BSIM4gds; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_GMBS: |
|||
value->rValue = here->BSIM4gmbs; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_GBD: |
|||
value->rValue = here->BSIM4gbd; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_GBS: |
|||
value->rValue = here->BSIM4gbs; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
/* case BSIM4_QB: |
|||
value->rValue = *(ckt->CKTstate0 + here->BSIM4qb); |
|||
return(OK); */ |
|||
case BSIM4_CQB: |
|||
value->rValue = *(ckt->CKTstate0 + here->BSIM4cqb); |
|||
return(OK); |
|||
/* case BSIM4_QG: |
|||
value->rValue = *(ckt->CKTstate0 + here->BSIM4qg); |
|||
return(OK); */ |
|||
case BSIM4_CQG: |
|||
value->rValue = *(ckt->CKTstate0 + here->BSIM4cqg); |
|||
return(OK); |
|||
/* case BSIM4_QD: |
|||
value->rValue = *(ckt->CKTstate0 + here->BSIM4qd); |
|||
return(OK); */ |
|||
case BSIM4_CQD: |
|||
value->rValue = *(ckt->CKTstate0 + here->BSIM4cqd); |
|||
return(OK); |
|||
/* case BSIM4_QS: |
|||
value->rValue = *(ckt->CKTstate0 + here->BSIM4qs); |
|||
return(OK); */ |
|||
case BSIM4_QB: |
|||
value->rValue = here->BSIM4qbulk; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_QG: |
|||
value->rValue = here->BSIM4qgate; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_QS: |
|||
value->rValue = here->BSIM4qsrc; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_QD: |
|||
value->rValue = here->BSIM4qdrn; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_QDEF: |
|||
value->rValue = *(ckt->CKTstate0 + here->BSIM4qdef); |
|||
return(OK); |
|||
case BSIM4_GCRG: |
|||
value->rValue = here->BSIM4gcrg; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_GTAU: |
|||
value->rValue = here->BSIM4gtau; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_CGGB: |
|||
value->rValue = here->BSIM4cggb; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_CGDB: |
|||
value->rValue = here->BSIM4cgdb; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_CGSB: |
|||
value->rValue = here->BSIM4cgsb; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_CDGB: |
|||
value->rValue = here->BSIM4cdgb; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_CDDB: |
|||
value->rValue = here->BSIM4cddb; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_CDSB: |
|||
value->rValue = here->BSIM4cdsb; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_CBGB: |
|||
value->rValue = here->BSIM4cbgb; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_CBDB: |
|||
value->rValue = here->BSIM4cbdb; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_CBSB: |
|||
value->rValue = here->BSIM4cbsb; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_CSGB: |
|||
value->rValue = here->BSIM4csgb; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_CSDB: |
|||
value->rValue = here->BSIM4csdb; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_CSSB: |
|||
value->rValue = here->BSIM4cssb; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_CGBB: |
|||
value->rValue = here->BSIM4cgbb; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_CDBB: |
|||
value->rValue = here->BSIM4cdbb; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_CSBB: |
|||
value->rValue = here->BSIM4csbb; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_CBBB: |
|||
value->rValue = here->BSIM4cbbb; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_CAPBD: |
|||
value->rValue = here->BSIM4capbd; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_CAPBS: |
|||
value->rValue = here->BSIM4capbs; |
|||
value->rValue *= here->BSIM4m; |
|||
return(OK); |
|||
case BSIM4_VON: |
|||
value->rValue = here->BSIM4von; |
|||
return(OK); |
|||
case BSIM4_VDSAT: |
|||
value->rValue = here->BSIM4vdsat; |
|||
return(OK); |
|||
case BSIM4_QBS: |
|||
value->rValue = *(ckt->CKTstate0 + here->BSIM4qbs); |
|||
return(OK); |
|||
case BSIM4_QBD: |
|||
value->rValue = *(ckt->CKTstate0 + here->BSIM4qbd); |
|||
return(OK); |
|||
default: |
|||
return(E_BADPARM); |
|||
} |
|||
/* NOTREACHED */ |
|||
} |
|||
|
|||
@ -0,0 +1,899 @@ |
|||
/**** BSIM4.7.0 Released by Darsen Lu 04/08/2011 ****/ |
|||
|
|||
/********** |
|||
* Copyright 2006 Regents of the University of California. All rights reserved. |
|||
* File: b4check.c of BSIM4.7.0. |
|||
* Author: 2000 Weidong Liu |
|||
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu. |
|||
* Authors: 2006- Mohan Dunga, Ali Niknejad, Chenming Hu |
|||
* Authors: 2007- Mohan Dunga, Wenwei Yang, Ali Niknejad, Chenming Hu |
|||
* Project Director: Prof. Chenming Hu. |
|||
* Modified by Xuemei Xi, 04/06/2001. |
|||
* Modified by Xuemei Xi, 10/05/2001. |
|||
* Modified by Xuemei Xi, 11/15/2002. |
|||
* Modified by Xuemei Xi, 05/09/2003. |
|||
* Modified by Xuemei Xi, 03/04/2004. |
|||
* Modified by Xuemei Xi, 07/29/2005. |
|||
* Modified by Mohan Dunga, 12/13/2006 |
|||
* Modified by Mohan Dunga, Wenwei Yang, 05/18/2007. |
|||
* Modified by Wenwei Yang, 07/31/2008 . |
|||
* Modified by Tanvir Morshed, Darsen Lu 03/27/2011 |
|||
**********/ |
|||
|
|||
#include "ngspice/ngspice.h" |
|||
#include "ngspice/cktdefs.h" |
|||
#include "bsim4def.h" |
|||
#include "ngspice/trandefs.h" |
|||
#include "ngspice/const.h" |
|||
#include "ngspice/sperror.h" |
|||
#include "ngspice/devdefs.h" |
|||
#include "ngspice/suffix.h" |
|||
|
|||
int |
|||
BSIM4checkModel( |
|||
BSIM4model *model, |
|||
BSIM4instance *here, |
|||
CKTcircuit *ckt) |
|||
{ |
|||
struct bsim4SizeDependParam *pParam; |
|||
int Fatal_Flag = 0; |
|||
FILE *fplog; |
|||
|
|||
if ((fplog = fopen("bsim4.out", "w")) != NULL) |
|||
{ pParam = here->pParam; |
|||
fprintf(fplog, "BSIM4: Berkeley Short Channel IGFET Model-4\n"); |
|||
fprintf(fplog, "Developed by Xuemei (Jane) Xi, Mohan Dunga, Prof. Ali Niknejad and Prof. Chenming Hu in 2003.\n"); |
|||
fprintf(fplog, "\n"); |
|||
fprintf(fplog, "++++++++++ BSIM4 PARAMETER CHECKING BELOW ++++++++++\n"); |
|||
|
|||
if ((strcmp(model->BSIM4version, "4.7.0")) && (strcmp(model->BSIM4version, "4.70")) && (strcmp(model->BSIM4version, "4.7"))) |
|||
{ fprintf(fplog, "Warning: This model is BSIM4.7.0; you specified a wrong version number.\n"); |
|||
printf("Warning: This model is BSIM4.7.0; you specified a wrong version number.\n"); |
|||
} |
|||
fprintf(fplog, "Model = %s\n", model->BSIM4modName); |
|||
|
|||
|
|||
if ((here->BSIM4rgateMod == 2) || (here->BSIM4rgateMod == 3)) |
|||
{ if ((here->BSIM4trnqsMod == 1) || (here->BSIM4acnqsMod == 1)) |
|||
{ fprintf(fplog, "Warning: You've selected both Rg and charge deficit NQS; select one only.\n"); |
|||
printf("Warning: You've selected both Rg and charge deficit NQS; select one only.\n"); |
|||
} |
|||
} |
|||
|
|||
if (model->BSIM4toxe <= 0.0) |
|||
{ fprintf(fplog, "Fatal: Toxe = %g is not positive.\n", |
|||
model->BSIM4toxe); |
|||
printf("Fatal: Toxe = %g is not positive.\n", model->BSIM4toxe); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (model->BSIM4toxp <= 0.0) |
|||
{ fprintf(fplog, "Fatal: Toxp = %g is not positive.\n", |
|||
model->BSIM4toxp); |
|||
printf("Fatal: Toxp = %g is not positive.\n", model->BSIM4toxp); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (model->BSIM4eot <= 0.0) |
|||
{ fprintf(fplog, "Fatal: EOT = %g is not positive.\n", |
|||
model->BSIM4eot); |
|||
printf("Fatal: EOT = %g is not positive.\n", model->BSIM4eot); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (model->BSIM4epsrgate < 0.0) |
|||
{ fprintf(fplog, "Fatal: Epsrgate = %g is not positive.\n", |
|||
model->BSIM4epsrgate); |
|||
printf("Fatal: Epsrgate = %g is not positive.\n", model->BSIM4epsrgate); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (model->BSIM4epsrsub < 0.0) |
|||
{ fprintf(fplog, "Fatal: Epsrsub = %g is not positive.\n", |
|||
model->BSIM4epsrsub); |
|||
printf("Fatal: Epsrsub = %g is not positive.\n", model->BSIM4epsrsub); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (model->BSIM4easub < 0.0) |
|||
{ fprintf(fplog, "Fatal: Easub = %g is not positive.\n", |
|||
model->BSIM4easub); |
|||
printf("Fatal: Easub = %g is not positive.\n", model->BSIM4easub); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (model->BSIM4ni0sub <= 0.0) |
|||
{ fprintf(fplog, "Fatal: Ni0sub = %g is not positive.\n", |
|||
model->BSIM4ni0sub); |
|||
printf("Fatal: Easub = %g is not positive.\n", model->BSIM4ni0sub); |
|||
Fatal_Flag = 1; |
|||
} |
|||
|
|||
if (model->BSIM4toxm <= 0.0) |
|||
{ fprintf(fplog, "Fatal: Toxm = %g is not positive.\n", |
|||
model->BSIM4toxm); |
|||
printf("Fatal: Toxm = %g is not positive.\n", model->BSIM4toxm); |
|||
Fatal_Flag = 1; |
|||
} |
|||
|
|||
if (model->BSIM4toxref <= 0.0) |
|||
{ fprintf(fplog, "Fatal: Toxref = %g is not positive.\n", |
|||
model->BSIM4toxref); |
|||
printf("Fatal: Toxref = %g is not positive.\n", model->BSIM4toxref); |
|||
Fatal_Flag = 1; |
|||
} |
|||
|
|||
if (pParam->BSIM4lpe0 < -pParam->BSIM4leff) |
|||
{ fprintf(fplog, "Fatal: Lpe0 = %g is less than -Leff.\n", |
|||
pParam->BSIM4lpe0); |
|||
printf("Fatal: Lpe0 = %g is less than -Leff.\n", |
|||
pParam->BSIM4lpe0); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (model->BSIM4lintnoi > pParam->BSIM4leff/2) |
|||
{ fprintf(fplog, "Fatal: Lintnoi = %g is too large - Leff for noise is negative.\n", |
|||
model->BSIM4lintnoi); |
|||
printf("Fatal: Lintnoi = %g is too large - Leff for noise is negative.\n", |
|||
model->BSIM4lintnoi); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (pParam->BSIM4lpeb < -pParam->BSIM4leff) |
|||
{ fprintf(fplog, "Fatal: Lpeb = %g is less than -Leff.\n", |
|||
pParam->BSIM4lpeb); |
|||
printf("Fatal: Lpeb = %g is less than -Leff.\n", |
|||
pParam->BSIM4lpeb); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (pParam->BSIM4ndep <= 0.0) |
|||
{ fprintf(fplog, "Fatal: Ndep = %g is not positive.\n", |
|||
pParam->BSIM4ndep); |
|||
printf("Fatal: Ndep = %g is not positive.\n", |
|||
pParam->BSIM4ndep); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (pParam->BSIM4phi <= 0.0) |
|||
{ fprintf(fplog, "Fatal: Phi = %g is not positive. Please check Phin and Ndep\n", |
|||
pParam->BSIM4phi); |
|||
fprintf(fplog, " Phin = %g Ndep = %g \n", |
|||
pParam->BSIM4phin, pParam->BSIM4ndep); |
|||
printf("Fatal: Phi = %g is not positive. Please check Phin and Ndep\n", |
|||
pParam->BSIM4phi); |
|||
printf(" Phin = %g Ndep = %g \n", |
|||
pParam->BSIM4phin, pParam->BSIM4ndep); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (pParam->BSIM4nsub <= 0.0) |
|||
{ fprintf(fplog, "Fatal: Nsub = %g is not positive.\n", |
|||
pParam->BSIM4nsub); |
|||
printf("Fatal: Nsub = %g is not positive.\n", |
|||
pParam->BSIM4nsub); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (pParam->BSIM4ngate < 0.0) |
|||
{ fprintf(fplog, "Fatal: Ngate = %g is not positive.\n", |
|||
pParam->BSIM4ngate); |
|||
printf("Fatal: Ngate = %g Ngate is not positive.\n", |
|||
pParam->BSIM4ngate); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (pParam->BSIM4ngate > 1.e25) |
|||
{ fprintf(fplog, "Fatal: Ngate = %g is too high.\n", |
|||
pParam->BSIM4ngate); |
|||
printf("Fatal: Ngate = %g Ngate is too high\n", |
|||
pParam->BSIM4ngate); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (pParam->BSIM4xj <= 0.0) |
|||
{ fprintf(fplog, "Fatal: Xj = %g is not positive.\n", |
|||
pParam->BSIM4xj); |
|||
printf("Fatal: Xj = %g is not positive.\n", pParam->BSIM4xj); |
|||
Fatal_Flag = 1; |
|||
} |
|||
|
|||
if (pParam->BSIM4dvt1 < 0.0) |
|||
{ fprintf(fplog, "Fatal: Dvt1 = %g is negative.\n", |
|||
pParam->BSIM4dvt1); |
|||
printf("Fatal: Dvt1 = %g is negative.\n", pParam->BSIM4dvt1); |
|||
Fatal_Flag = 1; |
|||
} |
|||
|
|||
if (pParam->BSIM4dvt1w < 0.0) |
|||
{ fprintf(fplog, "Fatal: Dvt1w = %g is negative.\n", |
|||
pParam->BSIM4dvt1w); |
|||
printf("Fatal: Dvt1w = %g is negative.\n", pParam->BSIM4dvt1w); |
|||
Fatal_Flag = 1; |
|||
} |
|||
|
|||
if (pParam->BSIM4w0 == -pParam->BSIM4weff) |
|||
{ fprintf(fplog, "Fatal: (W0 + Weff) = 0 causing divided-by-zero.\n"); |
|||
printf("Fatal: (W0 + Weff) = 0 causing divided-by-zero.\n"); |
|||
Fatal_Flag = 1; |
|||
} |
|||
|
|||
if (pParam->BSIM4dsub < 0.0) |
|||
{ fprintf(fplog, "Fatal: Dsub = %g is negative.\n", pParam->BSIM4dsub); |
|||
printf("Fatal: Dsub = %g is negative.\n", pParam->BSIM4dsub); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (pParam->BSIM4b1 == -pParam->BSIM4weff) |
|||
{ fprintf(fplog, "Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n"); |
|||
printf("Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n"); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (here->BSIM4u0temp <= 0.0) |
|||
{ fprintf(fplog, "Fatal: u0 at current temperature = %g is not positive.\n", here->BSIM4u0temp); |
|||
printf("Fatal: u0 at current temperature = %g is not positive.\n", |
|||
here->BSIM4u0temp); |
|||
Fatal_Flag = 1; |
|||
} |
|||
|
|||
if (pParam->BSIM4delta < 0.0) |
|||
{ fprintf(fplog, "Fatal: Delta = %g is less than zero.\n", |
|||
pParam->BSIM4delta); |
|||
printf("Fatal: Delta = %g is less than zero.\n", pParam->BSIM4delta); |
|||
Fatal_Flag = 1; |
|||
} |
|||
|
|||
if (here->BSIM4vsattemp <= 0.0) |
|||
{ fprintf(fplog, "Fatal: Vsat at current temperature = %g is not positive.\n", here->BSIM4vsattemp); |
|||
printf("Fatal: Vsat at current temperature = %g is not positive.\n", |
|||
here->BSIM4vsattemp); |
|||
Fatal_Flag = 1; |
|||
} |
|||
|
|||
if (pParam->BSIM4pclm <= 0.0) |
|||
{ fprintf(fplog, "Fatal: Pclm = %g is not positive.\n", pParam->BSIM4pclm); |
|||
printf("Fatal: Pclm = %g is not positive.\n", pParam->BSIM4pclm); |
|||
Fatal_Flag = 1; |
|||
} |
|||
|
|||
if (pParam->BSIM4drout < 0.0) |
|||
{ fprintf(fplog, "Fatal: Drout = %g is negative.\n", pParam->BSIM4drout); |
|||
printf("Fatal: Drout = %g is negative.\n", pParam->BSIM4drout); |
|||
Fatal_Flag = 1; |
|||
} |
|||
|
|||
if (here->BSIM4m < 1.0) |
|||
{ fprintf(fplog, "Fatal: Number of multiplier = %g is smaller than one.\n", here->BSIM4m); |
|||
printf("Fatal: Number of multiplier = %g is smaller than one.\n", here->BSIM4m); |
|||
Fatal_Flag = 1; |
|||
} |
|||
|
|||
if (here->BSIM4nf < 1.0) |
|||
{ fprintf(fplog, "Fatal: Number of finger = %g is smaller than one.\n", here->BSIM4nf); |
|||
printf("Fatal: Number of finger = %g is smaller than one.\n", here->BSIM4nf); |
|||
Fatal_Flag = 1; |
|||
} |
|||
|
|||
if((here->BSIM4sa > 0.0) && (here->BSIM4sb > 0.0) && |
|||
((here->BSIM4nf == 1.0) || ((here->BSIM4nf > 1.0) && (here->BSIM4sd > 0.0))) ) |
|||
{ if (model->BSIM4saref <= 0.0) |
|||
{ fprintf(fplog, "Fatal: SAref = %g is not positive.\n",model->BSIM4saref); |
|||
printf("Fatal: SAref = %g is not positive.\n",model->BSIM4saref); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (model->BSIM4sbref <= 0.0) |
|||
{ fprintf(fplog, "Fatal: SBref = %g is not positive.\n",model->BSIM4sbref); |
|||
printf("Fatal: SBref = %g is not positive.\n",model->BSIM4sbref); |
|||
Fatal_Flag = 1; |
|||
} |
|||
} |
|||
|
|||
if ((here->BSIM4l + model->BSIM4xl) <= model->BSIM4xgl) |
|||
{ fprintf(fplog, "Fatal: The parameter xgl must be smaller than Ldrawn+XL.\n"); |
|||
printf("Fatal: The parameter xgl must be smaller than Ldrawn+XL.\n"); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (here->BSIM4ngcon < 1.0) |
|||
{ fprintf(fplog, "Fatal: The parameter ngcon cannot be smaller than one.\n"); |
|||
printf("Fatal: The parameter ngcon cannot be smaller than one.\n"); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if ((here->BSIM4ngcon != 1.0) && (here->BSIM4ngcon != 2.0)) |
|||
{ here->BSIM4ngcon = 1.0; |
|||
fprintf(fplog, "Warning: Ngcon must be equal to one or two; reset to 1.0.\n"); |
|||
printf("Warning: Ngcon must be equal to one or two; reset to 1.0.\n"); |
|||
} |
|||
|
|||
if (model->BSIM4gbmin < 1.0e-20) |
|||
{ fprintf(fplog, "Warning: Gbmin = %g is too small.\n", |
|||
model->BSIM4gbmin); |
|||
printf("Warning: Gbmin = %g is too small.\n", model->BSIM4gbmin); |
|||
} |
|||
|
|||
/* Check saturation parameters */ |
|||
if (pParam->BSIM4fprout < 0.0) |
|||
{ fprintf(fplog, "Fatal: fprout = %g is negative.\n", |
|||
pParam->BSIM4fprout); |
|||
printf("Fatal: fprout = %g is negative.\n", pParam->BSIM4fprout); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (pParam->BSIM4pdits < 0.0) |
|||
{ fprintf(fplog, "Fatal: pdits = %g is negative.\n", |
|||
pParam->BSIM4pdits); |
|||
printf("Fatal: pdits = %g is negative.\n", pParam->BSIM4pdits); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (model->BSIM4pditsl < 0.0) |
|||
{ fprintf(fplog, "Fatal: pditsl = %g is negative.\n", |
|||
model->BSIM4pditsl); |
|||
printf("Fatal: pditsl = %g is negative.\n", model->BSIM4pditsl); |
|||
Fatal_Flag = 1; |
|||
} |
|||
|
|||
/* Check gate current parameters */ |
|||
if (model->BSIM4igbMod) { |
|||
if (pParam->BSIM4nigbinv <= 0.0) |
|||
{ fprintf(fplog, "Fatal: nigbinv = %g is non-positive.\n", |
|||
pParam->BSIM4nigbinv); |
|||
printf("Fatal: nigbinv = %g is non-positive.\n", pParam->BSIM4nigbinv); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (pParam->BSIM4nigbacc <= 0.0) |
|||
{ fprintf(fplog, "Fatal: nigbacc = %g is non-positive.\n", |
|||
pParam->BSIM4nigbacc); |
|||
printf("Fatal: nigbacc = %g is non-positive.\n", pParam->BSIM4nigbacc); |
|||
Fatal_Flag = 1; |
|||
} |
|||
} |
|||
if (model->BSIM4igcMod) { |
|||
if (pParam->BSIM4nigc <= 0.0) |
|||
{ fprintf(fplog, "Fatal: nigc = %g is non-positive.\n", |
|||
pParam->BSIM4nigc); |
|||
printf("Fatal: nigc = %g is non-positive.\n", pParam->BSIM4nigc); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (pParam->BSIM4poxedge <= 0.0) |
|||
{ fprintf(fplog, "Fatal: poxedge = %g is non-positive.\n", |
|||
pParam->BSIM4poxedge); |
|||
printf("Fatal: poxedge = %g is non-positive.\n", pParam->BSIM4poxedge); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (pParam->BSIM4pigcd <= 0.0) |
|||
{ fprintf(fplog, "Fatal: pigcd = %g is non-positive.\n", |
|||
pParam->BSIM4pigcd); |
|||
printf("Fatal: pigcd = %g is non-positive.\n", pParam->BSIM4pigcd); |
|||
Fatal_Flag = 1; |
|||
} |
|||
} |
|||
|
|||
/* Check capacitance parameters */ |
|||
if (pParam->BSIM4clc < 0.0) |
|||
{ fprintf(fplog, "Fatal: Clc = %g is negative.\n", pParam->BSIM4clc); |
|||
printf("Fatal: Clc = %g is negative.\n", pParam->BSIM4clc); |
|||
Fatal_Flag = 1; |
|||
} |
|||
|
|||
/* Check overlap capacitance parameters */ |
|||
if (pParam->BSIM4ckappas < 0.02) |
|||
{ fprintf(fplog, "Warning: ckappas = %g is too small. Set to 0.02\n", |
|||
pParam->BSIM4ckappas); |
|||
printf("Warning: ckappas = %g is too small.\n", pParam->BSIM4ckappas); |
|||
pParam->BSIM4ckappas = 0.02; |
|||
} |
|||
if (pParam->BSIM4ckappad < 0.02) |
|||
{ fprintf(fplog, "Warning: ckappad = %g is too small. Set to 0.02\n", |
|||
pParam->BSIM4ckappad); |
|||
printf("Warning: ckappad = %g is too small.\n", pParam->BSIM4ckappad); |
|||
pParam->BSIM4ckappad = 0.02; |
|||
} |
|||
|
|||
if (model->BSIM4vtss < 0.0) |
|||
{ fprintf(fplog, "Fatal: Vtss = %g is negative.\n", |
|||
model->BSIM4vtss); |
|||
printf("Fatal: Vtss = %g is negative.\n", |
|||
model->BSIM4vtss); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (model->BSIM4vtsd < 0.0) |
|||
{ fprintf(fplog, "Fatal: Vtsd = %g is negative.\n", |
|||
model->BSIM4vtsd); |
|||
printf("Fatal: Vtsd = %g is negative.\n", |
|||
model->BSIM4vtsd); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (model->BSIM4vtssws < 0.0) |
|||
{ fprintf(fplog, "Fatal: Vtssws = %g is negative.\n", |
|||
model->BSIM4vtssws); |
|||
printf("Fatal: Vtssws = %g is negative.\n", |
|||
model->BSIM4vtssws); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (model->BSIM4vtsswd < 0.0) |
|||
{ fprintf(fplog, "Fatal: Vtsswd = %g is negative.\n", |
|||
model->BSIM4vtsswd); |
|||
printf("Fatal: Vtsswd = %g is negative.\n", |
|||
model->BSIM4vtsswd); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (model->BSIM4vtsswgs < 0.0) |
|||
{ fprintf(fplog, "Fatal: Vtsswgs = %g is negative.\n", |
|||
model->BSIM4vtsswgs); |
|||
printf("Fatal: Vtsswgs = %g is negative.\n", |
|||
model->BSIM4vtsswgs); |
|||
Fatal_Flag = 1; |
|||
} |
|||
if (model->BSIM4vtsswgd < 0.0) |
|||
{ fprintf(fplog, "Fatal: Vtsswgd = %g is negative.\n", |
|||
model->BSIM4vtsswgd); |
|||
printf("Fatal: Vtsswgd = %g is negative.\n", |
|||
model->BSIM4vtsswgd); |
|||
Fatal_Flag = 1; |
|||
} |
|||
|
|||
|
|||
if (model->BSIM4paramChk ==1) |
|||
{ |
|||
/* Check L and W parameters */ |
|||
if (pParam->BSIM4leff <= 1.0e-9) |
|||
{ fprintf(fplog, "Warning: Leff = %g <= 1.0e-9. Recommended Leff >= 1e-8 \n", |
|||
pParam->BSIM4leff); |
|||
printf("Warning: Leff = %g <= 1.0e-9. Recommended Leff >= 1e-8 \n", |
|||
pParam->BSIM4leff); |
|||
} |
|||
|
|||
if (pParam->BSIM4leffCV <= 1.0e-9) |
|||
{ fprintf(fplog, "Warning: Leff for CV = %g <= 1.0e-9. Recommended LeffCV >=1e-8 \n", |
|||
pParam->BSIM4leffCV); |
|||
printf("Warning: Leff for CV = %g <= 1.0e-9. Recommended LeffCV >=1e-8 \n", |
|||
pParam->BSIM4leffCV); |
|||
} |
|||
|
|||
if (pParam->BSIM4weff <= 1.0e-9) |
|||
{ fprintf(fplog, "Warning: Weff = %g <= 1.0e-9. Recommended Weff >=1e-7 \n", |
|||
pParam->BSIM4weff); |
|||
printf("Warning: Weff = %g <= 1.0e-9. Recommended Weff >=1e-7 \n", |
|||
pParam->BSIM4weff); |
|||
} |
|||
|
|||
if (pParam->BSIM4weffCV <= 1.0e-9) |
|||
{ fprintf(fplog, "Warning: Weff for CV = %g <= 1.0e-9. Recommended WeffCV >= 1e-7 \n", |
|||
pParam->BSIM4weffCV); |
|||
printf("Warning: Weff for CV = %g <= 1.0e-9. Recommended WeffCV >= 1e-7 \n", |
|||
pParam->BSIM4weffCV); |
|||
} |
|||
|
|||
/* Check threshold voltage parameters */ |
|||
if (model->BSIM4toxe < 1.0e-10) |
|||
{ fprintf(fplog, "Warning: Toxe = %g is less than 1A. Recommended Toxe >= 5A\n", |
|||
model->BSIM4toxe); |
|||
printf("Warning: Toxe = %g is less than 1A. Recommended Toxe >= 5A\n", model->BSIM4toxe); |
|||
} |
|||
if (model->BSIM4toxp < 1.0e-10) |
|||
{ fprintf(fplog, "Warning: Toxp = %g is less than 1A. Recommended Toxp >= 5A\n", |
|||
model->BSIM4toxp); |
|||
printf("Warning: Toxp = %g is less than 1A. Recommended Toxp >= 5A\n", model->BSIM4toxp); |
|||
} |
|||
if (model->BSIM4toxm < 1.0e-10) |
|||
{ fprintf(fplog, "Warning: Toxm = %g is less than 1A. Recommended Toxm >= 5A\n", |
|||
model->BSIM4toxm); |
|||
printf("Warning: Toxm = %g is less than 1A. Recommended Toxm >= 5A\n", model->BSIM4toxm); |
|||
} |
|||
|
|||
if (pParam->BSIM4ndep <= 1.0e12) |
|||
{ fprintf(fplog, "Warning: Ndep = %g may be too small.\n", |
|||
pParam->BSIM4ndep); |
|||
printf("Warning: Ndep = %g may be too small.\n", |
|||
pParam->BSIM4ndep); |
|||
} |
|||
else if (pParam->BSIM4ndep >= 1.0e21) |
|||
{ fprintf(fplog, "Warning: Ndep = %g may be too large.\n", |
|||
pParam->BSIM4ndep); |
|||
printf("Warning: Ndep = %g may be too large.\n", |
|||
pParam->BSIM4ndep); |
|||
} |
|||
|
|||
if (pParam->BSIM4nsub <= 1.0e14) |
|||
{ fprintf(fplog, "Warning: Nsub = %g may be too small.\n", |
|||
pParam->BSIM4nsub); |
|||
printf("Warning: Nsub = %g may be too small.\n", |
|||
pParam->BSIM4nsub); |
|||
} |
|||
else if (pParam->BSIM4nsub >= 1.0e21) |
|||
{ fprintf(fplog, "Warning: Nsub = %g may be too large.\n", |
|||
pParam->BSIM4nsub); |
|||
printf("Warning: Nsub = %g may be too large.\n", |
|||
pParam->BSIM4nsub); |
|||
} |
|||
|
|||
if ((pParam->BSIM4ngate > 0.0) && |
|||
(pParam->BSIM4ngate <= 1.e18)) |
|||
{ fprintf(fplog, "Warning: Ngate = %g is less than 1.E18cm^-3.\n", |
|||
pParam->BSIM4ngate); |
|||
printf("Warning: Ngate = %g is less than 1.E18cm^-3.\n", |
|||
pParam->BSIM4ngate); |
|||
} |
|||
|
|||
if (pParam->BSIM4dvt0 < 0.0) |
|||
{ fprintf(fplog, "Warning: Dvt0 = %g is negative.\n", |
|||
pParam->BSIM4dvt0); |
|||
printf("Warning: Dvt0 = %g is negative.\n", pParam->BSIM4dvt0); |
|||
} |
|||
|
|||
if (fabs(1.0e-8 / (pParam->BSIM4w0 + pParam->BSIM4weff)) > 10.0) |
|||
{ fprintf(fplog, "Warning: (W0 + Weff) may be too small.\n"); |
|||
printf("Warning: (W0 + Weff) may be too small.\n"); |
|||
} |
|||
|
|||
/* Check subthreshold parameters */ |
|||
if (pParam->BSIM4nfactor < 0.0) |
|||
{ fprintf(fplog, "Warning: Nfactor = %g is negative.\n", |
|||
pParam->BSIM4nfactor); |
|||
printf("Warning: Nfactor = %g is negative.\n", pParam->BSIM4nfactor); |
|||
} |
|||
if (pParam->BSIM4cdsc < 0.0) |
|||
{ fprintf(fplog, "Warning: Cdsc = %g is negative.\n", |
|||
pParam->BSIM4cdsc); |
|||
printf("Warning: Cdsc = %g is negative.\n", pParam->BSIM4cdsc); |
|||
} |
|||
if (pParam->BSIM4cdscd < 0.0) |
|||
{ fprintf(fplog, "Warning: Cdscd = %g is negative.\n", |
|||
pParam->BSIM4cdscd); |
|||
printf("Warning: Cdscd = %g is negative.\n", pParam->BSIM4cdscd); |
|||
} |
|||
/* Check DIBL parameters */ |
|||
if (here->BSIM4eta0 < 0.0) |
|||
{ fprintf(fplog, "Warning: Eta0 = %g is negative.\n", |
|||
here->BSIM4eta0); |
|||
printf("Warning: Eta0 = %g is negative.\n", here->BSIM4eta0); |
|||
} |
|||
|
|||
/* Check Abulk parameters */ |
|||
if (fabs(1.0e-8 / (pParam->BSIM4b1 + pParam->BSIM4weff)) > 10.0) |
|||
{ fprintf(fplog, "Warning: (B1 + Weff) may be too small.\n"); |
|||
printf("Warning: (B1 + Weff) may be too small.\n"); |
|||
} |
|||
|
|||
|
|||
/* Check Saturation parameters */ |
|||
if (pParam->BSIM4a2 < 0.01) |
|||
{ fprintf(fplog, "Warning: A2 = %g is too small. Set to 0.01.\n", pParam->BSIM4a2); |
|||
printf("Warning: A2 = %g is too small. Set to 0.01.\n", |
|||
pParam->BSIM4a2); |
|||
pParam->BSIM4a2 = 0.01; |
|||
} |
|||
else if (pParam->BSIM4a2 > 1.0) |
|||
{ fprintf(fplog, "Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n", |
|||
pParam->BSIM4a2); |
|||
printf("Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n", |
|||
pParam->BSIM4a2); |
|||
pParam->BSIM4a2 = 1.0; |
|||
pParam->BSIM4a1 = 0.0; |
|||
} |
|||
|
|||
if (pParam->BSIM4prwg < 0.0) |
|||
{ fprintf(fplog, "Warning: Prwg = %g is negative. Set to zero.\n", |
|||
pParam->BSIM4prwg); |
|||
printf("Warning: Prwg = %g is negative. Set to zero.\n", |
|||
pParam->BSIM4prwg); |
|||
pParam->BSIM4prwg = 0.0; |
|||
} |
|||
|
|||
if (pParam->BSIM4rdsw < 0.0) |
|||
{ fprintf(fplog, "Warning: Rdsw = %g is negative. Set to zero.\n", |
|||
pParam->BSIM4rdsw); |
|||
printf("Warning: Rdsw = %g is negative. Set to zero.\n", |
|||
pParam->BSIM4rdsw); |
|||
pParam->BSIM4rdsw = 0.0; |
|||
pParam->BSIM4rds0 = 0.0; |
|||
} |
|||
|
|||
if (pParam->BSIM4rds0 < 0.0) |
|||
{ fprintf(fplog, "Warning: Rds at current temperature = %g is negative. Set to zero.\n", |
|||
pParam->BSIM4rds0); |
|||
printf("Warning: Rds at current temperature = %g is negative. Set to zero.\n", |
|||
pParam->BSIM4rds0); |
|||
pParam->BSIM4rds0 = 0.0; |
|||
} |
|||
|
|||
if (pParam->BSIM4rdswmin < 0.0) |
|||
{ fprintf(fplog, "Warning: Rdswmin at current temperature = %g is negative. Set to zero.\n", |
|||
pParam->BSIM4rdswmin); |
|||
printf("Warning: Rdswmin at current temperature = %g is negative. Set to zero.\n", |
|||
pParam->BSIM4rdswmin); |
|||
pParam->BSIM4rdswmin = 0.0; |
|||
} |
|||
|
|||
if (pParam->BSIM4pscbe2 <= 0.0) |
|||
{ fprintf(fplog, "Warning: Pscbe2 = %g is not positive.\n", |
|||
pParam->BSIM4pscbe2); |
|||
printf("Warning: Pscbe2 = %g is not positive.\n", pParam->BSIM4pscbe2); |
|||
} |
|||
|
|||
if (pParam->BSIM4vsattemp < 1.0e3) |
|||
{ fprintf(fplog, "Warning: Vsat at current temperature = %g may be too small.\n", pParam->BSIM4vsattemp); |
|||
printf("Warning: Vsat at current temperature = %g may be too small.\n", pParam->BSIM4vsattemp); |
|||
} |
|||
|
|||
if((model->BSIM4lambdaGiven) && (pParam->BSIM4lambda > 0.0) ) |
|||
{ |
|||
if (pParam->BSIM4lambda > 1.0e-9) |
|||
{ fprintf(fplog, "Warning: Lambda = %g may be too large.\n", pParam->BSIM4lambda); |
|||
printf("Warning: Lambda = %g may be too large.\n", pParam->BSIM4lambda); |
|||
} |
|||
} |
|||
|
|||
if((model->BSIM4vtlGiven) && (pParam->BSIM4vtl > 0.0) ) |
|||
{ |
|||
if (pParam->BSIM4vtl < 6.0e4) |
|||
{ fprintf(fplog, "Warning: Thermal velocity vtl = %g may be too small.\n", pParam->BSIM4vtl); |
|||
printf("Warning: Thermal velocity vtl = %g may be too small.\n", pParam->BSIM4vtl); |
|||
} |
|||
|
|||
if (pParam->BSIM4xn < 3.0) |
|||
{ fprintf(fplog, "Warning: back scattering coeff xn = %g is too small.\n", pParam->BSIM4xn); |
|||
printf("Warning: back scattering coeff xn = %g is too small. Reset to 3.0 \n", pParam->BSIM4xn); |
|||
pParam->BSIM4xn = 3.0; |
|||
} |
|||
|
|||
if (model->BSIM4lc < 0.0) |
|||
{ fprintf(fplog, "Warning: back scattering coeff lc = %g is too small.\n", model->BSIM4lc); |
|||
printf("Warning: back scattering coeff lc = %g is too small. Reset to 0.0\n", model->BSIM4lc); |
|||
pParam->BSIM4lc = 0.0; |
|||
} |
|||
} |
|||
|
|||
if (pParam->BSIM4pdibl1 < 0.0) |
|||
{ fprintf(fplog, "Warning: Pdibl1 = %g is negative.\n", |
|||
pParam->BSIM4pdibl1); |
|||
printf("Warning: Pdibl1 = %g is negative.\n", pParam->BSIM4pdibl1); |
|||
} |
|||
if (pParam->BSIM4pdibl2 < 0.0) |
|||
{ fprintf(fplog, "Warning: Pdibl2 = %g is negative.\n", |
|||
pParam->BSIM4pdibl2); |
|||
printf("Warning: Pdibl2 = %g is negative.\n", pParam->BSIM4pdibl2); |
|||
} |
|||
|
|||
/* Check stress effect parameters */ |
|||
if((here->BSIM4sa > 0.0) && (here->BSIM4sb > 0.0) && |
|||
((here->BSIM4nf == 1.0) || ((here->BSIM4nf > 1.0) && (here->BSIM4sd > 0.0))) ) |
|||
{ if (model->BSIM4lodk2 <= 0.0) |
|||
{ fprintf(fplog, "Warning: LODK2 = %g is not positive.\n",model->BSIM4lodk2); |
|||
printf("Warning: LODK2 = %g is not positive.\n",model->BSIM4lodk2); |
|||
} |
|||
if (model->BSIM4lodeta0 <= 0.0) |
|||
{ fprintf(fplog, "Warning: LODETA0 = %g is not positive.\n",model->BSIM4lodeta0); |
|||
printf("Warning: LODETA0 = %g is not positive.\n",model->BSIM4lodeta0); |
|||
} |
|||
} |
|||
|
|||
/* Check gate resistance parameters */ |
|||
if (here->BSIM4rgateMod == 1) |
|||
{ if (model->BSIM4rshg <= 0.0) |
|||
printf("Warning: rshg should be positive for rgateMod = 1.\n"); |
|||
} |
|||
else if (here->BSIM4rgateMod == 2) |
|||
{ if (model->BSIM4rshg <= 0.0) |
|||
printf("Warning: rshg <= 0.0 for rgateMod = 2.\n"); |
|||
else if (pParam->BSIM4xrcrg1 <= 0.0) |
|||
printf("Warning: xrcrg1 <= 0.0 for rgateMod = 2.\n"); |
|||
} |
|||
if (here->BSIM4rgateMod == 3) |
|||
{ if (model->BSIM4rshg <= 0.0) |
|||
printf("Warning: rshg should be positive for rgateMod = 3.\n"); |
|||
else if (pParam->BSIM4xrcrg1 <= 0.0) |
|||
printf("Warning: xrcrg1 should be positive for rgateMod = 3.\n"); |
|||
} |
|||
|
|||
/* Check capacitance parameters */ |
|||
if (pParam->BSIM4noff < 0.1) |
|||
{ fprintf(fplog, "Warning: Noff = %g is too small.\n", |
|||
pParam->BSIM4noff); |
|||
printf("Warning: Noff = %g is too small.\n", pParam->BSIM4noff); |
|||
} |
|||
|
|||
if (pParam->BSIM4voffcv < -0.5) |
|||
{ fprintf(fplog, "Warning: Voffcv = %g is too small.\n", |
|||
pParam->BSIM4voffcv); |
|||
printf("Warning: Voffcv = %g is too small.\n", pParam->BSIM4voffcv); |
|||
} |
|||
if (pParam->BSIM4moin < 5.0) |
|||
{ fprintf(fplog, "Warning: Moin = %g is too small.\n", |
|||
pParam->BSIM4moin); |
|||
printf("Warning: Moin = %g is too small.\n", pParam->BSIM4moin); |
|||
} |
|||
if (pParam->BSIM4moin > 25.0) |
|||
{ fprintf(fplog, "Warning: Moin = %g is too large.\n", |
|||
pParam->BSIM4moin); |
|||
printf("Warning: Moin = %g is too large.\n", pParam->BSIM4moin); |
|||
} |
|||
if(model->BSIM4capMod ==2) { |
|||
if (pParam->BSIM4acde < 0.1) |
|||
{ fprintf(fplog, "Warning: Acde = %g is too small.\n", |
|||
pParam->BSIM4acde); |
|||
printf("Warning: Acde = %g is too small.\n", pParam->BSIM4acde); |
|||
} |
|||
if (pParam->BSIM4acde > 1.6) |
|||
{ fprintf(fplog, "Warning: Acde = %g is too large.\n", |
|||
pParam->BSIM4acde); |
|||
printf("Warning: Acde = %g is too large.\n", pParam->BSIM4acde); |
|||
} |
|||
} |
|||
|
|||
/* Check overlap capacitance parameters */ |
|||
if (model->BSIM4cgdo < 0.0) |
|||
{ fprintf(fplog, "Warning: cgdo = %g is negative. Set to zero.\n", model->BSIM4cgdo); |
|||
printf("Warning: cgdo = %g is negative. Set to zero.\n", model->BSIM4cgdo); |
|||
model->BSIM4cgdo = 0.0; |
|||
} |
|||
if (model->BSIM4cgso < 0.0) |
|||
{ fprintf(fplog, "Warning: cgso = %g is negative. Set to zero.\n", model->BSIM4cgso); |
|||
printf("Warning: cgso = %g is negative. Set to zero.\n", model->BSIM4cgso); |
|||
model->BSIM4cgso = 0.0; |
|||
} |
|||
if (model->BSIM4cgbo < 0.0) |
|||
{ fprintf(fplog, "Warning: cgbo = %g is negative. Set to zero.\n", model->BSIM4cgbo); |
|||
printf("Warning: cgbo = %g is negative. Set to zero.\n", model->BSIM4cgbo); |
|||
model->BSIM4cgbo = 0.0; |
|||
} |
|||
|
|||
/* v4.7 */ |
|||
if (model->BSIM4tnoiMod == 1 || model->BSIM4tnoiMod == 2) { |
|||
if (model->BSIM4tnoia < 0.0) { |
|||
fprintf(fplog, "Warning: tnoia = %g is negative. Set to zero.\n", model->BSIM4tnoia); |
|||
printf("Warning: tnoia = %g is negative. Set to zero.\n", model->BSIM4tnoia); |
|||
model->BSIM4tnoia = 0.0; |
|||
} |
|||
if (model->BSIM4tnoib < 0.0) { |
|||
fprintf(fplog, "Warning: tnoib = %g is negative. Set to zero.\n", model->BSIM4tnoib); |
|||
printf("Warning: tnoib = %g is negative. Set to zero.\n", model->BSIM4tnoib); |
|||
model->BSIM4tnoib = 0.0; |
|||
} |
|||
if (model->BSIM4rnoia < 0.0) { |
|||
fprintf(fplog, "Warning: rnoia = %g is negative. Set to zero.\n", model->BSIM4rnoia); |
|||
printf("Warning: rnoia = %g is negative. Set to zero.\n", model->BSIM4rnoia); |
|||
model->BSIM4rnoia = 0.0; |
|||
} |
|||
if (model->BSIM4rnoib < 0.0) { |
|||
fprintf(fplog, "Warning: rnoib = %g is negative. Set to zero.\n", model->BSIM4rnoib); |
|||
printf("Warning: rnoib = %g is negative. Set to zero.\n", model->BSIM4rnoib); |
|||
model->BSIM4rnoib = 0.0; |
|||
} |
|||
} |
|||
|
|||
/* v4.7 */ |
|||
if (model->BSIM4tnoiMod == 2) { |
|||
if (model->BSIM4tnoic < 0.0) { |
|||
fprintf(fplog, "Warning: tnoic = %g is negative. Set to zero.\n", model->BSIM4tnoic); |
|||
printf("Warning: tnoic = %g is negative. Set to zero.\n", model->BSIM4tnoic); |
|||
model->BSIM4tnoic = 0.0; |
|||
} |
|||
if (model->BSIM4rnoic < 0.0) { |
|||
fprintf(fplog, "Warning: rnoic = %g is negative. Set to zero.\n", model->BSIM4rnoic); |
|||
printf("Warning: rnoic = %g is negative. Set to zero.\n", model->BSIM4rnoic); |
|||
model->BSIM4rnoic = 0.0; |
|||
} |
|||
} |
|||
|
|||
/* Limits of Njs and Njd modified in BSIM4.7 */ |
|||
if (model->BSIM4SjctEmissionCoeff < 0.1) { |
|||
fprintf(fplog, "Warning: Njs = %g is less than 0.1. Setting Njs to 0.1.\n", model->BSIM4SjctEmissionCoeff); |
|||
printf("Warning: Njs = %g is less than 0.1. Setting Njs to 0.1.\n", model->BSIM4SjctEmissionCoeff); |
|||
model->BSIM4SjctEmissionCoeff = 0.1; |
|||
} |
|||
else if (model->BSIM4SjctEmissionCoeff < 0.7) { |
|||
fprintf(fplog, "Warning: Njs = %g is less than 0.7.\n", model->BSIM4SjctEmissionCoeff); |
|||
printf("Warning: Njs = %g is less than 0.7.\n", model->BSIM4SjctEmissionCoeff); |
|||
} |
|||
if (model->BSIM4DjctEmissionCoeff < 0.1) { |
|||
fprintf(fplog, "Warning: Njd = %g is less than 0.1. Setting Njd to 0.1.\n", model->BSIM4DjctEmissionCoeff); |
|||
printf("Warning: Njd = %g is less than 0.1. Setting Njd to 0.1.\n", model->BSIM4DjctEmissionCoeff); |
|||
model->BSIM4DjctEmissionCoeff = 0.1; |
|||
} |
|||
else if (model->BSIM4DjctEmissionCoeff < 0.7) { |
|||
fprintf(fplog, "Warning: Njd = %g is less than 0.7.\n", model->BSIM4DjctEmissionCoeff); |
|||
printf("Warning: Njd = %g is less than 0.7.\n", model->BSIM4DjctEmissionCoeff); |
|||
} |
|||
|
|||
if (model->BSIM4njtsstemp < 0.0) |
|||
{ fprintf(fplog, "Warning: Njts = %g is negative at temperature = %g.\n", |
|||
model->BSIM4njtsstemp, ckt->CKTtemp); |
|||
printf("Warning: Njts = %g is negative at temperature = %g.\n", |
|||
model->BSIM4njtsstemp, ckt->CKTtemp); |
|||
} |
|||
if (model->BSIM4njtsswstemp < 0.0) |
|||
{ fprintf(fplog, "Warning: Njtssw = %g is negative at temperature = %g.\n", |
|||
model->BSIM4njtsswstemp, ckt->CKTtemp); |
|||
printf("Warning: Njtssw = %g is negative at temperature = %g.\n", |
|||
model->BSIM4njtsswstemp, ckt->CKTtemp); |
|||
} |
|||
if (model->BSIM4njtsswgstemp < 0.0) |
|||
{ fprintf(fplog, "Warning: Njtsswg = %g is negative at temperature = %g.\n", |
|||
model->BSIM4njtsswgstemp, ckt->CKTtemp); |
|||
printf("Warning: Njtsswg = %g is negative at temperature = %g.\n", |
|||
model->BSIM4njtsswgstemp, ckt->CKTtemp); |
|||
} |
|||
|
|||
if (model->BSIM4njtsdGiven && model->BSIM4njtsdtemp < 0.0) |
|||
{ fprintf(fplog, "Warning: Njtsd = %g is negative at temperature = %g.\n", |
|||
model->BSIM4njtsdtemp, ckt->CKTtemp); |
|||
printf("Warning: Njtsd = %g is negative at temperature = %g.\n", |
|||
model->BSIM4njtsdtemp, ckt->CKTtemp); |
|||
} |
|||
if (model->BSIM4njtsswdGiven && model->BSIM4njtsswdtemp < 0.0) |
|||
{ fprintf(fplog, "Warning: Njtsswd = %g is negative at temperature = %g.\n", |
|||
model->BSIM4njtsswdtemp, ckt->CKTtemp); |
|||
printf("Warning: Njtsswd = %g is negative at temperature = %g.\n", |
|||
model->BSIM4njtsswdtemp, ckt->CKTtemp); |
|||
} |
|||
if (model->BSIM4njtsswgdGiven && model->BSIM4njtsswgdtemp < 0.0) |
|||
{ fprintf(fplog, "Warning: Njtsswgd = %g is negative at temperature = %g.\n", |
|||
model->BSIM4njtsswgdtemp, ckt->CKTtemp); |
|||
printf("Warning: Njtsswgd = %g is negative at temperature = %g.\n", |
|||
model->BSIM4njtsswgdtemp, ckt->CKTtemp); |
|||
} |
|||
|
|||
if (model->BSIM4ntnoi < 0.0) |
|||
{ fprintf(fplog, "Warning: ntnoi = %g is negative. Set to zero.\n", model->BSIM4ntnoi); |
|||
printf("Warning: ntnoi = %g is negative. Set to zero.\n", model->BSIM4ntnoi); |
|||
model->BSIM4ntnoi = 0.0; |
|||
} |
|||
|
|||
/* diode model */ |
|||
if (model->BSIM4SbulkJctBotGradingCoeff >= 0.99) |
|||
{ fprintf(fplog, "Warning: MJS = %g is too big. Set to 0.99.\n", model->BSIM4SbulkJctBotGradingCoeff); |
|||
printf("Warning: MJS = %g is too big. Set to 0.99.\n", model->BSIM4SbulkJctBotGradingCoeff); |
|||
model->BSIM4SbulkJctBotGradingCoeff = 0.99; |
|||
} |
|||
if (model->BSIM4SbulkJctSideGradingCoeff >= 0.99) |
|||
{ fprintf(fplog, "Warning: MJSWS = %g is too big. Set to 0.99.\n", model->BSIM4SbulkJctSideGradingCoeff); |
|||
printf("Warning: MJSWS = %g is too big. Set to 0.99.\n", model->BSIM4SbulkJctSideGradingCoeff); |
|||
model->BSIM4SbulkJctSideGradingCoeff = 0.99; |
|||
} |
|||
if (model->BSIM4SbulkJctGateSideGradingCoeff >= 0.99) |
|||
{ fprintf(fplog, "Warning: MJSWGS = %g is too big. Set to 0.99.\n", model->BSIM4SbulkJctGateSideGradingCoeff); |
|||
printf("Warning: MJSWGS = %g is too big. Set to 0.99.\n", model->BSIM4SbulkJctGateSideGradingCoeff); |
|||
model->BSIM4SbulkJctGateSideGradingCoeff = 0.99; |
|||
} |
|||
|
|||
if (model->BSIM4DbulkJctBotGradingCoeff >= 0.99) |
|||
{ fprintf(fplog, "Warning: MJD = %g is too big. Set to 0.99.\n", model->BSIM4DbulkJctBotGradingCoeff); |
|||
printf("Warning: MJD = %g is too big. Set to 0.99.\n", model->BSIM4DbulkJctBotGradingCoeff); |
|||
model->BSIM4DbulkJctBotGradingCoeff = 0.99; |
|||
} |
|||
if (model->BSIM4DbulkJctSideGradingCoeff >= 0.99) |
|||
{ fprintf(fplog, "Warning: MJSWD = %g is too big. Set to 0.99.\n", model->BSIM4DbulkJctSideGradingCoeff); |
|||
printf("Warning: MJSWD = %g is too big. Set to 0.99.\n", model->BSIM4DbulkJctSideGradingCoeff); |
|||
model->BSIM4DbulkJctSideGradingCoeff = 0.99; |
|||
} |
|||
if (model->BSIM4DbulkJctGateSideGradingCoeff >= 0.99) |
|||
{ fprintf(fplog, "Warning: MJSWGD = %g is too big. Set to 0.99.\n", model->BSIM4DbulkJctGateSideGradingCoeff); |
|||
printf("Warning: MJSWGD = %g is too big. Set to 0.99.\n", model->BSIM4DbulkJctGateSideGradingCoeff); |
|||
model->BSIM4DbulkJctGateSideGradingCoeff = 0.99; |
|||
} |
|||
if (model->BSIM4wpemod == 1) |
|||
{ |
|||
if (model->BSIM4scref <= 0.0) |
|||
{ fprintf(fplog, "Warning: SCREF = %g is not positive. Set to 1e-6.\n", model->BSIM4scref); |
|||
printf("Warning: SCREF = %g is not positive. Set to 1e-6.\n", model->BSIM4scref); |
|||
model->BSIM4scref = 1e-6; |
|||
} |
|||
/*Move these checks to temp.c for sceff calculation*/ |
|||
/* |
|||
if (here->BSIM4sca < 0.0) |
|||
{ fprintf(fplog, "Warning: SCA = %g is negative. Set to 0.0.\n", here->BSIM4sca); |
|||
printf("Warning: SCA = %g is negative. Set to 0.0.\n", here->BSIM4sca); |
|||
here->BSIM4sca = 0.0; |
|||
} |
|||
if (here->BSIM4scb < 0.0) |
|||
{ fprintf(fplog, "Warning: SCB = %g is negative. Set to 0.0.\n", here->BSIM4scb); |
|||
printf("Warning: SCB = %g is negative. Set to 0.0.\n", here->BSIM4scb); |
|||
here->BSIM4scb = 0.0; |
|||
} |
|||
if (here->BSIM4scc < 0.0) |
|||
{ fprintf(fplog, "Warning: SCC = %g is negative. Set to 0.0.\n", here->BSIM4scc); |
|||
printf("Warning: SCC = %g is negative. Set to 0.0.\n", here->BSIM4scc); |
|||
here->BSIM4scc = 0.0; |
|||
} |
|||
if (here->BSIM4sc < 0.0) |
|||
{ fprintf(fplog, "Warning: SC = %g is negative. Set to 0.0.\n", here->BSIM4sc); |
|||
printf("Warning: SC = %g is negative. Set to 0.0.\n", here->BSIM4sc); |
|||
here->BSIM4sc = 0.0; |
|||
} |
|||
*/ |
|||
|
|||
} |
|||
}/* loop for the parameter check for warning messages */ |
|||
fclose(fplog); |
|||
} |
|||
else |
|||
{ fprintf(stderr, "Warning: Can't open log file. Parameter checking skipped.\n"); |
|||
} |
|||
|
|||
return(Fatal_Flag); |
|||
} |
|||
|
|||
@ -0,0 +1,200 @@ |
|||
/**** BSIM4.7.0 Released by Darsen Lu 04/08/2011 ****/ |
|||
|
|||
/********** |
|||
* Copyright 2006 Regents of the University of California. All rights reserved. |
|||
* File: b4cvtest.c of BSIM4.7.0. |
|||
* Author: 2000 Weidong Liu |
|||
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu. |
|||
* Authors: 2006- Mohan Dunga, Ali Niknejad, Chenming Hu |
|||
* Authors: 2007- Mohan Dunga, Wenwei Yang, Ali Niknejad, Chenming Hu |
|||
* Project Director: Prof. Chenming Hu. |
|||
* Modified by Xuemei Xi, 04/06/2001. |
|||
* Modified by Xuemei Xi, 10/05/2001. |
|||
* Modified by Xuemei Xi, 05/09/2003. |
|||
**********/ |
|||
|
|||
#include "ngspice/ngspice.h" |
|||
#include "ngspice/cktdefs.h" |
|||
#include "bsim4def.h" |
|||
#include "ngspice/trandefs.h" |
|||
#include "ngspice/const.h" |
|||
#include "ngspice/devdefs.h" |
|||
#include "ngspice/sperror.h" |
|||
#include "ngspice/suffix.h" |
|||
|
|||
|
|||
int |
|||
BSIM4convTest( |
|||
GENmodel *inModel, |
|||
CKTcircuit *ckt) |
|||
{ |
|||
BSIM4model *model = (BSIM4model*)inModel; |
|||
BSIM4instance *here; |
|||
double delvbd, delvbs, delvds, delvgd, delvgs; |
|||
double delvdbd, delvsbs; |
|||
double delvbd_jct, delvbs_jct; |
|||
double vds, vgs, vgd, vgdo, vbs, vbd; |
|||
double vdbd, vdbs, vsbs; |
|||
double cbhat, cdhat, Idtot, Ibtot; |
|||
double vses, vdes, vdedo, delvses, delvded, delvdes; |
|||
double Isestot, cseshat, Idedtot, cdedhat; |
|||
double Igstot, cgshat, Igdtot, cgdhat, Igbtot, cgbhat; |
|||
double tol0, tol1, tol2, tol3, tol4, tol5, tol6; |
|||
|
|||
for (; model != NULL; model = model->BSIM4nextModel) |
|||
{ for (here = model->BSIM4instances; here != NULL ; |
|||
here=here->BSIM4nextInstance) |
|||
{ |
|||
vds = model->BSIM4type |
|||
* (*(ckt->CKTrhsOld + here->BSIM4dNodePrime) |
|||
- *(ckt->CKTrhsOld + here->BSIM4sNodePrime)); |
|||
vgs = model->BSIM4type |
|||
* (*(ckt->CKTrhsOld + here->BSIM4gNodePrime) |
|||
- *(ckt->CKTrhsOld + here->BSIM4sNodePrime)); |
|||
vbs = model->BSIM4type |
|||
* (*(ckt->CKTrhsOld + here->BSIM4bNodePrime) |
|||
- *(ckt->CKTrhsOld + here->BSIM4sNodePrime)); |
|||
vdbs = model->BSIM4type |
|||
* (*(ckt->CKTrhsOld + here->BSIM4dbNode) |
|||
- *(ckt->CKTrhsOld + here->BSIM4sNodePrime)); |
|||
vsbs = model->BSIM4type |
|||
* (*(ckt->CKTrhsOld + here->BSIM4sbNode) |
|||
- *(ckt->CKTrhsOld + here->BSIM4sNodePrime)); |
|||
vses = model->BSIM4type |
|||
* (*(ckt->CKTrhsOld + here->BSIM4sNode) |
|||
- *(ckt->CKTrhsOld + here->BSIM4sNodePrime)); |
|||
vdes = model->BSIM4type |
|||
* (*(ckt->CKTrhsOld + here->BSIM4dNode) |
|||
- *(ckt->CKTrhsOld + here->BSIM4sNodePrime)); |
|||
|
|||
vgdo = *(ckt->CKTstate0 + here->BSIM4vgs) |
|||
- *(ckt->CKTstate0 + here->BSIM4vds); |
|||
vbd = vbs - vds; |
|||
vdbd = vdbs - vds; |
|||
vgd = vgs - vds; |
|||
|
|||
delvbd = vbd - *(ckt->CKTstate0 + here->BSIM4vbd); |
|||
delvdbd = vdbd - *(ckt->CKTstate0 + here->BSIM4vdbd); |
|||
delvgd = vgd - vgdo; |
|||
|
|||
delvds = vds - *(ckt->CKTstate0 + here->BSIM4vds); |
|||
delvgs = vgs - *(ckt->CKTstate0 + here->BSIM4vgs); |
|||
delvbs = vbs - *(ckt->CKTstate0 + here->BSIM4vbs); |
|||
delvsbs = vsbs - *(ckt->CKTstate0 + here->BSIM4vsbs); |
|||
|
|||
delvses = vses - (*(ckt->CKTstate0 + here->BSIM4vses)); |
|||
vdedo = *(ckt->CKTstate0 + here->BSIM4vdes) |
|||
- *(ckt->CKTstate0 + here->BSIM4vds); |
|||
delvdes = vdes - *(ckt->CKTstate0 + here->BSIM4vdes); |
|||
delvded = vdes - vds - vdedo; |
|||
|
|||
delvbd_jct = (!here->BSIM4rbodyMod) ? delvbd : delvdbd; |
|||
delvbs_jct = (!here->BSIM4rbodyMod) ? delvbs : delvsbs; |
|||
|
|||
if (here->BSIM4mode >= 0) |
|||
{ Idtot = here->BSIM4cd + here->BSIM4csub - here->BSIM4cbd |
|||
+ here->BSIM4Igidl; |
|||
cdhat = Idtot - here->BSIM4gbd * delvbd_jct |
|||
+ (here->BSIM4gmbs + here->BSIM4gbbs + here->BSIM4ggidlb) * delvbs |
|||
+ (here->BSIM4gm + here->BSIM4gbgs + here->BSIM4ggidlg) * delvgs |
|||
+ (here->BSIM4gds + here->BSIM4gbds + here->BSIM4ggidld) * delvds; |
|||
|
|||
Igstot = here->BSIM4Igs + here->BSIM4Igcs; |
|||
cgshat = Igstot + (here->BSIM4gIgsg + here->BSIM4gIgcsg) * delvgs |
|||
+ here->BSIM4gIgcsd * delvds + here->BSIM4gIgcsb * delvbs; |
|||
|
|||
Igdtot = here->BSIM4Igd + here->BSIM4Igcd; |
|||
cgdhat = Igdtot + here->BSIM4gIgdg * delvgd + here->BSIM4gIgcdg * delvgs |
|||
+ here->BSIM4gIgcdd * delvds + here->BSIM4gIgcdb * delvbs; |
|||
|
|||
Igbtot = here->BSIM4Igb; |
|||
cgbhat = here->BSIM4Igb + here->BSIM4gIgbg * delvgs + here->BSIM4gIgbd |
|||
* delvds + here->BSIM4gIgbb * delvbs; |
|||
} |
|||
else |
|||
{ Idtot = here->BSIM4cd + here->BSIM4cbd - here->BSIM4Igidl; /* bugfix */ |
|||
cdhat = Idtot + here->BSIM4gbd * delvbd_jct + here->BSIM4gmbs |
|||
* delvbd + here->BSIM4gm * delvgd |
|||
- (here->BSIM4gds + here->BSIM4ggidls) * delvds |
|||
- here->BSIM4ggidlg * delvgs - here->BSIM4ggidlb * delvbs; |
|||
|
|||
Igstot = here->BSIM4Igs + here->BSIM4Igcd; |
|||
cgshat = Igstot + here->BSIM4gIgsg * delvgs + here->BSIM4gIgcdg * delvgd |
|||
- here->BSIM4gIgcdd * delvds + here->BSIM4gIgcdb * delvbd; |
|||
|
|||
Igdtot = here->BSIM4Igd + here->BSIM4Igcs; |
|||
cgdhat = Igdtot + (here->BSIM4gIgdg + here->BSIM4gIgcsg) * delvgd |
|||
- here->BSIM4gIgcsd * delvds + here->BSIM4gIgcsb * delvbd; |
|||
|
|||
Igbtot = here->BSIM4Igb; |
|||
cgbhat = here->BSIM4Igb + here->BSIM4gIgbg * delvgd - here->BSIM4gIgbd |
|||
* delvds + here->BSIM4gIgbb * delvbd; |
|||
} |
|||
|
|||
Isestot = here->BSIM4gstot * (*(ckt->CKTstate0 + here->BSIM4vses)); |
|||
cseshat = Isestot + here->BSIM4gstot * delvses |
|||
+ here->BSIM4gstotd * delvds + here->BSIM4gstotg * delvgs |
|||
+ here->BSIM4gstotb * delvbs; |
|||
|
|||
Idedtot = here->BSIM4gdtot * vdedo; |
|||
cdedhat = Idedtot + here->BSIM4gdtot * delvded |
|||
+ here->BSIM4gdtotd * delvds + here->BSIM4gdtotg * delvgs |
|||
+ here->BSIM4gdtotb * delvbs; |
|||
|
|||
/* |
|||
* Check convergence |
|||
*/ |
|||
|
|||
if ((here->BSIM4off == 0) || (!(ckt->CKTmode & MODEINITFIX))) |
|||
{ tol0 = ckt->CKTreltol * MAX(fabs(cdhat), fabs(Idtot)) |
|||
+ ckt->CKTabstol; |
|||
tol1 = ckt->CKTreltol * MAX(fabs(cseshat), fabs(Isestot)) |
|||
+ ckt->CKTabstol; |
|||
tol2 = ckt->CKTreltol * MAX(fabs(cdedhat), fabs(Idedtot)) |
|||
+ ckt->CKTabstol; |
|||
tol3 = ckt->CKTreltol * MAX(fabs(cgshat), fabs(Igstot)) |
|||
+ ckt->CKTabstol; |
|||
tol4 = ckt->CKTreltol * MAX(fabs(cgdhat), fabs(Igdtot)) |
|||
+ ckt->CKTabstol; |
|||
tol5 = ckt->CKTreltol * MAX(fabs(cgbhat), fabs(Igbtot)) |
|||
+ ckt->CKTabstol; |
|||
|
|||
if ((fabs(cdhat - Idtot) >= tol0) || (fabs(cseshat - Isestot) >= tol1) |
|||
|| (fabs(cdedhat - Idedtot) >= tol2)) |
|||
{ ckt->CKTnoncon++; |
|||
return(OK); |
|||
} |
|||
|
|||
if ((fabs(cgshat - Igstot) >= tol3) || (fabs(cgdhat - Igdtot) >= tol4) |
|||
|| (fabs(cgbhat - Igbtot) >= tol5)) |
|||
{ ckt->CKTnoncon++; |
|||
return(OK); |
|||
} |
|||
|
|||
Ibtot = here->BSIM4cbs + here->BSIM4cbd |
|||
- here->BSIM4Igidl - here->BSIM4Igisl - here->BSIM4csub; |
|||
if (here->BSIM4mode >= 0) |
|||
{ cbhat = Ibtot + here->BSIM4gbd * delvbd_jct |
|||
+ here->BSIM4gbs * delvbs_jct - (here->BSIM4gbbs + here->BSIM4ggidlb) |
|||
* delvbs - (here->BSIM4gbgs + here->BSIM4ggidlg) * delvgs |
|||
- (here->BSIM4gbds + here->BSIM4ggidld) * delvds |
|||
- here->BSIM4ggislg * delvgd - here->BSIM4ggislb* delvbd + here->BSIM4ggisls * delvds ; |
|||
} |
|||
else |
|||
{ cbhat = Ibtot + here->BSIM4gbs * delvbs_jct + here->BSIM4gbd |
|||
* delvbd_jct - (here->BSIM4gbbs + here->BSIM4ggislb) * delvbd |
|||
- (here->BSIM4gbgs + here->BSIM4ggislg) * delvgd |
|||
+ (here->BSIM4gbds + here->BSIM4ggisld - here->BSIM4ggidls) * delvds |
|||
- here->BSIM4ggidlg * delvgs - here->BSIM4ggidlb * delvbs; |
|||
} |
|||
tol6 = ckt->CKTreltol * MAX(fabs(cbhat), |
|||
fabs(Ibtot)) + ckt->CKTabstol; |
|||
if (fabs(cbhat - Ibtot) > tol6) |
|||
{ ckt->CKTnoncon++; |
|||
return(OK); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
return(OK); |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
/**** BSIM4.7.0 Released by Darsen Lu 04/08/2011 ****/ |
|||
|
|||
/********** |
|||
* Copyright 2006 Regents of the University of California. All rights reserved. |
|||
* File: b4del.c of BSIM4.7.0. |
|||
* Author: 2000 Weidong Liu |
|||
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu. |
|||
* Authors: 2006- Mohan Dunga, Ali Niknejad, Chenming Hu |
|||
* Authors: 2007- Mohan Dunga, Wenwei Yang, Ali Niknejad, Chenming Hu |
|||
* Project Director: Prof. Chenming Hu. |
|||
**********/ |
|||
|
|||
#include "ngspice/ngspice.h" |
|||
#include "bsim4def.h" |
|||
#include "ngspice/sperror.h" |
|||
#include "ngspice/gendefs.h" |
|||
#include "ngspice/suffix.h" |
|||
|
|||
|
|||
int |
|||
BSIM4delete( |
|||
GENmodel *inModel, |
|||
IFuid name, |
|||
GENinstance **inInst) |
|||
{ |
|||
BSIM4instance **fast = (BSIM4instance**)inInst; |
|||
BSIM4model *model = (BSIM4model*)inModel; |
|||
BSIM4instance **prev = NULL; |
|||
BSIM4instance *here; |
|||
|
|||
for (; model ; model = model->BSIM4nextModel) |
|||
{ prev = &(model->BSIM4instances); |
|||
for (here = *prev; here ; here = *prev) |
|||
{ if (here->BSIM4name == name || (fast && here==*fast)) |
|||
{ *prev= here->BSIM4nextInstance; |
|||
FREE(here); |
|||
return(OK); |
|||
} |
|||
prev = &(here->BSIM4nextInstance); |
|||
} |
|||
} |
|||
return(E_NODEV); |
|||
} |
|||
@ -0,0 +1,63 @@ |
|||
/**** BSIM4.7.0 Released by Darsen Lu 04/08/2011 ****/ |
|||
|
|||
/********** |
|||
* Copyright 2006 Regents of the University of California. All rights reserved. |
|||
* File: b4dest.c of BSIM4.7.0. |
|||
* Author: 2000 Weidong Liu |
|||
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu. |
|||
* Authors: 2006- Mohan Dunga, Ali Niknejad, Chenming Hu |
|||
* Authors: 2007- Mohan Dunga, Wenwei Yang, Ali Niknejad, Chenming Hu |
|||
* Project Director: Prof. Chenming Hu. |
|||
**********/ |
|||
|
|||
#include "ngspice/ngspice.h" |
|||
#include "bsim4def.h" |
|||
#include "ngspice/suffix.h" |
|||
|
|||
void |
|||
BSIM4destroy( |
|||
GENmodel **inModel) |
|||
{ |
|||
BSIM4model **model = (BSIM4model**)inModel; |
|||
BSIM4instance *here; |
|||
BSIM4instance *prev = NULL; |
|||
BSIM4model *mod = *model; |
|||
BSIM4model *oldmod = NULL; |
|||
|
|||
for (; mod ; mod = mod->BSIM4nextModel) { |
|||
/** added to get rid of link list pSizeDependParamKnot **/ |
|||
struct bsim4SizeDependParam *pParam, *pParamOld=NULL; |
|||
|
|||
pParam = mod->pSizeDependParamKnot; |
|||
|
|||
for (; pParam ; pParam = pParam->pNext) { |
|||
FREE(pParamOld); |
|||
pParamOld = pParam; |
|||
} |
|||
FREE(pParamOld); |
|||
pParam = NULL; |
|||
/** end of extra code **/ |
|||
if(oldmod) { |
|||
FREE(oldmod->BSIM4version); |
|||
FREE(oldmod); |
|||
} |
|||
oldmod = mod; |
|||
prev = (BSIM4instance *)NULL; |
|||
for (here = mod->BSIM4instances; here; here = here->BSIM4nextInstance) { |
|||
if(prev) FREE(prev); |
|||
prev = here; |
|||
} |
|||
if(prev) FREE(prev); |
|||
} |
|||
if(oldmod) { |
|||
#ifdef USE_OMP |
|||
/* free just once for all models */ |
|||
FREE(oldmod->BSIM4InstanceArray); |
|||
#endif |
|||
/* oldmod->BSIM4modName to be freed in INPtabEnd() */ |
|||
FREE(oldmod->BSIM4version); |
|||
FREE(oldmod); |
|||
} |
|||
*model = NULL; |
|||
return; |
|||
} |
|||
@ -0,0 +1,395 @@ |
|||
/**** BSIM4.7.0 Released by Darsen Lu 04/08/2011 ****/ |
|||
|
|||
/********** |
|||
* Copyright 2006 Regents of the University of California. All rights reserved. |
|||
* File: b4geo.c of BSIM4.7.0. |
|||
* Author: 2000 Weidong Liu |
|||
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu. |
|||
* Authors: 2006- Mohan Dunga, Ali Niknejad, Chenming Hu |
|||
* Authors: 2007- Mohan Dunga, Wenwei Yang, Ali Niknejad, Chenming Hu |
|||
* Project Director: Prof. Chenming Hu. |
|||
**********/ |
|||
|
|||
#include "ngspice/ngspice.h" |
|||
#include "bsim4def.h" |
|||
|
|||
|
|||
/* |
|||
* WDLiu: |
|||
* This subrutine is a special module to process the geometry dependent |
|||
* parasitics for BSIM4, which calculates Ps, Pd, As, Ad, and Rs and Rd |
|||
* for multi-fingers and varous GEO and RGEO options. |
|||
*/ |
|||
|
|||
static int |
|||
BSIM4NumFingerDiff( |
|||
double nf, |
|||
int minSD, |
|||
double *nuIntD, double *nuEndD, double *nuIntS, double *nuEndS) |
|||
{ |
|||
int NF; |
|||
NF = (int)nf; |
|||
if ((NF%2) != 0) |
|||
{ *nuEndD = *nuEndS = 1.0; |
|||
*nuIntD = *nuIntS = 2.0 * MAX((nf - 1.0) / 2.0, 0.0); |
|||
} |
|||
else |
|||
{ if (minSD == 1) /* minimize # of source */ |
|||
{ *nuEndD = 2.0; |
|||
*nuIntD = 2.0 * MAX((nf / 2.0 - 1.0), 0.0); |
|||
*nuEndS = 0.0; |
|||
*nuIntS = nf; |
|||
} |
|||
else |
|||
{ *nuEndD = 0.0; |
|||
*nuIntD = nf; |
|||
*nuEndS = 2.0; |
|||
*nuIntS = 2.0 * MAX((nf / 2.0 - 1.0), 0.0); |
|||
} |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
|
|||
int |
|||
BSIM4PAeffGeo( |
|||
double nf, |
|||
int geo, int minSD, |
|||
double Weffcj, double DMCG, double DMCI, double DMDG, |
|||
double *Ps, double *Pd, double *As, double *Ad) |
|||
{ |
|||
double T0, T1, T2; |
|||
double ADiso, ADsha, ADmer, ASiso, ASsha, ASmer; |
|||
double PDiso, PDsha, PDmer, PSiso, PSsha, PSmer; |
|||
double nuIntD = 0.0, nuEndD = 0.0, nuIntS = 0.0, nuEndS = 0.0; |
|||
|
|||
if (geo < 9) /* For geo = 9 and 10, the numbers of S/D diffusions already known */ |
|||
BSIM4NumFingerDiff(nf, minSD, &nuIntD, &nuEndD, &nuIntS, &nuEndS); |
|||
|
|||
T0 = DMCG + DMCI; |
|||
T1 = DMCG + DMCG; |
|||
T2 = DMDG + DMDG; |
|||
|
|||
PSiso = PDiso = T0 + T0 + Weffcj; |
|||
PSsha = PDsha = T1; |
|||
PSmer = PDmer = T2; |
|||
|
|||
ASiso = ADiso = T0 * Weffcj; |
|||
ASsha = ADsha = DMCG * Weffcj; |
|||
ASmer = ADmer = DMDG * Weffcj; |
|||
|
|||
switch(geo) |
|||
{ case 0: |
|||
*Ps = nuEndS * PSiso + nuIntS * PSsha; |
|||
*Pd = nuEndD * PDiso + nuIntD * PDsha; |
|||
*As = nuEndS * ASiso + nuIntS * ASsha; |
|||
*Ad = nuEndD * ADiso + nuIntD * ADsha; |
|||
break; |
|||
case 1: |
|||
*Ps = nuEndS * PSiso + nuIntS * PSsha; |
|||
*Pd = (nuEndD + nuIntD) * PDsha; |
|||
*As = nuEndS * ASiso + nuIntS * ASsha; |
|||
*Ad = (nuEndD + nuIntD) * ADsha; |
|||
break; |
|||
case 2: |
|||
*Ps = (nuEndS + nuIntS) * PSsha; |
|||
*Pd = nuEndD * PDiso + nuIntD * PDsha; |
|||
*As = (nuEndS + nuIntS) * ASsha; |
|||
*Ad = nuEndD * ADiso + nuIntD * ADsha; |
|||
break; |
|||
case 3: |
|||
*Ps = (nuEndS + nuIntS) * PSsha; |
|||
*Pd = (nuEndD + nuIntD) * PDsha; |
|||
*As = (nuEndS + nuIntS) * ASsha; |
|||
*Ad = (nuEndD + nuIntD) * ADsha; |
|||
break; |
|||
case 4: |
|||
*Ps = nuEndS * PSiso + nuIntS * PSsha; |
|||
*Pd = nuEndD * PDmer + nuIntD * PDsha; |
|||
*As = nuEndS * ASiso + nuIntS * ASsha; |
|||
*Ad = nuEndD * ADmer + nuIntD * ADsha; |
|||
break; |
|||
case 5: |
|||
*Ps = (nuEndS + nuIntS) * PSsha; |
|||
*Pd = nuEndD * PDmer + nuIntD * PDsha; |
|||
*As = (nuEndS + nuIntS) * ASsha; |
|||
*Ad = nuEndD * ADmer + nuIntD * ADsha; |
|||
break; |
|||
case 6: |
|||
*Ps = nuEndS * PSmer + nuIntS * PSsha; |
|||
*Pd = nuEndD * PDiso + nuIntD * PDsha; |
|||
*As = nuEndS * ASmer + nuIntS * ASsha; |
|||
*Ad = nuEndD * ADiso + nuIntD * ADsha; |
|||
break; |
|||
case 7: |
|||
*Ps = nuEndS * PSmer + nuIntS * PSsha; |
|||
*Pd = (nuEndD + nuIntD) * PDsha; |
|||
*As = nuEndS * ASmer + nuIntS * ASsha; |
|||
*Ad = (nuEndD + nuIntD) * ADsha; |
|||
break; |
|||
case 8: |
|||
*Ps = nuEndS * PSmer + nuIntS * PSsha; |
|||
*Pd = nuEndD * PDmer + nuIntD * PDsha; |
|||
*As = nuEndS * ASmer + nuIntS * ASsha; |
|||
*Ad = nuEndD * ADmer + nuIntD * ADsha; |
|||
break; |
|||
case 9: /* geo = 9 and 10 happen only when nf = even */ |
|||
*Ps = PSiso + (nf - 1.0) * PSsha; |
|||
*Pd = nf * PDsha; |
|||
*As = ASiso + (nf - 1.0) * ASsha; |
|||
*Ad = nf * ADsha; |
|||
break; |
|||
case 10: |
|||
*Ps = nf * PSsha; |
|||
*Pd = PDiso + (nf - 1.0) * PDsha; |
|||
*As = nf * ASsha; |
|||
*Ad = ADiso + (nf - 1.0) * ADsha; |
|||
break; |
|||
default: |
|||
printf("Warning: Specified GEO = %d not matched\n", geo); |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
|
|||
int |
|||
BSIM4RdseffGeo( |
|||
double nf, |
|||
int geo, int rgeo, int minSD, |
|||
double Weffcj, double Rsh, double DMCG, double DMCI, double DMDG, |
|||
int Type, |
|||
double *Rtot) |
|||
{ |
|||
double Rint=0.0, Rend = 0.0; |
|||
double nuIntD = 0.0, nuEndD = 0.0, nuIntS = 0.0, nuEndS = 0.0; |
|||
|
|||
if (geo < 9) /* since geo = 9 and 10 only happen when nf = even */ |
|||
{ BSIM4NumFingerDiff(nf, minSD, &nuIntD, &nuEndD, &nuIntS, &nuEndS); |
|||
|
|||
/* Internal S/D resistance -- assume shared S or D and all wide contacts */ |
|||
if (Type == 1) |
|||
{ if (nuIntS == 0.0) |
|||
Rint = 0.0; |
|||
else |
|||
Rint = Rsh * DMCG / ( Weffcj * nuIntS); |
|||
} |
|||
else |
|||
{ if (nuIntD == 0.0) |
|||
Rint = 0.0; |
|||
else |
|||
Rint = Rsh * DMCG / ( Weffcj * nuIntD); |
|||
} |
|||
} |
|||
|
|||
/* End S/D resistance -- geo dependent */ |
|||
switch(geo) |
|||
{ case 0: |
|||
if (Type == 1) BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG, |
|||
nuEndS, rgeo, 1, &Rend); |
|||
else BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG, |
|||
nuEndD, rgeo, 0, &Rend); |
|||
break; |
|||
case 1: |
|||
if (Type == 1) BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG, |
|||
nuEndS, rgeo, 1, &Rend); |
|||
else BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG, |
|||
nuEndD, rgeo, 0, &Rend); |
|||
break; |
|||
case 2: |
|||
if (Type == 1) BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG, |
|||
nuEndS, rgeo, 1, &Rend); |
|||
else BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG, |
|||
nuEndD, rgeo, 0, &Rend); |
|||
break; |
|||
case 3: |
|||
if (Type == 1) BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG, |
|||
nuEndS, rgeo, 1, &Rend); |
|||
else BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG, |
|||
nuEndD, rgeo, 0, &Rend); |
|||
break; |
|||
case 4: |
|||
if (Type == 1) BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG, |
|||
nuEndS, rgeo, 1, &Rend); |
|||
else Rend = Rsh * DMDG / Weffcj; |
|||
break; |
|||
case 5: |
|||
if (Type == 1) BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG, |
|||
nuEndS, rgeo, 1, &Rend); |
|||
else Rend = Rsh * DMDG / (Weffcj * nuEndD); |
|||
break; |
|||
case 6: |
|||
if (Type == 1) Rend = Rsh * DMDG / Weffcj; |
|||
else BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG, |
|||
nuEndD, rgeo, 0, &Rend); |
|||
break; |
|||
case 7: |
|||
if (Type == 1) Rend = Rsh * DMDG / (Weffcj * nuEndS); |
|||
else BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG, |
|||
nuEndD, rgeo, 0, &Rend); |
|||
break; |
|||
case 8: |
|||
Rend = Rsh * DMDG / Weffcj; |
|||
break; |
|||
case 9: /* all wide contacts assumed for geo = 9 and 10 */ |
|||
if (Type == 1) |
|||
{ Rend = 0.5 * Rsh * DMCG / Weffcj; |
|||
if (nf == 2.0) |
|||
Rint = 0.0; |
|||
else |
|||
Rint = Rsh * DMCG / (Weffcj * (nf - 2.0)); |
|||
} |
|||
else |
|||
{ Rend = 0.0; |
|||
Rint = Rsh * DMCG / (Weffcj * nf); |
|||
} |
|||
break; |
|||
case 10: |
|||
if (Type == 1) |
|||
{ Rend = 0.0; |
|||
Rint = Rsh * DMCG / (Weffcj * nf); |
|||
} |
|||
else |
|||
{ Rend = 0.5 * Rsh * DMCG / Weffcj;; |
|||
if (nf == 2.0) |
|||
Rint = 0.0; |
|||
else |
|||
Rint = Rsh * DMCG / (Weffcj * (nf - 2.0)); |
|||
} |
|||
break; |
|||
default: |
|||
printf("Warning: Specified GEO = %d not matched\n", geo); |
|||
} |
|||
|
|||
if (Rint <= 0.0) |
|||
*Rtot = Rend; |
|||
else if (Rend <= 0.0) |
|||
*Rtot = Rint; |
|||
else |
|||
*Rtot = Rint * Rend / (Rint + Rend); |
|||
if(*Rtot==0.0) |
|||
printf("Warning: Zero resistance returned from RdseffGeo\n"); |
|||
return 0; |
|||
} |
|||
|
|||
|
|||
int |
|||
BSIM4RdsEndIso( |
|||
double Weffcj, double Rsh, double DMCG, double DMCI, double DMDG, |
|||
double nuEnd, |
|||
int rgeo, int Type, |
|||
double *Rend) |
|||
{ |
|||
NG_IGNORE(DMDG); |
|||
|
|||
if (Type == 1) |
|||
{ switch(rgeo) |
|||
{ case 1: |
|||
case 2: |
|||
case 5: |
|||
if (nuEnd == 0.0) |
|||
*Rend = 0.0; |
|||
else |
|||
*Rend = Rsh * DMCG / (Weffcj * nuEnd); |
|||
break; |
|||
case 3: |
|||
case 4: |
|||
case 6: |
|||
if ((DMCG + DMCI) == 0.0) |
|||
printf("(DMCG + DMCI) can not be equal to zero\n"); |
|||
if ((nuEnd == 0.0)||((DMCG+DMCI)==0.0)) |
|||
*Rend = 0.0; |
|||
else |
|||
*Rend = Rsh * Weffcj / (3.0 * nuEnd * (DMCG + DMCI)); |
|||
break; |
|||
default: |
|||
printf("Warning: Specified RGEO = %d not matched\n", rgeo); |
|||
} |
|||
} |
|||
else |
|||
{ switch(rgeo) |
|||
{ case 1: |
|||
case 3: |
|||
case 7: |
|||
if (nuEnd == 0.0) |
|||
*Rend = 0.0; |
|||
else |
|||
*Rend = Rsh * DMCG / (Weffcj * nuEnd); |
|||
break; |
|||
case 2: |
|||
case 4: |
|||
case 8: |
|||
if ((DMCG + DMCI) == 0.0) |
|||
printf("(DMCG + DMCI) can not be equal to zero\n"); |
|||
if ((nuEnd == 0.0)||((DMCG + DMCI)==0.0)) |
|||
*Rend = 0.0; |
|||
else |
|||
*Rend = Rsh * Weffcj / (3.0 * nuEnd * (DMCG + DMCI)); |
|||
break; |
|||
default: |
|||
printf("Warning: Specified RGEO = %d not matched\n", rgeo); |
|||
} |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
|
|||
int |
|||
BSIM4RdsEndSha( |
|||
double Weffcj, double Rsh, double DMCG, double DMCI, double DMDG, |
|||
double nuEnd, |
|||
int rgeo, int Type, |
|||
double *Rend) |
|||
{ |
|||
NG_IGNORE(DMCI); |
|||
NG_IGNORE(DMDG); |
|||
|
|||
if (Type == 1) |
|||
{ switch(rgeo) |
|||
{ case 1: |
|||
case 2: |
|||
case 5: |
|||
if (nuEnd == 0.0) |
|||
*Rend = 0.0; |
|||
else |
|||
*Rend = Rsh * DMCG / (Weffcj * nuEnd); |
|||
break; |
|||
case 3: |
|||
case 4: |
|||
case 6: |
|||
if (DMCG == 0.0) |
|||
printf("DMCG can not be equal to zero\n"); |
|||
if (nuEnd == 0.0) |
|||
*Rend = 0.0; |
|||
else |
|||
*Rend = Rsh * Weffcj / (6.0 * nuEnd * DMCG); |
|||
break; |
|||
default: |
|||
printf("Warning: Specified RGEO = %d not matched\n", rgeo); |
|||
} |
|||
} |
|||
else |
|||
{ switch(rgeo) |
|||
{ case 1: |
|||
case 3: |
|||
case 7: |
|||
if (nuEnd == 0.0) |
|||
*Rend = 0.0; |
|||
else |
|||
*Rend = Rsh * DMCG / (Weffcj * nuEnd); |
|||
break; |
|||
case 2: |
|||
case 4: |
|||
case 8: |
|||
if (DMCG == 0.0) |
|||
printf("DMCG can not be equal to zero\n"); |
|||
if (nuEnd == 0.0) |
|||
*Rend = 0.0; |
|||
else |
|||
*Rend = Rsh * Weffcj / (6.0 * nuEnd * DMCG); |
|||
break; |
|||
default: |
|||
printf("Warning: Specified RGEO = %d not matched\n", rgeo); |
|||
} |
|||
} |
|||
return 0; |
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
/**** BSIM4.7.0 Released by Darsen Lu 04/08/2011 ****/ |
|||
|
|||
/********** |
|||
* Copyright 2006 Regents of the University of California. All rights reserved. |
|||
* File: b4getic.c of BSIM4.7.0. |
|||
* Author: 2000 Weidong Liu |
|||
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu. |
|||
* Authors: 2006- Mohan Dunga, Ali Niknejad, Chenming Hu |
|||
* Authors: 2007- Mohan Dunga, Wenwei Yang, Ali Niknejad, Chenming Hu |
|||
* Project Director: Prof. Chenming Hu. |
|||
**********/ |
|||
|
|||
#include "ngspice/ngspice.h" |
|||
#include "ngspice/cktdefs.h" |
|||
#include "bsim4def.h" |
|||
#include "ngspice/sperror.h" |
|||
#include "ngspice/suffix.h" |
|||
|
|||
|
|||
int |
|||
BSIM4getic( |
|||
GENmodel *inModel, |
|||
CKTcircuit *ckt) |
|||
{ |
|||
BSIM4model *model = (BSIM4model*)inModel; |
|||
BSIM4instance *here; |
|||
|
|||
for (; model ; model = model->BSIM4nextModel) |
|||
{ for (here = model->BSIM4instances; here; here = here->BSIM4nextInstance) |
|||
{ |
|||
if (!here->BSIM4icVDSGiven) |
|||
{ here->BSIM4icVDS = *(ckt->CKTrhs + here->BSIM4dNode) |
|||
- *(ckt->CKTrhs + here->BSIM4sNode); |
|||
} |
|||
if (!here->BSIM4icVGSGiven) |
|||
{ here->BSIM4icVGS = *(ckt->CKTrhs + here->BSIM4gNodeExt) |
|||
- *(ckt->CKTrhs + here->BSIM4sNode); |
|||
} |
|||
if(!here->BSIM4icVBSGiven) |
|||
{ here->BSIM4icVBS = *(ckt->CKTrhs + here->BSIM4bNode) |
|||
- *(ckt->CKTrhs + here->BSIM4sNode); |
|||
} |
|||
} |
|||
} |
|||
return(OK); |
|||
} |
|||
5545
src/spicelib/devices/bsim4v7/b4v7ld.c
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
2723
src/spicelib/devices/bsim4v7/b4v7mask.c
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,48 @@ |
|||
/**** BSIM4.7.0 Released by Darsen Lu 04/08/2011 ****/ |
|||
|
|||
/********** |
|||
* Copyright 2006 Regents of the University of California. All rights reserved. |
|||
* File: b4mdel.c of BSIM4.7.0. |
|||
* Author: 2000 Weidong Liu |
|||
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu. |
|||
* Authors: 2006- Mohan Dunga, Ali Niknejad, Chenming Hu |
|||
* Authors: 2007- Mohan Dunga, Wenwei Yang, Ali Niknejad, Chenming Hu |
|||
* Project Director: Prof. Chenming Hu. |
|||
**********/ |
|||
|
|||
#include "ngspice/ngspice.h" |
|||
#include "bsim4def.h" |
|||
#include "ngspice/sperror.h" |
|||
#include "ngspice/suffix.h" |
|||
|
|||
int |
|||
BSIM4mDelete( |
|||
GENmodel **inModel, |
|||
IFuid modname, |
|||
GENmodel *kill) |
|||
{ |
|||
BSIM4model **model = (BSIM4model**)inModel; |
|||
BSIM4model *modfast = (BSIM4model*)kill; |
|||
BSIM4instance *here; |
|||
BSIM4instance *prev = NULL; |
|||
BSIM4model **oldmod; |
|||
|
|||
oldmod = model; |
|||
for (; *model ; model = &((*model)->BSIM4nextModel)) |
|||
{ if ((*model)->BSIM4modName == modname || |
|||
(modfast && *model == modfast)) |
|||
goto delgot; |
|||
oldmod = model; |
|||
} |
|||
return(E_NOMOD); |
|||
|
|||
delgot: |
|||
*oldmod = (*model)->BSIM4nextModel; /* cut deleted device out of list */ |
|||
for (here = (*model)->BSIM4instances; here; here = here->BSIM4nextInstance) |
|||
{ if(prev) FREE(prev); |
|||
prev = here; |
|||
} |
|||
if(prev) FREE(prev); |
|||
FREE(*model); |
|||
return(OK); |
|||
} |
|||
3649
src/spicelib/devices/bsim4v7/b4v7mpar.c
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,648 @@ |
|||
/**** BSIM4.7.0 Released by Darsen Lu 04/08/2011 ****/ |
|||
|
|||
/********** |
|||
* Copyright 2006 Regents of the University of California. All rights reserved. |
|||
* File: b4noi.c of BSIM4.7.0. |
|||
* Author: 2000 Weidong Liu |
|||
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu. |
|||
* Authors: 2006- Mohan Dunga, Ali Niknejad, Chenming Hu |
|||
* Authors: 2007- Mohan Dunga, Wenwei Yang, Ali Niknejad, Chenming Hu |
|||
* Authors: 2008- Wenwei Yang, Ali Niknejad, Chenming Hu |
|||
* Project Director: Prof. Chenming Hu. |
|||
* Modified by Xuemei Xi, 04/06/2001. |
|||
* Modified by Xuemei Xi, 10/05/2001. |
|||
* Modified by Xuemei Xi, 05/09/2003. |
|||
* Modified by Xuemei Xi, 03/04/2004. |
|||
* Modified by Xuemei Xi, 07/29/2005. |
|||
* Modified by Mohan Dunga, 12/13/2006 |
|||
* Modified by Wenwei Yang, 07/31/2008. |
|||
* Modified by Tanvir Morshed, Darsen Lu 03/27/2011 |
|||
**********/ |
|||
|
|||
#include "ngspice/ngspice.h" |
|||
#include "bsim4def.h" |
|||
#include "ngspice/cktdefs.h" |
|||
#include "ngspice/iferrmsg.h" |
|||
#include "ngspice/noisedef.h" |
|||
#include "ngspice/suffix.h" |
|||
#include "ngspice/const.h" |
|||
|
|||
|
|||
/* |
|||
* WDL: 1/f noise model has been smoothed out and enhanced with |
|||
* bulk charge effect as well as physical N* equ. and necessary |
|||
* conversion into the SI unit system. |
|||
*/ |
|||
|
|||
static double |
|||
Eval1ovFNoise( |
|||
double Vds, |
|||
BSIM4model *model, |
|||
BSIM4instance *here, |
|||
double freq, double temp) |
|||
{ |
|||
struct bsim4SizeDependParam *pParam; |
|||
double cd, esat, DelClm, EffFreq, N0, Nl, Leff, Leffsq; |
|||
double T0=0.0, T1, T2, T3, T4, T5, T6, T7, T8, T9, Ssi; |
|||
|
|||
pParam = here->pParam; |
|||
cd = fabs(here->BSIM4cd); |
|||
Leff = pParam->BSIM4leff - 2.0 * model->BSIM4lintnoi; |
|||
Leffsq = Leff * Leff; |
|||
esat = 2.0 * here->BSIM4vsattemp / here->BSIM4ueff; |
|||
if(model->BSIM4em<=0.0) DelClm = 0.0; /* flicker noise modified -JX */ |
|||
else { |
|||
T0 = ((((Vds - here->BSIM4Vdseff) / pParam->BSIM4litl) |
|||
+ model->BSIM4em) / esat); |
|||
DelClm = pParam->BSIM4litl * log (MAX(T0, N_MINLOG)); |
|||
if (DelClm < 0.0) DelClm = 0.0; /* bugfix */ |
|||
} |
|||
EffFreq = pow(freq, model->BSIM4ef); |
|||
T1 = CHARGE * CHARGE * CONSTboltz * cd * temp * here->BSIM4ueff; |
|||
T2 = 1.0e10 * EffFreq * here->BSIM4Abulk * model->BSIM4coxe * Leffsq; |
|||
N0 = model->BSIM4coxe * here->BSIM4Vgsteff / CHARGE; |
|||
Nl = model->BSIM4coxe * here->BSIM4Vgsteff |
|||
* (1.0 - here->BSIM4AbovVgst2Vtm * here->BSIM4Vdseff) / CHARGE; |
|||
|
|||
T3 = model->BSIM4oxideTrapDensityA |
|||
* log(MAX(((N0 + here->BSIM4nstar) / (Nl + here->BSIM4nstar)), N_MINLOG)); |
|||
T4 = model->BSIM4oxideTrapDensityB * (N0 - Nl); |
|||
T5 = model->BSIM4oxideTrapDensityC * 0.5 * (N0 * N0 - Nl * Nl); |
|||
|
|||
T6 = CONSTboltz * temp * cd * cd; |
|||
T7 = 1.0e10 * EffFreq * Leffsq * pParam->BSIM4weff * here->BSIM4nf; |
|||
T8 = model->BSIM4oxideTrapDensityA + model->BSIM4oxideTrapDensityB * Nl |
|||
+ model->BSIM4oxideTrapDensityC * Nl * Nl; |
|||
T9 = (Nl + here->BSIM4nstar) * (Nl + here->BSIM4nstar); |
|||
Ssi = T1 / T2 * (T3 + T4 + T5) + T6 / T7 * DelClm * T8 / T9; |
|||
return Ssi; |
|||
} |
|||
|
|||
|
|||
int |
|||
BSIM4noise ( |
|||
int mode, int operation, |
|||
GENmodel *inModel, |
|||
CKTcircuit *ckt, |
|||
Ndata *data, |
|||
double *OnDens) |
|||
{ |
|||
NOISEAN *job = (NOISEAN *) ckt->CKTcurJob; |
|||
|
|||
BSIM4model *model = (BSIM4model *)inModel; |
|||
BSIM4instance *here; |
|||
struct bsim4SizeDependParam *pParam; |
|||
char name[N_MXVLNTH]; |
|||
double tempOnoise; |
|||
double tempInoise; |
|||
double noizDens[BSIM4NSRCS]; |
|||
double lnNdens[BSIM4NSRCS]; |
|||
|
|||
double T0, T1, T2, T3, T4, T5, T6, T7, T8, T10, T11; |
|||
double Vds, Ssi, Swi; |
|||
double tmp=0.0, gdpr, gspr, npart_theta=0.0, npart_beta=0.0, igsquare, bodymode; |
|||
|
|||
/* tnoiMod=2 (v4.7) */ |
|||
double eta, Leff, Lvsat, gamma, delta, epsilon, GammaGd0=0.0; |
|||
double npart_c, sigrat=0.0, C0, omega, ctnoi=0.0; |
|||
|
|||
int i; |
|||
|
|||
double m; |
|||
|
|||
/* define the names of the noise sources */ |
|||
static char *BSIM4nNames[BSIM4NSRCS] = |
|||
{ /* Note that we have to keep the order */ |
|||
".rd", /* noise due to rd */ |
|||
".rs", /* noise due to rs */ |
|||
".rg", /* noise due to rgeltd */ |
|||
".rbps", /* noise due to rbps */ |
|||
".rbpd", /* noise due to rbpd */ |
|||
".rbpb", /* noise due to rbpb */ |
|||
".rbsb", /* noise due to rbsb */ |
|||
".rbdb", /* noise due to rbdb */ |
|||
".id", /* noise due to id (for tnoiMod2: uncorrelated portion only) */ |
|||
".1overf", /* flicker (1/f) noise */ |
|||
".igs", /* shot noise due to IGS */ |
|||
".igd", /* shot noise due to IGD */ |
|||
".igb", /* shot noise due to IGB */ |
|||
".corl", /* contribution of correlated drain and induced gate noise */ |
|||
"" /* total transistor noise */ |
|||
}; |
|||
|
|||
for (; model != NULL; model = model->BSIM4nextModel) |
|||
{ |
|||
if(model->BSIM4tnoiMod != 2) { |
|||
noizDens[BSIM4CORLNOIZ] = 0.0; |
|||
lnNdens[BSIM4CORLNOIZ] = N_MINLOG; |
|||
} |
|||
for (here = model->BSIM4instances; here != NULL; |
|||
here = here->BSIM4nextInstance) |
|||
{ pParam = here->pParam; |
|||
switch (operation) |
|||
{ case N_OPEN: |
|||
/* see if we have to to produce a summary report */ |
|||
/* if so, name all the noise generators */ |
|||
|
|||
if (job->NStpsSm != 0) |
|||
{ switch (mode) |
|||
{ case N_DENS: |
|||
for (i = 0; i < BSIM4NSRCS; i++) |
|||
{ (void) sprintf(name, "onoise.%s%s", |
|||
here->BSIM4name, |
|||
BSIM4nNames[i]); |
|||
data->namelist = TREALLOC(IFuid, |
|||
data->namelist, |
|||
data->numPlots + 1); |
|||
if (!data->namelist) |
|||
return(E_NOMEM); |
|||
SPfrontEnd->IFnewUid (ckt, |
|||
&(data->namelist[data->numPlots++]), |
|||
NULL, name, UID_OTHER, NULL); |
|||
/* we've added one more plot */ |
|||
} |
|||
break; |
|||
case INT_NOIZ: |
|||
for (i = 0; i < BSIM4NSRCS; i++) |
|||
{ (void) sprintf(name, "onoise_total.%s%s", |
|||
here->BSIM4name, |
|||
BSIM4nNames[i]); |
|||
data->namelist = TREALLOC(IFuid, |
|||
data->namelist, |
|||
data->numPlots + 1); |
|||
if (!data->namelist) |
|||
return(E_NOMEM); |
|||
SPfrontEnd->IFnewUid (ckt, |
|||
&(data->namelist[data->numPlots++]), |
|||
NULL, name, UID_OTHER, NULL); |
|||
/* we've added one more plot */ |
|||
|
|||
(void) sprintf(name, "inoise_total.%s%s", |
|||
here->BSIM4name, |
|||
BSIM4nNames[i]); |
|||
data->namelist = TREALLOC(IFuid, |
|||
data->namelist, |
|||
data->numPlots + 1); |
|||
if (!data->namelist) |
|||
return(E_NOMEM); |
|||
SPfrontEnd->IFnewUid (ckt, |
|||
&(data->namelist[data->numPlots++]), |
|||
NULL, name, UID_OTHER, NULL); |
|||
/* we've added one more plot */ |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
break; |
|||
case N_CALC: |
|||
m = here->BSIM4m; |
|||
switch (mode) |
|||
{ case N_DENS: |
|||
if (model->BSIM4tnoiMod == 0) |
|||
{ if (model->BSIM4rdsMod == 0) |
|||
{ gspr = here->BSIM4sourceConductance; |
|||
gdpr = here->BSIM4drainConductance; |
|||
if (here->BSIM4grdsw > 0.0) |
|||
tmp = 1.0 / here->BSIM4grdsw; /* tmp used below */ |
|||
else |
|||
tmp = 0.0; |
|||
} |
|||
else |
|||
{ gspr = here->BSIM4gstot; |
|||
gdpr = here->BSIM4gdtot; |
|||
tmp = 0.0; |
|||
} |
|||
} |
|||
else if(model->BSIM4tnoiMod == 1) |
|||
{ T5 = here->BSIM4Vgsteff / here->BSIM4EsatL; |
|||
T5 *= T5; |
|||
npart_beta = model->BSIM4rnoia * (1.0 + T5 |
|||
* model->BSIM4tnoia * pParam->BSIM4leff); |
|||
npart_theta = model->BSIM4rnoib * (1.0 + T5 |
|||
* model->BSIM4tnoib * pParam->BSIM4leff); |
|||
if(npart_theta > 0.9) |
|||
npart_theta = 0.9; |
|||
if(npart_theta > 0.9 * npart_beta) |
|||
npart_theta = 0.9 * npart_beta; //4.6.2 |
|||
|
|||
if (model->BSIM4rdsMod == 0) |
|||
{ gspr = here->BSIM4sourceConductance; |
|||
gdpr = here->BSIM4drainConductance; |
|||
} |
|||
else |
|||
{ gspr = here->BSIM4gstot; |
|||
gdpr = here->BSIM4gdtot; |
|||
} |
|||
|
|||
if ((*(ckt->CKTstates[0] + here->BSIM4vds)) >= 0.0) |
|||
gspr = gspr * (1.0 + npart_theta * npart_theta * gspr |
|||
/ here->BSIM4IdovVds); |
|||
else |
|||
gdpr = gdpr * (1.0 + npart_theta * npart_theta * gdpr |
|||
/ here->BSIM4IdovVds); |
|||
} |
|||
else |
|||
{ /* tnoiMod=2 (v4.7) */ |
|||
|
|||
if (model->BSIM4rdsMod == 0) |
|||
{ gspr = here->BSIM4sourceConductance; |
|||
gdpr = here->BSIM4drainConductance; |
|||
} |
|||
else |
|||
{ gspr = here->BSIM4gstot; |
|||
gdpr = here->BSIM4gdtot; |
|||
} |
|||
|
|||
} |
|||
|
|||
NevalSrc(&noizDens[BSIM4RDNOIZ], |
|||
&lnNdens[BSIM4RDNOIZ], ckt, THERMNOISE, |
|||
here->BSIM4dNodePrime, here->BSIM4dNode, |
|||
gdpr * m); |
|||
|
|||
NevalSrc(&noizDens[BSIM4RSNOIZ], |
|||
&lnNdens[BSIM4RSNOIZ], ckt, THERMNOISE, |
|||
here->BSIM4sNodePrime, here->BSIM4sNode, |
|||
gspr * m); |
|||
|
|||
|
|||
if (here->BSIM4rgateMod == 1) |
|||
{ NevalSrc(&noizDens[BSIM4RGNOIZ], |
|||
&lnNdens[BSIM4RGNOIZ], ckt, THERMNOISE, |
|||
here->BSIM4gNodePrime, here->BSIM4gNodeExt, |
|||
here->BSIM4grgeltd * m); |
|||
} |
|||
else if (here->BSIM4rgateMod == 2) |
|||
{ |
|||
T0 = 1.0 + here->BSIM4grgeltd/here->BSIM4gcrg; |
|||
T1 = T0 * T0; |
|||
NevalSrc(&noizDens[BSIM4RGNOIZ], |
|||
&lnNdens[BSIM4RGNOIZ], ckt, THERMNOISE, |
|||
here->BSIM4gNodePrime, here->BSIM4gNodeExt, |
|||
here->BSIM4grgeltd * m / T1); |
|||
} |
|||
else if (here->BSIM4rgateMod == 3) |
|||
{ NevalSrc(&noizDens[BSIM4RGNOIZ], |
|||
&lnNdens[BSIM4RGNOIZ], ckt, THERMNOISE, |
|||
here->BSIM4gNodeMid, here->BSIM4gNodeExt, |
|||
here->BSIM4grgeltd * m); |
|||
} |
|||
else |
|||
{ noizDens[BSIM4RGNOIZ] = 0.0; |
|||
lnNdens[BSIM4RGNOIZ] = |
|||
log(MAX(noizDens[BSIM4RGNOIZ], N_MINLOG)); |
|||
} |
|||
|
|||
bodymode = 5; |
|||
if (here->BSIM4rbodyMod == 2) |
|||
{ if( ( !model->BSIM4rbps0Given) || |
|||
( !model->BSIM4rbpd0Given) ) |
|||
bodymode = 1; |
|||
else |
|||
if( (!model->BSIM4rbsbx0Given && !model->BSIM4rbsby0Given) || |
|||
(!model->BSIM4rbdbx0Given && !model->BSIM4rbdby0Given) ) |
|||
bodymode = 3; |
|||
} |
|||
|
|||
if (here->BSIM4rbodyMod) |
|||
{ |
|||
if(bodymode == 5) |
|||
{ |
|||
NevalSrc(&noizDens[BSIM4RBPSNOIZ], |
|||
&lnNdens[BSIM4RBPSNOIZ], ckt, THERMNOISE, |
|||
here->BSIM4bNodePrime, here->BSIM4sbNode, |
|||
here->BSIM4grbps * m); |
|||
NevalSrc(&noizDens[BSIM4RBPDNOIZ], |
|||
&lnNdens[BSIM4RBPDNOIZ], ckt, THERMNOISE, |
|||
here->BSIM4bNodePrime, here->BSIM4dbNode, |
|||
here->BSIM4grbpd * m); |
|||
NevalSrc(&noizDens[BSIM4RBPBNOIZ], |
|||
&lnNdens[BSIM4RBPBNOIZ], ckt, THERMNOISE, |
|||
here->BSIM4bNodePrime, here->BSIM4bNode, |
|||
here->BSIM4grbpb * m); |
|||
NevalSrc(&noizDens[BSIM4RBSBNOIZ], |
|||
&lnNdens[BSIM4RBSBNOIZ], ckt, THERMNOISE, |
|||
here->BSIM4bNode, here->BSIM4sbNode, |
|||
here->BSIM4grbsb * m); |
|||
NevalSrc(&noizDens[BSIM4RBDBNOIZ], |
|||
&lnNdens[BSIM4RBDBNOIZ], ckt, THERMNOISE, |
|||
here->BSIM4bNode, here->BSIM4dbNode, |
|||
here->BSIM4grbdb * m); |
|||
} |
|||
if(bodymode == 3) |
|||
{ |
|||
NevalSrc(&noizDens[BSIM4RBPSNOIZ], |
|||
&lnNdens[BSIM4RBPSNOIZ], ckt, THERMNOISE, |
|||
here->BSIM4bNodePrime, here->BSIM4sbNode, |
|||
here->BSIM4grbps * m); |
|||
NevalSrc(&noizDens[BSIM4RBPDNOIZ], |
|||
&lnNdens[BSIM4RBPDNOIZ], ckt, THERMNOISE, |
|||
here->BSIM4bNodePrime, here->BSIM4dbNode, |
|||
here->BSIM4grbpd * m); |
|||
NevalSrc(&noizDens[BSIM4RBPBNOIZ], |
|||
&lnNdens[BSIM4RBPBNOIZ], ckt, THERMNOISE, |
|||
here->BSIM4bNodePrime, here->BSIM4bNode, |
|||
here->BSIM4grbpb * m); |
|||
noizDens[BSIM4RBSBNOIZ] = noizDens[BSIM4RBDBNOIZ] = 0.0; |
|||
lnNdens[BSIM4RBSBNOIZ] = |
|||
log(MAX(noizDens[BSIM4RBSBNOIZ], N_MINLOG)); |
|||
lnNdens[BSIM4RBDBNOIZ] = |
|||
log(MAX(noizDens[BSIM4RBDBNOIZ], N_MINLOG)); |
|||
} |
|||
if(bodymode == 1) |
|||
{ |
|||
NevalSrc(&noizDens[BSIM4RBPBNOIZ], |
|||
&lnNdens[BSIM4RBPBNOIZ], ckt, THERMNOISE, |
|||
here->BSIM4bNodePrime, here->BSIM4bNode, |
|||
here->BSIM4grbpb * m); |
|||
noizDens[BSIM4RBPSNOIZ] = noizDens[BSIM4RBPDNOIZ] = 0.0; |
|||
noizDens[BSIM4RBSBNOIZ] = noizDens[BSIM4RBDBNOIZ] = 0.0; |
|||
lnNdens[BSIM4RBPSNOIZ] = |
|||
log(MAX(noizDens[BSIM4RBPSNOIZ], N_MINLOG)); |
|||
lnNdens[BSIM4RBPDNOIZ] = |
|||
log(MAX(noizDens[BSIM4RBPDNOIZ], N_MINLOG)); |
|||
lnNdens[BSIM4RBSBNOIZ] = |
|||
log(MAX(noizDens[BSIM4RBSBNOIZ], N_MINLOG)); |
|||
lnNdens[BSIM4RBDBNOIZ] = |
|||
log(MAX(noizDens[BSIM4RBDBNOIZ], N_MINLOG)); |
|||
} |
|||
} |
|||
else |
|||
{ noizDens[BSIM4RBPSNOIZ] = noizDens[BSIM4RBPDNOIZ] = 0.0; |
|||
noizDens[BSIM4RBPBNOIZ] = 0.0; |
|||
noizDens[BSIM4RBSBNOIZ] = noizDens[BSIM4RBDBNOIZ] = 0.0; |
|||
lnNdens[BSIM4RBPSNOIZ] = |
|||
log(MAX(noizDens[BSIM4RBPSNOIZ], N_MINLOG)); |
|||
lnNdens[BSIM4RBPDNOIZ] = |
|||
log(MAX(noizDens[BSIM4RBPDNOIZ], N_MINLOG)); |
|||
lnNdens[BSIM4RBPBNOIZ] = |
|||
log(MAX(noizDens[BSIM4RBPBNOIZ], N_MINLOG)); |
|||
lnNdens[BSIM4RBSBNOIZ] = |
|||
log(MAX(noizDens[BSIM4RBSBNOIZ], N_MINLOG)); |
|||
lnNdens[BSIM4RBDBNOIZ] = |
|||
log(MAX(noizDens[BSIM4RBDBNOIZ], N_MINLOG)); |
|||
} |
|||
|
|||
if(model->BSIM4tnoiMod == 2) |
|||
{ |
|||
eta = 1.0 - here->BSIM4Vdseff * here->BSIM4AbovVgst2Vtm; |
|||
T0 = 1.0 - eta; |
|||
T1 = 1.0 + eta; |
|||
T2 = T1 + 2.0 * here->BSIM4Abulk * model->BSIM4vtm / here->BSIM4Vgsteff; |
|||
Leff = pParam->BSIM4leff; |
|||
Lvsat = Leff * (1.0 + here->BSIM4Vdseff / here->BSIM4EsatL); |
|||
T6 = Leff / Lvsat; |
|||
|
|||
T5 = here->BSIM4Vgsteff / here->BSIM4EsatL; |
|||
T5 = T5 * T5; |
|||
gamma = T6 * (0.5 * T1 + T0 * T0 / (6.0 * T2)); |
|||
T3 = T2 * T2; |
|||
T4 = T0 * T0; |
|||
T5 = T3 * T3; |
|||
delta = (T1 / T3 - (5.0 * T1 + T2) * T4 / (15.0 * T5) + T4 * T4 / (9.0 * T5 * T2)) / (6.0 * T6 * T6 * T6); |
|||
T7 = T0 / T2; |
|||
epsilon = (T7 - T7 * T7 * T7 / 3.0) / (6.0 * T6); |
|||
|
|||
T8 = here->BSIM4Vgsteff / here->BSIM4EsatL; |
|||
T8 *= T8; |
|||
npart_c = model->BSIM4rnoic * (1.0 + T8 |
|||
* model->BSIM4tnoic * Leff); |
|||
ctnoi = epsilon / sqrt(gamma * delta) |
|||
* (2.5316 * npart_c); |
|||
|
|||
npart_beta = model->BSIM4rnoia * (1.0 + T8 |
|||
* model->BSIM4tnoia * Leff); |
|||
npart_theta = model->BSIM4rnoib * (1.0 + T8 |
|||
* model->BSIM4tnoib * Leff); |
|||
gamma = gamma * (3.0 * npart_beta * npart_beta); |
|||
delta = delta * (3.75 * npart_theta * npart_theta); |
|||
|
|||
GammaGd0 = gamma * here->BSIM4noiGd0; |
|||
C0 = here->BSIM4Coxeff * pParam->BSIM4weffCV * here->BSIM4nf * pParam->BSIM4leffCV; |
|||
T0 = C0 / here->BSIM4noiGd0; |
|||
sigrat = T0 * sqrt(delta / gamma); |
|||
} |
|||
switch(model->BSIM4tnoiMod) |
|||
{ case 0: |
|||
T0 = here->BSIM4ueff * fabs(here->BSIM4qinv); |
|||
T1 = T0 * tmp + pParam->BSIM4leff |
|||
* pParam->BSIM4leff; |
|||
NevalSrc(&noizDens[BSIM4IDNOIZ], |
|||
&lnNdens[BSIM4IDNOIZ], ckt, |
|||
THERMNOISE, here->BSIM4dNodePrime, |
|||
here->BSIM4sNodePrime, |
|||
(T0 / T1) * model->BSIM4ntnoi * m); |
|||
break; |
|||
case 1: |
|||
T0 = here->BSIM4gm + here->BSIM4gmbs + here->BSIM4gds; |
|||
T0 *= T0; |
|||
igsquare = npart_theta * npart_theta * T0 / here->BSIM4IdovVds; |
|||
T1 = npart_beta * (here->BSIM4gm |
|||
+ here->BSIM4gmbs) + here->BSIM4gds; |
|||
T2 = T1 * T1 / here->BSIM4IdovVds; |
|||
NevalSrc(&noizDens[BSIM4IDNOIZ], |
|||
&lnNdens[BSIM4IDNOIZ], ckt, |
|||
THERMNOISE, here->BSIM4dNodePrime, |
|||
here->BSIM4sNodePrime, (T2 - igsquare) * m); |
|||
break; |
|||
case 2: |
|||
T2 = GammaGd0; |
|||
T3 = ctnoi * ctnoi; |
|||
T4 = 1.0 - T3; |
|||
NevalSrc(&noizDens[BSIM4IDNOIZ], |
|||
&lnNdens[BSIM4IDNOIZ], ckt, |
|||
THERMNOISE, here->BSIM4dNodePrime, |
|||
here->BSIM4sNodePrime, T2 * T4 * m); |
|||
|
|||
/* Evaluate output noise due to two correlated noise sources */ |
|||
omega = 2.0 * M_PI * data->freq; |
|||
T5 = omega * sigrat; |
|||
T6 = T5 * T5; |
|||
T7 = T6 / (1.0 + T6); |
|||
|
|||
if (here->BSIM4mode >= 0) { |
|||
NevalSrc2(&noizDens[BSIM4CORLNOIZ], |
|||
&lnNdens[BSIM4CORLNOIZ], ckt, |
|||
THERMNOISE, here->BSIM4dNodePrime, |
|||
here->BSIM4sNodePrime, T2 * T3 * m, |
|||
here->BSIM4gNodePrime, |
|||
here->BSIM4sNodePrime, |
|||
T2 * T7 * m, 0.5 * M_PI); |
|||
} |
|||
else |
|||
{ |
|||
NevalSrc2(&noizDens[BSIM4CORLNOIZ], |
|||
&lnNdens[BSIM4CORLNOIZ], ckt, |
|||
THERMNOISE, here->BSIM4sNodePrime, |
|||
here->BSIM4dNodePrime, T2 * T3 * m, |
|||
here->BSIM4gNodePrime, |
|||
here->BSIM4dNodePrime, |
|||
T2 * T7 * m, 0.5 * M_PI); |
|||
} |
|||
break; |
|||
} |
|||
|
|||
NevalSrc(&noizDens[BSIM4FLNOIZ], (double*) NULL, |
|||
ckt, N_GAIN, here->BSIM4dNodePrime, |
|||
here->BSIM4sNodePrime, (double) 0.0); |
|||
|
|||
switch(model->BSIM4fnoiMod) |
|||
{ case 0: |
|||
noizDens[BSIM4FLNOIZ] *= m * model->BSIM4kf |
|||
* exp(model->BSIM4af |
|||
* log(MAX(fabs(here->BSIM4cd), |
|||
N_MINLOG))) |
|||
/ (pow(data->freq, model->BSIM4ef) |
|||
* pParam->BSIM4leff |
|||
* pParam->BSIM4leff |
|||
* model->BSIM4coxe); |
|||
break; |
|||
case 1: |
|||
Vds = *(ckt->CKTstates[0] + here->BSIM4vds); |
|||
if (Vds < 0.0) |
|||
Vds = -Vds; |
|||
|
|||
Ssi = Eval1ovFNoise(Vds, model, here, |
|||
data->freq, ckt->CKTtemp); |
|||
T10 = model->BSIM4oxideTrapDensityA |
|||
* CONSTboltz * ckt->CKTtemp; |
|||
T11 = pParam->BSIM4weff * here->BSIM4nf * pParam->BSIM4leff |
|||
* pow(data->freq, model->BSIM4ef) * 1.0e10 |
|||
* here->BSIM4nstar * here->BSIM4nstar; |
|||
Swi = T10 / T11 * here->BSIM4cd |
|||
* here->BSIM4cd; |
|||
T1 = Swi + Ssi; |
|||
if (T1 > 0.0) |
|||
noizDens[BSIM4FLNOIZ] *= m * (Ssi * Swi) / T1; |
|||
else |
|||
noizDens[BSIM4FLNOIZ] *= 0.0; |
|||
break; |
|||
} |
|||
|
|||
lnNdens[BSIM4FLNOIZ] = |
|||
log(MAX(noizDens[BSIM4FLNOIZ], N_MINLOG)); |
|||
|
|||
|
|||
if(here->BSIM4mode >= 0) { /* bugfix */ |
|||
NevalSrc(&noizDens[BSIM4IGSNOIZ], |
|||
&lnNdens[BSIM4IGSNOIZ], ckt, SHOTNOISE, |
|||
here->BSIM4gNodePrime, here->BSIM4sNodePrime, |
|||
m * (here->BSIM4Igs + here->BSIM4Igcs)); |
|||
NevalSrc(&noizDens[BSIM4IGDNOIZ], |
|||
&lnNdens[BSIM4IGDNOIZ], ckt, SHOTNOISE, |
|||
here->BSIM4gNodePrime, here->BSIM4dNodePrime, |
|||
m * (here->BSIM4Igd + here->BSIM4Igcd)); |
|||
} else { |
|||
NevalSrc(&noizDens[BSIM4IGSNOIZ], |
|||
&lnNdens[BSIM4IGSNOIZ], ckt, SHOTNOISE, |
|||
here->BSIM4gNodePrime, here->BSIM4sNodePrime, |
|||
m * (here->BSIM4Igs + here->BSIM4Igcd)); |
|||
NevalSrc(&noizDens[BSIM4IGDNOIZ], |
|||
&lnNdens[BSIM4IGDNOIZ], ckt, SHOTNOISE, |
|||
here->BSIM4gNodePrime, here->BSIM4dNodePrime, |
|||
m * (here->BSIM4Igd + here->BSIM4Igcs)); |
|||
} |
|||
NevalSrc(&noizDens[BSIM4IGBNOIZ], |
|||
&lnNdens[BSIM4IGBNOIZ], ckt, SHOTNOISE, |
|||
here->BSIM4gNodePrime, here->BSIM4bNodePrime, |
|||
m * here->BSIM4Igb); |
|||
|
|||
|
|||
noizDens[BSIM4TOTNOIZ] = noizDens[BSIM4RDNOIZ] |
|||
+ noizDens[BSIM4RSNOIZ] + noizDens[BSIM4RGNOIZ] |
|||
+ noizDens[BSIM4RBPSNOIZ] + noizDens[BSIM4RBPDNOIZ] |
|||
+ noizDens[BSIM4RBPBNOIZ] |
|||
+ noizDens[BSIM4RBSBNOIZ] + noizDens[BSIM4RBDBNOIZ] |
|||
+ noizDens[BSIM4IDNOIZ] + noizDens[BSIM4FLNOIZ] |
|||
+ noizDens[BSIM4IGSNOIZ] + noizDens[BSIM4IGDNOIZ] |
|||
+ noizDens[BSIM4IGBNOIZ] + noizDens[BSIM4CORLNOIZ]; |
|||
lnNdens[BSIM4TOTNOIZ] = |
|||
log(MAX(noizDens[BSIM4TOTNOIZ], N_MINLOG)); |
|||
|
|||
*OnDens += noizDens[BSIM4TOTNOIZ]; |
|||
|
|||
if (data->delFreq == 0.0) |
|||
{ /* if we haven't done any previous |
|||
integration, we need to initialize our |
|||
"history" variables. |
|||
*/ |
|||
|
|||
for (i = 0; i < BSIM4NSRCS; i++) |
|||
{ here->BSIM4nVar[LNLSTDENS][i] = |
|||
lnNdens[i]; |
|||
} |
|||
|
|||
/* clear out our integration variables |
|||
if it's the first pass |
|||
*/ |
|||
if (data->freq == |
|||
job->NstartFreq) |
|||
{ for (i = 0; i < BSIM4NSRCS; i++) |
|||
{ here->BSIM4nVar[OUTNOIZ][i] = 0.0; |
|||
here->BSIM4nVar[INNOIZ][i] = 0.0; |
|||
} |
|||
} |
|||
} |
|||
else |
|||
{ /* data->delFreq != 0.0, |
|||
we have to integrate. |
|||
*/ |
|||
for (i = 0; i < BSIM4NSRCS; i++) |
|||
{ if (i != BSIM4TOTNOIZ) |
|||
{ tempOnoise = Nintegrate(noizDens[i], |
|||
lnNdens[i], |
|||
here->BSIM4nVar[LNLSTDENS][i], |
|||
data); |
|||
tempInoise = Nintegrate(noizDens[i] |
|||
* data->GainSqInv, lnNdens[i] |
|||
+ data->lnGainInv, |
|||
here->BSIM4nVar[LNLSTDENS][i] |
|||
+ data->lnGainInv, data); |
|||
here->BSIM4nVar[LNLSTDENS][i] = |
|||
lnNdens[i]; |
|||
data->outNoiz += tempOnoise; |
|||
data->inNoise += tempInoise; |
|||
if (job->NStpsSm != 0) |
|||
{ here->BSIM4nVar[OUTNOIZ][i] |
|||
+= tempOnoise; |
|||
here->BSIM4nVar[OUTNOIZ][BSIM4TOTNOIZ] |
|||
+= tempOnoise; |
|||
here->BSIM4nVar[INNOIZ][i] |
|||
+= tempInoise; |
|||
here->BSIM4nVar[INNOIZ][BSIM4TOTNOIZ] |
|||
+= tempInoise; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
if (data->prtSummary) |
|||
{ for (i = 0; i < BSIM4NSRCS; i++) |
|||
{ /* print a summary report */ |
|||
data->outpVector[data->outNumber++] |
|||
= noizDens[i]; |
|||
} |
|||
} |
|||
break; |
|||
case INT_NOIZ: |
|||
/* already calculated, just output */ |
|||
if (job->NStpsSm != 0) |
|||
{ for (i = 0; i < BSIM4NSRCS; i++) |
|||
{ data->outpVector[data->outNumber++] |
|||
= here->BSIM4nVar[OUTNOIZ][i]; |
|||
data->outpVector[data->outNumber++] |
|||
= here->BSIM4nVar[INNOIZ][i]; |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
break; |
|||
case N_CLOSE: |
|||
/* do nothing, the main calling routine will close */ |
|||
return (OK); |
|||
break; /* the plots */ |
|||
} /* switch (operation) */ |
|||
} /* for here */ |
|||
} /* for model */ |
|||
|
|||
return(OK); |
|||
} |
|||
@ -0,0 +1,204 @@ |
|||
/**** BSIM4.7.0 Released by Darsen Lu 04/08/2011 ****/ |
|||
|
|||
/********** |
|||
* Copyright 2006 Regents of the University of California. All rights reserved. |
|||
* File: b4par.c of BSIM4.7.0. |
|||
* Author: 2000 Weidong Liu |
|||
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu. |
|||
* Authors: 2006- Mohan Dunga, Ali Niknejad, Chenming Hu |
|||
* Authors: 2007- Mohan Dunga, Wenwei Yang, Ali Niknejad, Chenming Hu |
|||
* Project Director: Prof. Chenming Hu. |
|||
* Modified by Xuemei Xi, 04/06/2001. |
|||
* Modified by Xuemei Xi, 11/15/2002. |
|||
* Modified by Xuemei Xi, 05/09/2003. |
|||
* Modified by Xuemei Xi, Mohan Dunga, 07/29/2005. |
|||
**********/ |
|||
|
|||
#include "ngspice/ngspice.h" |
|||
#include "ngspice/ifsim.h" |
|||
#include "bsim4def.h" |
|||
#include "ngspice/sperror.h" |
|||
#include "ngspice/suffix.h" |
|||
#include "ngspice/fteext.h" |
|||
|
|||
int |
|||
BSIM4param( |
|||
int param, |
|||
IFvalue *value, |
|||
GENinstance *inst, |
|||
IFvalue *select) |
|||
{ |
|||
double scale; |
|||
|
|||
BSIM4instance *here = (BSIM4instance*)inst; |
|||
|
|||
NG_IGNORE(select); |
|||
|
|||
if (!cp_getvar("scale", CP_REAL, &scale)) |
|||
scale = 1; |
|||
|
|||
switch(param) |
|||
{ case BSIM4_W: |
|||
here->BSIM4w = value->rValue * scale; |
|||
here->BSIM4wGiven = TRUE; |
|||
break; |
|||
case BSIM4_L: |
|||
here->BSIM4l = value->rValue * scale; |
|||
here->BSIM4lGiven = TRUE; |
|||
break; |
|||
case BSIM4_M: |
|||
here->BSIM4m = value->rValue; |
|||
here->BSIM4mGiven = TRUE; |
|||
break; |
|||
case BSIM4_NF: |
|||
here->BSIM4nf = value->rValue; |
|||
here->BSIM4nfGiven = TRUE; |
|||
break; |
|||
case BSIM4_MIN: |
|||
here->BSIM4min = value->iValue; |
|||
here->BSIM4minGiven = TRUE; |
|||
break; |
|||
case BSIM4_AS: |
|||
here->BSIM4sourceArea = value->rValue * scale * scale; |
|||
here->BSIM4sourceAreaGiven = TRUE; |
|||
break; |
|||
case BSIM4_AD: |
|||
here->BSIM4drainArea = value->rValue * scale * scale; |
|||
here->BSIM4drainAreaGiven = TRUE; |
|||
break; |
|||
case BSIM4_PS: |
|||
here->BSIM4sourcePerimeter = value->rValue * scale; |
|||
here->BSIM4sourcePerimeterGiven = TRUE; |
|||
break; |
|||
case BSIM4_PD: |
|||
here->BSIM4drainPerimeter = value->rValue * scale; |
|||
here->BSIM4drainPerimeterGiven = TRUE; |
|||
break; |
|||
case BSIM4_NRS: |
|||
here->BSIM4sourceSquares = value->rValue; |
|||
here->BSIM4sourceSquaresGiven = TRUE; |
|||
break; |
|||
case BSIM4_NRD: |
|||
here->BSIM4drainSquares = value->rValue; |
|||
here->BSIM4drainSquaresGiven = TRUE; |
|||
break; |
|||
case BSIM4_OFF: |
|||
here->BSIM4off = value->iValue; |
|||
break; |
|||
case BSIM4_SA: |
|||
here->BSIM4sa = value->rValue; |
|||
here->BSIM4saGiven = TRUE; |
|||
break; |
|||
case BSIM4_SB: |
|||
here->BSIM4sb = value->rValue; |
|||
here->BSIM4sbGiven = TRUE; |
|||
break; |
|||
case BSIM4_SD: |
|||
here->BSIM4sd = value->rValue; |
|||
here->BSIM4sdGiven = TRUE; |
|||
break; |
|||
case BSIM4_SCA: |
|||
here->BSIM4sca = value->rValue; |
|||
here->BSIM4scaGiven = TRUE; |
|||
break; |
|||
case BSIM4_SCB: |
|||
here->BSIM4scb = value->rValue; |
|||
here->BSIM4scbGiven = TRUE; |
|||
break; |
|||
case BSIM4_SCC: |
|||
here->BSIM4scc = value->rValue; |
|||
here->BSIM4sccGiven = TRUE; |
|||
break; |
|||
case BSIM4_SC: |
|||
here->BSIM4sc = value->rValue; |
|||
here->BSIM4scGiven = TRUE; |
|||
break; |
|||
case BSIM4_RBSB: |
|||
here->BSIM4rbsb = value->rValue; |
|||
here->BSIM4rbsbGiven = TRUE; |
|||
break; |
|||
case BSIM4_RBDB: |
|||
here->BSIM4rbdb = value->rValue; |
|||
here->BSIM4rbdbGiven = TRUE; |
|||
break; |
|||
case BSIM4_RBPB: |
|||
here->BSIM4rbpb = value->rValue; |
|||
here->BSIM4rbpbGiven = TRUE; |
|||
break; |
|||
case BSIM4_RBPS: |
|||
here->BSIM4rbps = value->rValue; |
|||
here->BSIM4rbpsGiven = TRUE; |
|||
break; |
|||
case BSIM4_RBPD: |
|||
here->BSIM4rbpd = value->rValue; |
|||
here->BSIM4rbpdGiven = TRUE; |
|||
break; |
|||
case BSIM4_DELVTO: |
|||
here->BSIM4delvto = value->rValue; |
|||
here->BSIM4delvtoGiven = TRUE; |
|||
break; |
|||
case BSIM4_XGW: |
|||
here->BSIM4xgw = value->rValue; |
|||
here->BSIM4xgwGiven = TRUE; |
|||
break; |
|||
case BSIM4_NGCON: |
|||
here->BSIM4ngcon = value->rValue; |
|||
here->BSIM4ngconGiven = TRUE; |
|||
break; |
|||
case BSIM4_TRNQSMOD: |
|||
here->BSIM4trnqsMod = value->iValue; |
|||
here->BSIM4trnqsModGiven = TRUE; |
|||
break; |
|||
case BSIM4_ACNQSMOD: |
|||
here->BSIM4acnqsMod = value->iValue; |
|||
here->BSIM4acnqsModGiven = TRUE; |
|||
break; |
|||
case BSIM4_RBODYMOD: |
|||
here->BSIM4rbodyMod = value->iValue; |
|||
here->BSIM4rbodyModGiven = TRUE; |
|||
break; |
|||
case BSIM4_RGATEMOD: |
|||
here->BSIM4rgateMod = value->iValue; |
|||
here->BSIM4rgateModGiven = TRUE; |
|||
break; |
|||
case BSIM4_GEOMOD: |
|||
here->BSIM4geoMod = value->iValue; |
|||
here->BSIM4geoModGiven = TRUE; |
|||
break; |
|||
case BSIM4_RGEOMOD: |
|||
here->BSIM4rgeoMod = value->iValue; |
|||
here->BSIM4rgeoModGiven = TRUE; |
|||
break; |
|||
case BSIM4_IC_VDS: |
|||
here->BSIM4icVDS = value->rValue; |
|||
here->BSIM4icVDSGiven = TRUE; |
|||
break; |
|||
case BSIM4_IC_VGS: |
|||
here->BSIM4icVGS = value->rValue; |
|||
here->BSIM4icVGSGiven = TRUE; |
|||
break; |
|||
case BSIM4_IC_VBS: |
|||
here->BSIM4icVBS = value->rValue; |
|||
here->BSIM4icVBSGiven = TRUE; |
|||
break; |
|||
case BSIM4_IC: |
|||
switch(value->v.numValue) |
|||
{ case 3: |
|||
here->BSIM4icVBS = *(value->v.vec.rVec+2); |
|||
here->BSIM4icVBSGiven = TRUE; |
|||
case 2: |
|||
here->BSIM4icVGS = *(value->v.vec.rVec+1); |
|||
here->BSIM4icVGSGiven = TRUE; |
|||
case 1: |
|||
here->BSIM4icVDS = *(value->v.vec.rVec); |
|||
here->BSIM4icVDSGiven = TRUE; |
|||
break; |
|||
default: |
|||
return(E_BADPARM); |
|||
} |
|||
break; |
|||
default: |
|||
return(E_BADPARM); |
|||
} |
|||
return(OK); |
|||
} |
|||
@ -0,0 +1,759 @@ |
|||
/**** BSIM4.7.0 Released by Darsen Lu 04/08/2011 ****/ |
|||
|
|||
/********** |
|||
* Copyright 2006 Regents of the University of California. All rights reserved. |
|||
* File: b4pzld.c of BSIM4.7.0. |
|||
* Author: 2000 Weidong Liu |
|||
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu. |
|||
* Authors: 2006- Mohan Dunga, Ali Niknejad, Chenming Hu |
|||
* Authors: 2007- Mohan Dunga, Wenwei Yang, Ali Niknejad, Chenming Hu |
|||
* Project Director: Prof. Chenming Hu. |
|||
* Modified by Xuemei Xi, 10/05/2001. |
|||
**********/ |
|||
|
|||
#include "ngspice/ngspice.h" |
|||
#include "ngspice/cktdefs.h" |
|||
#include "ngspice/complex.h" |
|||
#include "ngspice/sperror.h" |
|||
#include "bsim4def.h" |
|||
#include "ngspice/suffix.h" |
|||
|
|||
int |
|||
BSIM4pzLoad( |
|||
GENmodel *inModel, |
|||
CKTcircuit *ckt, |
|||
SPcomplex *s) |
|||
{ |
|||
BSIM4model *model = (BSIM4model*)inModel; |
|||
BSIM4instance *here; |
|||
|
|||
double gjbd, gjbs, geltd, gcrg, gcrgg, gcrgd, gcrgs, gcrgb; |
|||
double xcggb, xcgdb, xcgsb, xcgbb, xcbgb, xcbdb, xcbsb, xcbbb; |
|||
double xcdgb, xcddb, xcdsb, xcdbb, xcsgb, xcsdb, xcssb, xcsbb; |
|||
double gds, capbd, capbs, FwdSum, RevSum, Gm, Gmbs; |
|||
double gstot, gstotd, gstotg, gstots, gstotb, gspr; |
|||
double gdtot, gdtotd, gdtotg, gdtots, gdtotb, gdpr; |
|||
double gIstotg, gIstotd, gIstots, gIstotb; |
|||
double gIdtotg, gIdtotd, gIdtots, gIdtotb; |
|||
double gIbtotg, gIbtotd, gIbtots, gIbtotb; |
|||
double gIgtotg, gIgtotd, gIgtots, gIgtotb; |
|||
double cgso, cgdo, cgbo; |
|||
double xcdbdb=0.0, xcsbsb=0.0, xcgmgmb=0.0, xcgmdb=0.0, xcgmsb=0.0, xcdgmb=0.0, xcsgmb=0.0; |
|||
double xcgmbb=0.0, xcbgmb=0.0; |
|||
double dxpart, sxpart, xgtg, xgtd, xgts, xgtb, xcqgb=0.0, xcqdb=0.0, xcqsb=0.0, xcqbb=0.0; |
|||
double gbspsp, gbbdp, gbbsp, gbspg, gbspb; |
|||
double gbspdp, gbdpdp, gbdpg, gbdpb, gbdpsp; |
|||
double ddxpart_dVd, ddxpart_dVg, ddxpart_dVb, ddxpart_dVs; |
|||
double dsxpart_dVd, dsxpart_dVg, dsxpart_dVb, dsxpart_dVs; |
|||
double T0=0.0, T1, CoxWL, qcheq, Cdg, Cdd, Cds, Csg, Csd, Css; |
|||
double ScalingFactor = 1.0e-9; |
|||
struct bsim4SizeDependParam *pParam; |
|||
double ggidld, ggidlg, ggidlb, ggislg, ggislb, ggisls; |
|||
|
|||
double m; |
|||
|
|||
for (; model != NULL; model = model->BSIM4nextModel) |
|||
{ for (here = model->BSIM4instances; here!= NULL; |
|||
here = here->BSIM4nextInstance) |
|||
{ |
|||
pParam = here->pParam; |
|||
capbd = here->BSIM4capbd; |
|||
capbs = here->BSIM4capbs; |
|||
cgso = here->BSIM4cgso; |
|||
cgdo = here->BSIM4cgdo; |
|||
cgbo = pParam->BSIM4cgbo; |
|||
|
|||
if (here->BSIM4mode >= 0) |
|||
{ Gm = here->BSIM4gm; |
|||
Gmbs = here->BSIM4gmbs; |
|||
FwdSum = Gm + Gmbs; |
|||
RevSum = 0.0; |
|||
|
|||
gbbdp = -(here->BSIM4gbds); |
|||
gbbsp = here->BSIM4gbds + here->BSIM4gbgs + here->BSIM4gbbs; |
|||
gbdpg = here->BSIM4gbgs; |
|||
gbdpdp = here->BSIM4gbds; |
|||
gbdpb = here->BSIM4gbbs; |
|||
gbdpsp = -(gbdpg + gbdpdp + gbdpb); |
|||
|
|||
gbspdp = 0.0; |
|||
gbspg = 0.0; |
|||
gbspb = 0.0; |
|||
gbspsp = 0.0; |
|||
|
|||
if (model->BSIM4igcMod) |
|||
{ gIstotg = here->BSIM4gIgsg + here->BSIM4gIgcsg; |
|||
gIstotd = here->BSIM4gIgcsd; |
|||
gIstots = here->BSIM4gIgss + here->BSIM4gIgcss; |
|||
gIstotb = here->BSIM4gIgcsb; |
|||
|
|||
gIdtotg = here->BSIM4gIgdg + here->BSIM4gIgcdg; |
|||
gIdtotd = here->BSIM4gIgdd + here->BSIM4gIgcdd; |
|||
gIdtots = here->BSIM4gIgcds; |
|||
gIdtotb = here->BSIM4gIgcdb; |
|||
} |
|||
else |
|||
{ gIstotg = gIstotd = gIstots = gIstotb = 0.0; |
|||
gIdtotg = gIdtotd = gIdtots = gIdtotb = 0.0; |
|||
} |
|||
|
|||
if (model->BSIM4igbMod) |
|||
{ gIbtotg = here->BSIM4gIgbg; |
|||
gIbtotd = here->BSIM4gIgbd; |
|||
gIbtots = here->BSIM4gIgbs; |
|||
gIbtotb = here->BSIM4gIgbb; |
|||
} |
|||
else |
|||
gIbtotg = gIbtotd = gIbtots = gIbtotb = 0.0; |
|||
|
|||
if ((model->BSIM4igcMod != 0) || (model->BSIM4igbMod != 0)) |
|||
{ gIgtotg = gIstotg + gIdtotg + gIbtotg; |
|||
gIgtotd = gIstotd + gIdtotd + gIbtotd ; |
|||
gIgtots = gIstots + gIdtots + gIbtots; |
|||
gIgtotb = gIstotb + gIdtotb + gIbtotb; |
|||
} |
|||
else |
|||
gIgtotg = gIgtotd = gIgtots = gIgtotb = 0.0; |
|||
|
|||
if (here->BSIM4rgateMod == 2) |
|||
T0 = *(ckt->CKTstates[0] + here->BSIM4vges) |
|||
- *(ckt->CKTstates[0] + here->BSIM4vgs); |
|||
else if (here->BSIM4rgateMod == 3) |
|||
T0 = *(ckt->CKTstates[0] + here->BSIM4vgms) |
|||
- *(ckt->CKTstates[0] + here->BSIM4vgs); |
|||
if (here->BSIM4rgateMod > 1) |
|||
{ gcrgd = here->BSIM4gcrgd * T0; |
|||
gcrgg = here->BSIM4gcrgg * T0; |
|||
gcrgs = here->BSIM4gcrgs * T0; |
|||
gcrgb = here->BSIM4gcrgb * T0; |
|||
gcrgg -= here->BSIM4gcrg; |
|||
gcrg = here->BSIM4gcrg; |
|||
} |
|||
else |
|||
gcrg = gcrgd = gcrgg = gcrgs = gcrgb = 0.0; |
|||
|
|||
if (here->BSIM4acnqsMod == 0) |
|||
{ if (here->BSIM4rgateMod == 3) |
|||
{ xcgmgmb = cgdo + cgso + pParam->BSIM4cgbo; |
|||
xcgmdb = -cgdo; |
|||
xcgmsb = -cgso; |
|||
xcgmbb = -pParam->BSIM4cgbo; |
|||
|
|||
xcdgmb = xcgmdb; |
|||
xcsgmb = xcgmsb; |
|||
xcbgmb = xcgmbb; |
|||
|
|||
xcggb = here->BSIM4cggb; |
|||
xcgdb = here->BSIM4cgdb; |
|||
xcgsb = here->BSIM4cgsb; |
|||
xcgbb = -(xcggb + xcgdb + xcgsb); |
|||
|
|||
xcdgb = here->BSIM4cdgb; |
|||
xcsgb = -(here->BSIM4cggb + here->BSIM4cbgb |
|||
+ here->BSIM4cdgb); |
|||
xcbgb = here->BSIM4cbgb; |
|||
} |
|||
else |
|||
{ xcggb = here->BSIM4cggb + cgdo + cgso |
|||
+ pParam->BSIM4cgbo; |
|||
xcgdb = here->BSIM4cgdb - cgdo; |
|||
xcgsb = here->BSIM4cgsb - cgso; |
|||
xcgbb = -(xcggb + xcgdb + xcgsb); |
|||
|
|||
xcdgb = here->BSIM4cdgb - cgdo; |
|||
xcsgb = -(here->BSIM4cggb + here->BSIM4cbgb |
|||
+ here->BSIM4cdgb + cgso); |
|||
xcbgb = here->BSIM4cbgb - pParam->BSIM4cgbo; |
|||
|
|||
xcdgmb = xcsgmb = xcbgmb = 0.0; |
|||
} |
|||
xcddb = here->BSIM4cddb + here->BSIM4capbd + cgdo; |
|||
xcdsb = here->BSIM4cdsb; |
|||
|
|||
xcsdb = -(here->BSIM4cgdb + here->BSIM4cbdb |
|||
+ here->BSIM4cddb); |
|||
xcssb = here->BSIM4capbs + cgso - (here->BSIM4cgsb |
|||
+ here->BSIM4cbsb + here->BSIM4cdsb); |
|||
|
|||
if (!here->BSIM4rbodyMod) |
|||
{ xcdbb = -(xcdgb + xcddb + xcdsb + xcdgmb); |
|||
xcsbb = -(xcsgb + xcsdb + xcssb + xcsgmb); |
|||
xcbdb = here->BSIM4cbdb - here->BSIM4capbd; |
|||
xcbsb = here->BSIM4cbsb - here->BSIM4capbs; |
|||
xcdbdb = 0.0; |
|||
} |
|||
else |
|||
{ xcdbb = -(here->BSIM4cddb + here->BSIM4cdgb |
|||
+ here->BSIM4cdsb); |
|||
xcsbb = -(xcsgb + xcsdb + xcssb + xcsgmb) |
|||
+ here->BSIM4capbs; |
|||
xcbdb = here->BSIM4cbdb; |
|||
xcbsb = here->BSIM4cbsb; |
|||
|
|||
xcdbdb = -here->BSIM4capbd; |
|||
xcsbsb = -here->BSIM4capbs; |
|||
} |
|||
xcbbb = -(xcbdb + xcbgb + xcbsb + xcbgmb); |
|||
|
|||
xgtg = xgtd = xgts = xgtb = 0.0; |
|||
sxpart = 0.6; |
|||
dxpart = 0.4; |
|||
ddxpart_dVd = ddxpart_dVg = ddxpart_dVb |
|||
= ddxpart_dVs = 0.0; |
|||
dsxpart_dVd = dsxpart_dVg = dsxpart_dVb |
|||
= dsxpart_dVs = 0.0; |
|||
} |
|||
else |
|||
{ xcggb = xcgdb = xcgsb = xcgbb = 0.0; |
|||
xcbgb = xcbdb = xcbsb = xcbbb = 0.0; |
|||
xcdgb = xcddb = xcdsb = xcdbb = 0.0; |
|||
xcsgb = xcsdb = xcssb = xcsbb = 0.0; |
|||
|
|||
xgtg = here->BSIM4gtg; |
|||
xgtd = here->BSIM4gtd; |
|||
xgts = here->BSIM4gts; |
|||
xgtb = here->BSIM4gtb; |
|||
|
|||
xcqgb = here->BSIM4cqgb; |
|||
xcqdb = here->BSIM4cqdb; |
|||
xcqsb = here->BSIM4cqsb; |
|||
xcqbb = here->BSIM4cqbb; |
|||
|
|||
CoxWL = model->BSIM4coxe * here->pParam->BSIM4weffCV |
|||
* here->BSIM4nf * here->pParam->BSIM4leffCV; |
|||
qcheq = -(here->BSIM4qgate + here->BSIM4qbulk); |
|||
if (fabs(qcheq) <= 1.0e-5 * CoxWL) |
|||
{ if (model->BSIM4xpart < 0.5) |
|||
{ dxpart = 0.4; |
|||
} |
|||
else if (model->BSIM4xpart > 0.5) |
|||
{ dxpart = 0.0; |
|||
} |
|||
else |
|||
{ dxpart = 0.5; |
|||
} |
|||
ddxpart_dVd = ddxpart_dVg = ddxpart_dVb |
|||
= ddxpart_dVs = 0.0; |
|||
} |
|||
else |
|||
{ dxpart = here->BSIM4qdrn / qcheq; |
|||
Cdd = here->BSIM4cddb; |
|||
Csd = -(here->BSIM4cgdb + here->BSIM4cddb |
|||
+ here->BSIM4cbdb); |
|||
ddxpart_dVd = (Cdd - dxpart * (Cdd + Csd)) / qcheq; |
|||
Cdg = here->BSIM4cdgb; |
|||
Csg = -(here->BSIM4cggb + here->BSIM4cdgb |
|||
+ here->BSIM4cbgb); |
|||
ddxpart_dVg = (Cdg - dxpart * (Cdg + Csg)) / qcheq; |
|||
|
|||
Cds = here->BSIM4cdsb; |
|||
Css = -(here->BSIM4cgsb + here->BSIM4cdsb |
|||
+ here->BSIM4cbsb); |
|||
ddxpart_dVs = (Cds - dxpart * (Cds + Css)) / qcheq; |
|||
|
|||
ddxpart_dVb = -(ddxpart_dVd + ddxpart_dVg |
|||
+ ddxpart_dVs); |
|||
} |
|||
sxpart = 1.0 - dxpart; |
|||
dsxpart_dVd = -ddxpart_dVd; |
|||
dsxpart_dVg = -ddxpart_dVg; |
|||
dsxpart_dVs = -ddxpart_dVs; |
|||
dsxpart_dVb = -(dsxpart_dVd + dsxpart_dVg + dsxpart_dVs); |
|||
} |
|||
} |
|||
else |
|||
{ Gm = -here->BSIM4gm; |
|||
Gmbs = -here->BSIM4gmbs; |
|||
FwdSum = 0.0; |
|||
RevSum = -(Gm + Gmbs); |
|||
|
|||
gbbsp = -(here->BSIM4gbds); |
|||
gbbdp = here->BSIM4gbds + here->BSIM4gbgs + here->BSIM4gbbs; |
|||
|
|||
gbdpg = 0.0; |
|||
gbdpsp = 0.0; |
|||
gbdpb = 0.0; |
|||
gbdpdp = 0.0; |
|||
|
|||
gbspg = here->BSIM4gbgs; |
|||
gbspsp = here->BSIM4gbds; |
|||
gbspb = here->BSIM4gbbs; |
|||
gbspdp = -(gbspg + gbspsp + gbspb); |
|||
|
|||
if (model->BSIM4igcMod) |
|||
{ gIstotg = here->BSIM4gIgsg + here->BSIM4gIgcdg; |
|||
gIstotd = here->BSIM4gIgcds; |
|||
gIstots = here->BSIM4gIgss + here->BSIM4gIgcdd; |
|||
gIstotb = here->BSIM4gIgcdb; |
|||
|
|||
gIdtotg = here->BSIM4gIgdg + here->BSIM4gIgcsg; |
|||
gIdtotd = here->BSIM4gIgdd + here->BSIM4gIgcss; |
|||
gIdtots = here->BSIM4gIgcsd; |
|||
gIdtotb = here->BSIM4gIgcsb; |
|||
} |
|||
else |
|||
{ gIstotg = gIstotd = gIstots = gIstotb = 0.0; |
|||
gIdtotg = gIdtotd = gIdtots = gIdtotb = 0.0; |
|||
} |
|||
|
|||
if (model->BSIM4igbMod) |
|||
{ gIbtotg = here->BSIM4gIgbg; |
|||
gIbtotd = here->BSIM4gIgbs; |
|||
gIbtots = here->BSIM4gIgbd; |
|||
gIbtotb = here->BSIM4gIgbb; |
|||
} |
|||
else |
|||
gIbtotg = gIbtotd = gIbtots = gIbtotb = 0.0; |
|||
|
|||
if ((model->BSIM4igcMod != 0) || (model->BSIM4igbMod != 0)) |
|||
{ gIgtotg = gIstotg + gIdtotg + gIbtotg; |
|||
gIgtotd = gIstotd + gIdtotd + gIbtotd ; |
|||
gIgtots = gIstots + gIdtots + gIbtots; |
|||
gIgtotb = gIstotb + gIdtotb + gIbtotb; |
|||
} |
|||
else |
|||
gIgtotg = gIgtotd = gIgtots = gIgtotb = 0.0; |
|||
|
|||
if (here->BSIM4rgateMod == 2) |
|||
T0 = *(ckt->CKTstates[0] + here->BSIM4vges) |
|||
- *(ckt->CKTstates[0] + here->BSIM4vgs); |
|||
else if (here->BSIM4rgateMod == 3) |
|||
T0 = *(ckt->CKTstates[0] + here->BSIM4vgms) |
|||
- *(ckt->CKTstates[0] + here->BSIM4vgs); |
|||
if (here->BSIM4rgateMod > 1) |
|||
{ gcrgd = here->BSIM4gcrgs * T0; |
|||
gcrgg = here->BSIM4gcrgg * T0; |
|||
gcrgs = here->BSIM4gcrgd * T0; |
|||
gcrgb = here->BSIM4gcrgb * T0; |
|||
gcrgg -= here->BSIM4gcrg; |
|||
gcrg = here->BSIM4gcrg; |
|||
} |
|||
else |
|||
gcrg = gcrgd = gcrgg = gcrgs = gcrgb = 0.0; |
|||
|
|||
if (here->BSIM4acnqsMod == 0) |
|||
{ if (here->BSIM4rgateMod == 3) |
|||
{ xcgmgmb = cgdo + cgso + pParam->BSIM4cgbo; |
|||
xcgmdb = -cgdo; |
|||
xcgmsb = -cgso; |
|||
xcgmbb = -pParam->BSIM4cgbo; |
|||
|
|||
xcdgmb = xcgmdb; |
|||
xcsgmb = xcgmsb; |
|||
xcbgmb = xcgmbb; |
|||
|
|||
xcggb = here->BSIM4cggb; |
|||
xcgdb = here->BSIM4cgsb; |
|||
xcgsb = here->BSIM4cgdb; |
|||
xcgbb = -(xcggb + xcgdb + xcgsb); |
|||
|
|||
xcdgb = -(here->BSIM4cggb + here->BSIM4cbgb |
|||
+ here->BSIM4cdgb); |
|||
xcsgb = here->BSIM4cdgb; |
|||
xcbgb = here->BSIM4cbgb; |
|||
} |
|||
else |
|||
{ xcggb = here->BSIM4cggb + cgdo + cgso |
|||
+ pParam->BSIM4cgbo; |
|||
xcgdb = here->BSIM4cgsb - cgdo; |
|||
xcgsb = here->BSIM4cgdb - cgso; |
|||
xcgbb = -(xcggb + xcgdb + xcgsb); |
|||
|
|||
xcdgb = -(here->BSIM4cggb + here->BSIM4cbgb |
|||
+ here->BSIM4cdgb + cgdo); |
|||
xcsgb = here->BSIM4cdgb - cgso; |
|||
xcbgb = here->BSIM4cbgb - pParam->BSIM4cgbo; |
|||
|
|||
xcdgmb = xcsgmb = xcbgmb = 0.0; |
|||
} |
|||
xcddb = here->BSIM4capbd + cgdo - (here->BSIM4cgsb |
|||
+ here->BSIM4cbsb + here->BSIM4cdsb); |
|||
xcdsb = -(here->BSIM4cgdb + here->BSIM4cbdb |
|||
+ here->BSIM4cddb); |
|||
|
|||
xcsdb = here->BSIM4cdsb; |
|||
xcssb = here->BSIM4cddb + here->BSIM4capbs + cgso; |
|||
|
|||
if (!here->BSIM4rbodyMod) |
|||
{ xcdbb = -(xcdgb + xcddb + xcdsb + xcdgmb); |
|||
xcsbb = -(xcsgb + xcsdb + xcssb + xcsgmb); |
|||
xcbdb = here->BSIM4cbsb - here->BSIM4capbd; |
|||
xcbsb = here->BSIM4cbdb - here->BSIM4capbs; |
|||
xcdbdb = 0.0; |
|||
} |
|||
else |
|||
{ xcdbb = -(xcdgb + xcddb + xcdsb + xcdgmb) |
|||
+ here->BSIM4capbd; |
|||
xcsbb = -(here->BSIM4cddb + here->BSIM4cdgb |
|||
+ here->BSIM4cdsb); |
|||
xcbdb = here->BSIM4cbsb; |
|||
xcbsb = here->BSIM4cbdb; |
|||
xcdbdb = -here->BSIM4capbd; |
|||
xcsbsb = -here->BSIM4capbs; |
|||
} |
|||
xcbbb = -(xcbgb + xcbdb + xcbsb + xcbgmb); |
|||
|
|||
xgtg = xgtd = xgts = xgtb = 0.0; |
|||
sxpart = 0.4; |
|||
dxpart = 0.6; |
|||
ddxpart_dVd = ddxpart_dVg = ddxpart_dVb |
|||
= ddxpart_dVs = 0.0; |
|||
dsxpart_dVd = dsxpart_dVg = dsxpart_dVb |
|||
= dsxpart_dVs = 0.0; |
|||
} |
|||
else |
|||
{ xcggb = xcgdb = xcgsb = xcgbb = 0.0; |
|||
xcbgb = xcbdb = xcbsb = xcbbb = 0.0; |
|||
xcdgb = xcddb = xcdsb = xcdbb = 0.0; |
|||
xcsgb = xcsdb = xcssb = xcsbb = 0.0; |
|||
|
|||
xgtg = here->BSIM4gtg; |
|||
xgtd = here->BSIM4gts; |
|||
xgts = here->BSIM4gtd; |
|||
xgtb = here->BSIM4gtb; |
|||
|
|||
xcqgb = here->BSIM4cqgb; |
|||
xcqdb = here->BSIM4cqsb; |
|||
xcqsb = here->BSIM4cqdb; |
|||
xcqbb = here->BSIM4cqbb; |
|||
|
|||
CoxWL = model->BSIM4coxe * here->pParam->BSIM4weffCV |
|||
* here->BSIM4nf * here->pParam->BSIM4leffCV; |
|||
qcheq = -(here->BSIM4qgate + here->BSIM4qbulk); |
|||
if (fabs(qcheq) <= 1.0e-5 * CoxWL) |
|||
{ if (model->BSIM4xpart < 0.5) |
|||
{ sxpart = 0.4; |
|||
} |
|||
else if (model->BSIM4xpart > 0.5) |
|||
{ sxpart = 0.0; |
|||
} |
|||
else |
|||
{ sxpart = 0.5; |
|||
} |
|||
dsxpart_dVd = dsxpart_dVg = dsxpart_dVb |
|||
= dsxpart_dVs = 0.0; |
|||
} |
|||
else |
|||
{ sxpart = here->BSIM4qdrn / qcheq; |
|||
Css = here->BSIM4cddb; |
|||
Cds = -(here->BSIM4cgdb + here->BSIM4cddb |
|||
+ here->BSIM4cbdb); |
|||
dsxpart_dVs = (Css - sxpart * (Css + Cds)) / qcheq; |
|||
Csg = here->BSIM4cdgb; |
|||
Cdg = -(here->BSIM4cggb + here->BSIM4cdgb |
|||
+ here->BSIM4cbgb); |
|||
dsxpart_dVg = (Csg - sxpart * (Csg + Cdg)) / qcheq; |
|||
|
|||
Csd = here->BSIM4cdsb; |
|||
Cdd = -(here->BSIM4cgsb + here->BSIM4cdsb |
|||
+ here->BSIM4cbsb); |
|||
dsxpart_dVd = (Csd - sxpart * (Csd + Cdd)) / qcheq; |
|||
|
|||
dsxpart_dVb = -(dsxpart_dVd + dsxpart_dVg |
|||
+ dsxpart_dVs); |
|||
} |
|||
dxpart = 1.0 - sxpart; |
|||
ddxpart_dVd = -dsxpart_dVd; |
|||
ddxpart_dVg = -dsxpart_dVg; |
|||
ddxpart_dVs = -dsxpart_dVs; |
|||
ddxpart_dVb = -(ddxpart_dVd + ddxpart_dVg + ddxpart_dVs); |
|||
} |
|||
} |
|||
|
|||
if (model->BSIM4rdsMod == 1) |
|||
{ gstot = here->BSIM4gstot; |
|||
gstotd = here->BSIM4gstotd; |
|||
gstotg = here->BSIM4gstotg; |
|||
gstots = here->BSIM4gstots - gstot; |
|||
gstotb = here->BSIM4gstotb; |
|||
|
|||
gdtot = here->BSIM4gdtot; |
|||
gdtotd = here->BSIM4gdtotd - gdtot; |
|||
gdtotg = here->BSIM4gdtotg; |
|||
gdtots = here->BSIM4gdtots; |
|||
gdtotb = here->BSIM4gdtotb; |
|||
} |
|||
else |
|||
{ gstot = gstotd = gstotg = gstots = gstotb = 0.0; |
|||
gdtot = gdtotd = gdtotg = gdtots = gdtotb = 0.0; |
|||
} |
|||
|
|||
|
|||
T1 = *(ckt->CKTstate0 + here->BSIM4qdef) * here->BSIM4gtau; |
|||
gds = here->BSIM4gds; |
|||
|
|||
/* |
|||
* Loading PZ matrix |
|||
*/ |
|||
m = here->BSIM4m; |
|||
|
|||
if (!model->BSIM4rdsMod) |
|||
{ gdpr = here->BSIM4drainConductance; |
|||
gspr = here->BSIM4sourceConductance; |
|||
} |
|||
else |
|||
gdpr = gspr = 0.0; |
|||
|
|||
if (!here->BSIM4rbodyMod) |
|||
{ gjbd = here->BSIM4gbd; |
|||
gjbs = here->BSIM4gbs; |
|||
} |
|||
else |
|||
gjbd = gjbs = 0.0; |
|||
|
|||
geltd = here->BSIM4grgeltd; |
|||
|
|||
if (here->BSIM4rgateMod == 1) |
|||
{ *(here->BSIM4GEgePtr) += m * geltd; |
|||
*(here->BSIM4GPgePtr) -= m * geltd; |
|||
*(here->BSIM4GEgpPtr) -= m * geltd; |
|||
|
|||
*(here->BSIM4GPgpPtr ) += m * xcggb * s->real; |
|||
*(here->BSIM4GPgpPtr +1) += m * xcggb * s->imag; |
|||
*(here->BSIM4GPgpPtr) += m * (geltd - xgtg + gIgtotg); |
|||
*(here->BSIM4GPdpPtr ) += m * xcgdb * s->real; |
|||
*(here->BSIM4GPdpPtr +1) += m * xcgdb * s->imag; |
|||
*(here->BSIM4GPdpPtr) -= m * (xgtd - gIgtotd); |
|||
*(here->BSIM4GPspPtr ) += m * xcgsb * s->real; |
|||
*(here->BSIM4GPspPtr +1) += m * xcgsb * s->imag; |
|||
*(here->BSIM4GPspPtr) -= m * (xgts - gIgtots); |
|||
*(here->BSIM4GPbpPtr ) += m * xcgbb * s->real; |
|||
*(here->BSIM4GPbpPtr +1) += m * xcgbb * s->imag; |
|||
*(here->BSIM4GPbpPtr) -= m * (xgtb - gIgtotb); |
|||
} |
|||
else if (here->BSIM4rgateMod == 2) |
|||
{ *(here->BSIM4GEgePtr) += m * gcrg; |
|||
*(here->BSIM4GEgpPtr) += m * gcrgg; |
|||
*(here->BSIM4GEdpPtr) += m * gcrgd; |
|||
*(here->BSIM4GEspPtr) += m * gcrgs; |
|||
*(here->BSIM4GEbpPtr) += m * gcrgb; |
|||
|
|||
*(here->BSIM4GPgePtr) -= m * gcrg; |
|||
*(here->BSIM4GPgpPtr ) += m * xcggb * s->real; |
|||
*(here->BSIM4GPgpPtr +1) += m * xcggb * s->imag; |
|||
*(here->BSIM4GPgpPtr) -= m * (gcrgg + xgtg - gIgtotg); |
|||
*(here->BSIM4GPdpPtr ) += m * xcgdb * s->real; |
|||
*(here->BSIM4GPdpPtr +1) += m * xcgdb * s->imag; |
|||
*(here->BSIM4GPdpPtr) -= m * (gcrgd + xgtd - gIgtotd); |
|||
*(here->BSIM4GPspPtr ) += m * xcgsb * s->real; |
|||
*(here->BSIM4GPspPtr +1) += m * xcgsb * s->imag; |
|||
*(here->BSIM4GPspPtr) -= m * (gcrgs + xgts - gIgtots); |
|||
*(here->BSIM4GPbpPtr ) += m * xcgbb * s->real; |
|||
*(here->BSIM4GPbpPtr +1) += m * xcgbb * s->imag; |
|||
*(here->BSIM4GPbpPtr) -= m * (gcrgb + xgtb - gIgtotb); |
|||
} |
|||
else if (here->BSIM4rgateMod == 3) |
|||
{ *(here->BSIM4GEgePtr) += m * geltd; |
|||
*(here->BSIM4GEgmPtr) -= m * geltd; |
|||
*(here->BSIM4GMgePtr) -= m * geltd; |
|||
*(here->BSIM4GMgmPtr) += m * (geltd + gcrg); |
|||
*(here->BSIM4GMgmPtr ) += m * xcgmgmb * s->real; |
|||
*(here->BSIM4GMgmPtr +1) += m * xcgmgmb * s->imag; |
|||
|
|||
*(here->BSIM4GMdpPtr) += m * gcrgd; |
|||
*(here->BSIM4GMdpPtr ) += m * xcgmdb * s->real; |
|||
*(here->BSIM4GMdpPtr +1) += m * xcgmdb * s->imag; |
|||
*(here->BSIM4GMgpPtr) += m * gcrgg; |
|||
*(here->BSIM4GMspPtr) += m * gcrgs; |
|||
*(here->BSIM4GMspPtr ) += m * xcgmsb * s->real; |
|||
*(here->BSIM4GMspPtr +1) += m * xcgmsb * s->imag; |
|||
*(here->BSIM4GMbpPtr) += m * gcrgb; |
|||
*(here->BSIM4GMbpPtr ) += m * xcgmbb * s->real; |
|||
*(here->BSIM4GMbpPtr +1) += m * xcgmbb * s->imag; |
|||
|
|||
*(here->BSIM4DPgmPtr ) += m * xcdgmb * s->real; |
|||
*(here->BSIM4DPgmPtr +1) += m * xcdgmb * s->imag; |
|||
*(here->BSIM4GPgmPtr) -= m * gcrg; |
|||
*(here->BSIM4SPgmPtr ) += m * xcsgmb * s->real; |
|||
*(here->BSIM4SPgmPtr +1) += m * xcsgmb * s->imag; |
|||
*(here->BSIM4BPgmPtr ) += m * xcbgmb * s->real; |
|||
*(here->BSIM4BPgmPtr +1) += m * xcbgmb * s->imag; |
|||
|
|||
*(here->BSIM4GPgpPtr) -= m * (gcrgg + xgtg - gIgtotg); |
|||
*(here->BSIM4GPgpPtr ) += m * xcggb * s->real; |
|||
*(here->BSIM4GPgpPtr +1) += m * xcggb * s->imag; |
|||
*(here->BSIM4GPdpPtr) -= m * (gcrgd + xgtd - gIgtotd); |
|||
*(here->BSIM4GPdpPtr ) += m * xcgdb * s->real; |
|||
*(here->BSIM4GPdpPtr +1) += m * xcgdb * s->imag; |
|||
*(here->BSIM4GPspPtr) -= m * (gcrgs + xgts - gIgtots); |
|||
*(here->BSIM4GPspPtr ) += m * xcgsb * s->real; |
|||
*(here->BSIM4GPspPtr +1) += m * xcgsb * s->imag; |
|||
*(here->BSIM4GPbpPtr) -= m * (gcrgb + xgtb - gIgtotb); |
|||
*(here->BSIM4GPbpPtr ) += m * xcgbb * s->real; |
|||
*(here->BSIM4GPbpPtr +1) += m * xcgbb * s->imag; |
|||
} |
|||
else |
|||
{ *(here->BSIM4GPdpPtr ) += m * xcgdb * s->real; |
|||
*(here->BSIM4GPdpPtr +1) += m * xcgdb * s->imag; |
|||
*(here->BSIM4GPdpPtr) -= m * (xgtd - gIgtotd); |
|||
*(here->BSIM4GPgpPtr ) += m * xcggb * s->real; |
|||
*(here->BSIM4GPgpPtr +1) += m * xcggb * s->imag; |
|||
*(here->BSIM4GPgpPtr) -= m * (xgtg - gIgtotg); |
|||
*(here->BSIM4GPspPtr ) += m * xcgsb * s->real; |
|||
*(here->BSIM4GPspPtr +1) += m * xcgsb * s->imag; |
|||
*(here->BSIM4GPspPtr) -= m * (xgts - gIgtots); |
|||
*(here->BSIM4GPbpPtr ) += m * xcgbb * s->real; |
|||
*(here->BSIM4GPbpPtr +1) += m * xcgbb * s->imag; |
|||
*(here->BSIM4GPbpPtr) -= m * (xgtb - gIgtotb); |
|||
} |
|||
|
|||
if (model->BSIM4rdsMod) |
|||
{ (*(here->BSIM4DgpPtr) += m * gdtotg); |
|||
(*(here->BSIM4DspPtr) += m * gdtots); |
|||
(*(here->BSIM4DbpPtr) += m * gdtotb); |
|||
(*(here->BSIM4SdpPtr) += m * gstotd); |
|||
(*(here->BSIM4SgpPtr) += m * gstotg); |
|||
(*(here->BSIM4SbpPtr) += m * gstotb); |
|||
} |
|||
|
|||
*(here->BSIM4DPdpPtr ) += m * xcddb * s->real; |
|||
*(here->BSIM4DPdpPtr +1) += m * xcddb * s->imag; |
|||
*(here->BSIM4DPdpPtr) += m * (gdpr + gds + here->BSIM4gbd |
|||
- gdtotd + RevSum + gbdpdp - gIdtotd |
|||
+ dxpart * xgtd + T1 * ddxpart_dVd); |
|||
*(here->BSIM4DPdPtr) -= m * (gdpr + gdtot); |
|||
*(here->BSIM4DPgpPtr ) += m * xcdgb * s->real; |
|||
*(here->BSIM4DPgpPtr +1) += m * xcdgb * s->imag; |
|||
*(here->BSIM4DPgpPtr) += m * (Gm - gdtotg + gbdpg - gIdtotg |
|||
+ T1 * ddxpart_dVg + dxpart * xgtg); |
|||
*(here->BSIM4DPspPtr ) += m * xcdsb * s->real; |
|||
*(here->BSIM4DPspPtr +1) += m * xcdsb * s->imag; |
|||
*(here->BSIM4DPspPtr) -= m * (gds + FwdSum + gdtots - gbdpsp + gIdtots |
|||
- T1 * ddxpart_dVs - dxpart * xgts); |
|||
*(here->BSIM4DPbpPtr ) += m * xcdbb * s->real; |
|||
*(here->BSIM4DPbpPtr +1) += m * xcdbb * s->imag; |
|||
*(here->BSIM4DPbpPtr) -= m * (gjbd + gdtotb - Gmbs - gbdpb + gIdtotb |
|||
- T1 * ddxpart_dVb - dxpart * xgtb); |
|||
|
|||
*(here->BSIM4DdpPtr) -= m * (gdpr - gdtotd); |
|||
*(here->BSIM4DdPtr) += m * (gdpr + gdtot); |
|||
|
|||
*(here->BSIM4SPdpPtr ) += m * xcsdb * s->real; |
|||
*(here->BSIM4SPdpPtr +1) += m * xcsdb * s->imag; |
|||
*(here->BSIM4SPdpPtr) -= m * (gds + gstotd + RevSum - gbspdp + gIstotd |
|||
- T1 * dsxpart_dVd - sxpart * xgtd); |
|||
*(here->BSIM4SPgpPtr ) += m * xcsgb * s->real; |
|||
*(here->BSIM4SPgpPtr +1) += m * xcsgb * s->imag; |
|||
*(here->BSIM4SPgpPtr) -= m * (Gm + gstotg - gbspg + gIstotg |
|||
- T1 * dsxpart_dVg - sxpart * xgtg); |
|||
*(here->BSIM4SPspPtr ) += m * xcssb * s->real; |
|||
*(here->BSIM4SPspPtr +1) += m * xcssb * s->imag; |
|||
*(here->BSIM4SPspPtr) += m * (gspr + gds + here->BSIM4gbs - gIstots |
|||
- gstots + FwdSum + gbspsp |
|||
+ sxpart * xgts + T1 * dsxpart_dVs); |
|||
*(here->BSIM4SPsPtr) -= m * (gspr + gstot); |
|||
*(here->BSIM4SPbpPtr ) += m * xcsbb * s->real; |
|||
*(here->BSIM4SPbpPtr +1) += m * xcsbb * s->imag; |
|||
*(here->BSIM4SPbpPtr) -= m * (gjbs + gstotb + Gmbs - gbspb + gIstotb |
|||
- T1 * dsxpart_dVb - sxpart * xgtb); |
|||
|
|||
*(here->BSIM4SspPtr) -= m * (gspr - gstots); |
|||
*(here->BSIM4SsPtr) += m * (gspr + gstot); |
|||
|
|||
*(here->BSIM4BPdpPtr ) += m * xcbdb * s->real; |
|||
*(here->BSIM4BPdpPtr +1) += m * xcbdb * s->imag; |
|||
*(here->BSIM4BPdpPtr) -= m * (gjbd - gbbdp + gIbtotd); |
|||
*(here->BSIM4BPgpPtr ) += m * xcbgb * s->real; |
|||
*(here->BSIM4BPgpPtr +1) += m * xcbgb * s->imag; |
|||
*(here->BSIM4BPgpPtr) -= m * (here->BSIM4gbgs + gIbtotg); |
|||
*(here->BSIM4BPspPtr ) += m * xcbsb * s->real; |
|||
*(here->BSIM4BPspPtr +1) += m * xcbsb * s->imag; |
|||
*(here->BSIM4BPspPtr) -= m * (gjbs - gbbsp + gIbtots); |
|||
*(here->BSIM4BPbpPtr ) += m * xcbbb * s->real; |
|||
*(here->BSIM4BPbpPtr +1) += m * xcbbb * s->imag; |
|||
*(here->BSIM4BPbpPtr) += m * (gjbd + gjbs - here->BSIM4gbbs |
|||
- gIbtotb); |
|||
ggidld = here->BSIM4ggidld; |
|||
ggidlg = here->BSIM4ggidlg; |
|||
ggidlb = here->BSIM4ggidlb; |
|||
ggislg = here->BSIM4ggislg; |
|||
ggisls = here->BSIM4ggisls; |
|||
ggislb = here->BSIM4ggislb; |
|||
|
|||
/* stamp gidl */ |
|||
(*(here->BSIM4DPdpPtr) += m * ggidld); |
|||
(*(here->BSIM4DPgpPtr) += m * ggidlg); |
|||
(*(here->BSIM4DPspPtr) -= m * ((ggidlg + ggidld) + ggidlb)); |
|||
(*(here->BSIM4DPbpPtr) += m * ggidlb); |
|||
(*(here->BSIM4BPdpPtr) -= m * ggidld); |
|||
(*(here->BSIM4BPgpPtr) -= m * ggidlg); |
|||
(*(here->BSIM4BPspPtr) += m * ((ggidlg + ggidld) + ggidlb)); |
|||
(*(here->BSIM4BPbpPtr) -= m * ggidlb); |
|||
/* stamp gisl */ |
|||
(*(here->BSIM4SPdpPtr) -= m * ((ggisls + ggislg) + ggislb)); |
|||
(*(here->BSIM4SPgpPtr) += m * ggislg); |
|||
(*(here->BSIM4SPspPtr) += m * ggisls); |
|||
(*(here->BSIM4SPbpPtr) += m * ggislb); |
|||
(*(here->BSIM4BPdpPtr) += m * ((ggislg + ggisls) + ggislb)); |
|||
(*(here->BSIM4BPgpPtr) -= m * ggislg); |
|||
(*(here->BSIM4BPspPtr) -= m * ggisls); |
|||
(*(here->BSIM4BPbpPtr) -= m * ggislb); |
|||
|
|||
if (here->BSIM4rbodyMod) |
|||
{ (*(here->BSIM4DPdbPtr ) += m * xcdbdb * s->real); |
|||
(*(here->BSIM4DPdbPtr +1) += m * xcdbdb * s->imag); |
|||
(*(here->BSIM4DPdbPtr) -= m * here->BSIM4gbd); |
|||
(*(here->BSIM4SPsbPtr ) += m * xcsbsb * s->real); |
|||
(*(here->BSIM4SPsbPtr +1) += m * xcsbsb * s->imag); |
|||
(*(here->BSIM4SPsbPtr) -= m * here->BSIM4gbs); |
|||
|
|||
(*(here->BSIM4DBdpPtr ) += m * xcdbdb * s->real); |
|||
(*(here->BSIM4DBdpPtr +1) += m * xcdbdb * s->imag); |
|||
(*(here->BSIM4DBdpPtr) -= m * here->BSIM4gbd); |
|||
(*(here->BSIM4DBdbPtr ) -= m * xcdbdb * s->real); |
|||
(*(here->BSIM4DBdbPtr +1) -= m * xcdbdb * s->imag); |
|||
(*(here->BSIM4DBdbPtr) += m * (here->BSIM4gbd + here->BSIM4grbpd |
|||
+ here->BSIM4grbdb)); |
|||
(*(here->BSIM4DBbpPtr) -= m * here->BSIM4grbpd); |
|||
(*(here->BSIM4DBbPtr) -= m * here->BSIM4grbdb); |
|||
|
|||
(*(here->BSIM4BPdbPtr) -= m * here->BSIM4grbpd); |
|||
(*(here->BSIM4BPbPtr) -= m * here->BSIM4grbpb); |
|||
(*(here->BSIM4BPsbPtr) -= m * here->BSIM4grbps); |
|||
(*(here->BSIM4BPbpPtr) += m * (here->BSIM4grbpd + here->BSIM4grbps |
|||
+ here->BSIM4grbpb)); |
|||
/* WDL: (-here->BSIM4gbbs) already added to BPbpPtr */ |
|||
|
|||
(*(here->BSIM4SBspPtr ) += m * xcsbsb * s->real); |
|||
(*(here->BSIM4SBspPtr +1) += m * xcsbsb * s->imag); |
|||
(*(here->BSIM4SBspPtr) -= m * here->BSIM4gbs); |
|||
(*(here->BSIM4SBbpPtr) -= m * here->BSIM4grbps); |
|||
(*(here->BSIM4SBbPtr) -= m * here->BSIM4grbsb); |
|||
(*(here->BSIM4SBsbPtr ) -= m * xcsbsb * s->real); |
|||
(*(here->BSIM4SBsbPtr +1) -= m * xcsbsb * s->imag); |
|||
(*(here->BSIM4SBsbPtr) += m * (here->BSIM4gbs |
|||
+ here->BSIM4grbps + here->BSIM4grbsb)); |
|||
|
|||
(*(here->BSIM4BdbPtr) -= m * here->BSIM4grbdb); |
|||
(*(here->BSIM4BbpPtr) -= m * here->BSIM4grbpb); |
|||
(*(here->BSIM4BsbPtr) -= m * here->BSIM4grbsb); |
|||
(*(here->BSIM4BbPtr) += m * (here->BSIM4grbsb + here->BSIM4grbdb |
|||
+ here->BSIM4grbpb)); |
|||
} |
|||
|
|||
if (here->BSIM4acnqsMod) |
|||
{ *(here->BSIM4QqPtr ) += m * s->real * ScalingFactor; |
|||
*(here->BSIM4QqPtr +1) += m * s->imag * ScalingFactor; |
|||
*(here->BSIM4QgpPtr ) -= m * xcqgb * s->real; |
|||
*(here->BSIM4QgpPtr +1) -= m * xcqgb * s->imag; |
|||
*(here->BSIM4QdpPtr ) -= m * xcqdb * s->real; |
|||
*(here->BSIM4QdpPtr +1) -= m * xcqdb * s->imag; |
|||
*(here->BSIM4QbpPtr ) -= m * xcqbb * s->real; |
|||
*(here->BSIM4QbpPtr +1) -= m * xcqbb * s->imag; |
|||
*(here->BSIM4QspPtr ) -= m * xcqsb * s->real; |
|||
*(here->BSIM4QspPtr +1) -= m * xcqsb * s->imag; |
|||
|
|||
*(here->BSIM4GPqPtr) -= m * here->BSIM4gtau; |
|||
*(here->BSIM4DPqPtr) += m * dxpart * here->BSIM4gtau; |
|||
*(here->BSIM4SPqPtr) += m * sxpart * here->BSIM4gtau; |
|||
|
|||
*(here->BSIM4QqPtr) += m * here->BSIM4gtau; |
|||
*(here->BSIM4QgpPtr) += m * xgtg; |
|||
*(here->BSIM4QdpPtr) += m * xgtd; |
|||
*(here->BSIM4QbpPtr) += m * xgtb; |
|||
*(here->BSIM4QspPtr) += m * xgts; |
|||
} |
|||
} |
|||
} |
|||
return(OK); |
|||
} |
|||
2640
src/spicelib/devices/bsim4v7/b4v7set.c
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,110 @@ |
|||
/********** |
|||
Copyright 2013 Dietmar Warning. All rights reserved. |
|||
Author: 2013 Dietmar Warning |
|||
**********/ |
|||
|
|||
#include "ngspice/ngspice.h" |
|||
#include "ngspice/cktdefs.h" |
|||
#include "bsim4def.h" |
|||
#include "ngspice/trandefs.h" |
|||
#include "ngspice/sperror.h" |
|||
#include "ngspice/suffix.h" |
|||
#include "ngspice/cpdefs.h" |
|||
|
|||
|
|||
int |
|||
BSIM4soaCheck(CKTcircuit *ckt, GENmodel *inModel) |
|||
{ |
|||
BSIM4model *model = (BSIM4model *) inModel; |
|||
BSIM4instance *here; |
|||
double vgs, vgd, vgb, vds, vbs, vbd; /* actual mos voltages */ |
|||
int maxwarns; |
|||
static int warns_vgs = 0, warns_vgd = 0, warns_vgb = 0, warns_vds = 0, warns_vbs = 0, warns_vbd = 0; |
|||
|
|||
if (!ckt) { |
|||
warns_vgs = 0; |
|||
warns_vgd = 0; |
|||
warns_vgb = 0; |
|||
warns_vds = 0; |
|||
warns_vbs = 0; |
|||
warns_vbd = 0; |
|||
return OK; |
|||
} |
|||
|
|||
maxwarns = ckt->CKTsoaMaxWarns; |
|||
|
|||
for (; model; model = model->BSIM4nextModel) { |
|||
|
|||
for (here = model->BSIM4instances; here; here = here->BSIM4nextInstance) { |
|||
|
|||
vgs = fabs(ckt->CKTrhsOld [here->BSIM4gNodePrime] - |
|||
ckt->CKTrhsOld [here->BSIM4sNodePrime]); |
|||
|
|||
vgd = fabs(ckt->CKTrhsOld [here->BSIM4gNodePrime] - |
|||
ckt->CKTrhsOld [here->BSIM4dNodePrime]); |
|||
|
|||
vgb = fabs(ckt->CKTrhsOld [here->BSIM4gNodePrime] - |
|||
ckt->CKTrhsOld [here->BSIM4bNodePrime]); |
|||
|
|||
vds = fabs(ckt->CKTrhsOld [here->BSIM4dNodePrime] - |
|||
ckt->CKTrhsOld [here->BSIM4sNodePrime]); |
|||
|
|||
vbs = fabs(ckt->CKTrhsOld [here->BSIM4bNodePrime] - |
|||
ckt->CKTrhsOld [here->BSIM4sNodePrime]); |
|||
|
|||
vbd = fabs(ckt->CKTrhsOld [here->BSIM4bNodePrime] - |
|||
ckt->CKTrhsOld [here->BSIM4dNodePrime]); |
|||
|
|||
if (vgs > model->BSIM4vgsMax) |
|||
if (warns_vgs < maxwarns) { |
|||
soa_printf(ckt, (GENinstance*) here, |
|||
"|Vgs|=%g has exceeded Vgs_max=%g\n", |
|||
vgs, model->BSIM4vgsMax); |
|||
warns_vgs++; |
|||
} |
|||
|
|||
if (vgd > model->BSIM4vgdMax) |
|||
if (warns_vgd < maxwarns) { |
|||
soa_printf(ckt, (GENinstance*) here, |
|||
"|Vgd|=%g has exceeded Vgd_max=%g\n", |
|||
vgd, model->BSIM4vgdMax); |
|||
warns_vgd++; |
|||
} |
|||
|
|||
if (vgb > model->BSIM4vgbMax) |
|||
if (warns_vgb < maxwarns) { |
|||
soa_printf(ckt, (GENinstance*) here, |
|||
"|Vgb|=%g has exceeded Vgb_max=%g\n", |
|||
vgb, model->BSIM4vgbMax); |
|||
warns_vgb++; |
|||
} |
|||
|
|||
if (vds > model->BSIM4vdsMax) |
|||
if (warns_vds < maxwarns) { |
|||
soa_printf(ckt, (GENinstance*) here, |
|||
"|Vds|=%g has exceeded Vds_max=%g\n", |
|||
vds, model->BSIM4vdsMax); |
|||
warns_vds++; |
|||
} |
|||
|
|||
if (vbs > model->BSIM4vbsMax) |
|||
if (warns_vbs < maxwarns) { |
|||
soa_printf(ckt, (GENinstance*) here, |
|||
"|Vbs|=%g has exceeded Vbs_max=%g\n", |
|||
vbs, model->BSIM4vbsMax); |
|||
warns_vbs++; |
|||
} |
|||
|
|||
if (vbd > model->BSIM4vbdMax) |
|||
if (warns_vbd < maxwarns) { |
|||
soa_printf(ckt, (GENinstance*) here, |
|||
"|Vbd|=%g has exceeded Vbd_max=%g\n", |
|||
vbd, model->BSIM4vbdMax); |
|||
warns_vbd++; |
|||
} |
|||
|
|||
} |
|||
} |
|||
|
|||
return OK; |
|||
} |
|||
2312
src/spicelib/devices/bsim4v7/b4v7temp.c
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,60 @@ |
|||
/**** BSIM4.7.0 Released by Darsen Lu 04/08/2011 ****/ |
|||
|
|||
/********** |
|||
* Copyright 2006 Regents of the University of California. All rights reserved. |
|||
* File: b4trunc.c of BSIM4.7.0. |
|||
* Author: 2000 Weidong Liu |
|||
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu. |
|||
* Authors: 2006- Mohan Dunga, Ali Niknejad, Chenming Hu |
|||
* Authors: 2007- Mohan Dunga, Wenwei Yang, Ali Niknejad, Chenming Hu |
|||
* Project Director: Prof. Chenming Hu. |
|||
**********/ |
|||
|
|||
#include "ngspice/ngspice.h" |
|||
#include "ngspice/cktdefs.h" |
|||
#include "bsim4def.h" |
|||
#include "ngspice/sperror.h" |
|||
#include "ngspice/suffix.h" |
|||
|
|||
|
|||
int |
|||
BSIM4trunc( |
|||
GENmodel *inModel, |
|||
CKTcircuit *ckt, |
|||
double *timeStep) |
|||
{ |
|||
BSIM4model *model = (BSIM4model*)inModel; |
|||
BSIM4instance *here; |
|||
|
|||
#ifdef STEPDEBUG |
|||
double debugtemp; |
|||
#endif /* STEPDEBUG */ |
|||
|
|||
for (; model != NULL; model = model->BSIM4nextModel) |
|||
{ for (here = model->BSIM4instances; here != NULL; |
|||
here = here->BSIM4nextInstance) |
|||
{ |
|||
#ifdef STEPDEBUG |
|||
debugtemp = *timeStep; |
|||
#endif /* STEPDEBUG */ |
|||
CKTterr(here->BSIM4qb,ckt,timeStep); |
|||
CKTterr(here->BSIM4qg,ckt,timeStep); |
|||
CKTterr(here->BSIM4qd,ckt,timeStep); |
|||
if (here->BSIM4trnqsMod) |
|||
CKTterr(here->BSIM4qcdump,ckt,timeStep); |
|||
if (here->BSIM4rbodyMod) |
|||
{ CKTterr(here->BSIM4qbs,ckt,timeStep); |
|||
CKTterr(here->BSIM4qbd,ckt,timeStep); |
|||
} |
|||
if (here->BSIM4rgateMod == 3) |
|||
CKTterr(here->BSIM4qgmid,ckt,timeStep); |
|||
#ifdef STEPDEBUG |
|||
if(debugtemp != *timeStep) |
|||
{ printf("device %s reduces step from %g to %g\n", |
|||
here->BSIM4name,debugtemp,*timeStep); |
|||
} |
|||
#endif /* STEPDEBUG */ |
|||
} |
|||
} |
|||
return(OK); |
|||
} |
|||
3775
src/spicelib/devices/bsim4v7/bsim4v7def.h
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,31 @@ |
|||
/********** |
|||
Copyright 2004 Regents of the University of California. All rights reserved. |
|||
Author: 2000 Weidong Liu |
|||
Author: 2001- Xuemei Xi |
|||
File: bsim4ext.h |
|||
**********/ |
|||
|
|||
extern int BSIM4acLoad(GENmodel *,CKTcircuit*); |
|||
extern int BSIM4ask(CKTcircuit *,GENinstance*,int,IFvalue*,IFvalue*); |
|||
extern int BSIM4convTest(GENmodel *,CKTcircuit*); |
|||
extern int BSIM4delete(GENmodel*,IFuid,GENinstance**); |
|||
extern void BSIM4destroy(GENmodel**); |
|||
extern int BSIM4getic(GENmodel*,CKTcircuit*); |
|||
extern int BSIM4load(GENmodel*,CKTcircuit*); |
|||
extern int BSIM4mAsk(CKTcircuit*,GENmodel *,int, IFvalue*); |
|||
extern int BSIM4mDelete(GENmodel**,IFuid,GENmodel*); |
|||
extern int BSIM4mParam(int,IFvalue*,GENmodel*); |
|||
extern void BSIM4mosCap(CKTcircuit*, double, double, double, double, |
|||
double, double, double, double, double, double, double, |
|||
double, double, double, double, double, double, double*, |
|||
double*, double*, double*, double*, double*, double*, double*, |
|||
double*, double*, double*, double*, double*, double*, double*, |
|||
double*); |
|||
extern int BSIM4param(int,IFvalue*,GENinstance*,IFvalue*); |
|||
extern int BSIM4pzLoad(GENmodel*,CKTcircuit*,SPcomplex*); |
|||
extern int BSIM4setup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); |
|||
extern int BSIM4temp(GENmodel*,CKTcircuit*); |
|||
extern int BSIM4trunc(GENmodel*,CKTcircuit*,double*); |
|||
extern int BSIM4noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); |
|||
extern int BSIM4unsetup(GENmodel*,CKTcircuit*); |
|||
extern int BSIM4soaCheck(CKTcircuit *, GENmodel *); |
|||
@ -0,0 +1,84 @@ |
|||
#include "ngspice/config.h" |
|||
|
|||
#include "ngspice/devdefs.h" |
|||
|
|||
#include "bsim4itf.h" |
|||
#include "bsim4ext.h" |
|||
#include "bsim4init.h" |
|||
|
|||
|
|||
SPICEdev BSIM4info = { |
|||
{ |
|||
"BSIM4", |
|||
"Berkeley Short Channel IGFET Model-4", |
|||
|
|||
&BSIM4nSize, |
|||
&BSIM4nSize, |
|||
BSIM4names, |
|||
|
|||
&BSIM4pTSize, |
|||
BSIM4pTable, |
|||
|
|||
&BSIM4mPTSize, |
|||
BSIM4mPTable, |
|||
|
|||
#ifdef XSPICE |
|||
/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ |
|||
NULL, /* This is a SPICE device, it has no MIF info data */ |
|||
|
|||
0, /* This is a SPICE device, it has no MIF info data */ |
|||
NULL, /* This is a SPICE device, it has no MIF info data */ |
|||
|
|||
0, /* This is a SPICE device, it has no MIF info data */ |
|||
NULL, /* This is a SPICE device, it has no MIF info data */ |
|||
|
|||
0, /* This is a SPICE device, it has no MIF info data */ |
|||
NULL, /* This is a SPICE device, it has no MIF info data */ |
|||
/*--------------------------- End of SDB fix -------------------------*/ |
|||
#endif |
|||
|
|||
DEV_DEFAULT |
|||
}, |
|||
|
|||
BSIM4param, /* DEVparam */ |
|||
BSIM4mParam, /* DEVmodParam */ |
|||
BSIM4load, /* DEVload */ |
|||
BSIM4setup, /* DEVsetup */ |
|||
BSIM4unsetup, /* DEVunsetup */ |
|||
BSIM4setup, /* DEVpzSetup */ |
|||
BSIM4temp, /* DEVtemperature */ |
|||
BSIM4trunc, /* DEVtrunc */ |
|||
NULL, /* DEVfindBranch */ |
|||
BSIM4acLoad, /* DEVacLoad */ |
|||
NULL, /* DEVaccept */ |
|||
BSIM4destroy, /* DEVdestroy */ |
|||
BSIM4mDelete, /* DEVmodDelete */ |
|||
BSIM4delete, /* DEVdelete */ |
|||
BSIM4getic, /* DEVsetic */ |
|||
BSIM4ask, /* DEVask */ |
|||
BSIM4mAsk, /* DEVmodAsk */ |
|||
BSIM4pzLoad, /* DEVpzLoad */ |
|||
BSIM4convTest, /* DEVconvTest */ |
|||
NULL, /* DEVsenSetup */ |
|||
NULL, /* DEVsenLoad */ |
|||
NULL, /* DEVsenUpdate */ |
|||
NULL, /* DEVsenAcLoad */ |
|||
NULL, /* DEVsenPrint */ |
|||
NULL, /* DEVsenTrunc */ |
|||
NULL, /* DEVdisto */ |
|||
BSIM4noise, /* DEVnoise */ |
|||
BSIM4soaCheck, /* DEVsoaCheck */ |
|||
#ifdef CIDER |
|||
NULL, /* DEVdump */ |
|||
NULL, /* DEVacct */ |
|||
#endif |
|||
&BSIM4iSize, /* DEVinstSize */ |
|||
&BSIM4mSize /* DEVmodSize */ |
|||
}; |
|||
|
|||
|
|||
SPICEdev * |
|||
get_bsim4_info(void) |
|||
{ |
|||
return &BSIM4info; |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
#ifndef _BSIM4INIT_H |
|||
#define _BSIM4INIT_H |
|||
|
|||
extern IFparm BSIM4pTable[ ]; |
|||
extern IFparm BSIM4mPTable[ ]; |
|||
extern char *BSIM4names[ ]; |
|||
extern int BSIM4pTSize; |
|||
extern int BSIM4mPTSize; |
|||
extern int BSIM4nSize; |
|||
extern int BSIM4iSize; |
|||
extern int BSIM4mSize; |
|||
|
|||
#endif |
|||
@ -0,0 +1,13 @@ |
|||
/********** |
|||
Copyright 2004 Regents of the University of California. All rights reserved. |
|||
Author: 2000 Weidong Liu. |
|||
Author: 2001- Xuemei Xi |
|||
File: bsim4itf.h |
|||
**********/ |
|||
|
|||
#ifndef DEV_BSIM4 |
|||
#define DEV_BSIM4 |
|||
|
|||
SPICEdev *get_bsim4_info(void); |
|||
|
|||
#endif |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue