devices/bsim4v7, new directory, plain copy from devices/bsim4
This commit is contained in:
parent
cba69c4850
commit
7e4128c60a
|
|
@ -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
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -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);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
Loading…
Reference in New Issue