devices/bsim4v7, new directory, plain copy from devices/bsim4

This commit is contained in:
dwarning 2014-05-19 22:34:09 +02:00 committed by rlar
parent cba69c4850
commit 7e4128c60a
27 changed files with 26467 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,673 @@
/**** BSIM4.7.0 Released by Darsen Lu 04/08/2011 ****/
/**********
* Copyright 2006 Regents of the University of California. All rights reserved.
* File: b4acld.c of BSIM4.7.0.
* Author: 2000 Weidong Liu
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu.
* Authors: 2006- Mohan Dunga, Ali Niknejad, Chenming Hu
* Authors: 2007- Mohan Dunga, Wenwei Yang, Ali Niknejad, Chenming Hu
* Project Director: Prof. Chenming Hu.
* Modified by Xuemei Xi, 10/05/2001.
**********/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "bsim4def.h"
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
int
BSIM4acLoad(
GENmodel *inModel,
CKTcircuit *ckt)
{
BSIM4model *model = (BSIM4model*)inModel;
BSIM4instance *here;
double gjbd, gjbs, geltd, gcrg, gcrgg, gcrgd, gcrgs, gcrgb;
double xcbgb, xcbdb, xcbsb, xcbbb;
double xcggbr, xcgdbr, xcgsbr, xcgbbr, xcggbi, xcgdbi, xcgsbi, xcgbbi;
double Cggr, Cgdr, Cgsr, Cgbr, Cggi, Cgdi, Cgsi, Cgbi;
double xcddbr, xcdgbr, xcdsbr, xcdbbr, xcsdbr, xcsgbr, xcssbr, xcsbbr;
double xcddbi, xcdgbi, xcdsbi, xcdbbi, xcsdbi, xcsgbi, xcssbi, xcsbbi;
double xcdbdb, xcsbsb=0.0, xcgmgmb=0.0, xcgmdb=0.0, xcgmsb=0.0, xcdgmb, xcsgmb;
double xcgmbb=0.0, xcbgmb;
double capbd, capbs, omega;
double gstot, gstotd, gstotg, gstots, gstotb, gspr;
double gdtot, gdtotd, gdtotg, gdtots, gdtotb, gdpr;
double gIstotg, gIstotd, gIstots, gIstotb;
double gIdtotg, gIdtotd, gIdtots, gIdtotb;
double gIbtotg, gIbtotd, gIbtots, gIbtotb;
double gIgtotg, gIgtotd, gIgtots, gIgtotb;
double cgso, cgdo, cgbo;
double gbspsp, gbbdp, gbbsp, gbspg, gbspb;
double gbspdp, gbdpdp, gbdpg, gbdpb, gbdpsp;
double T0=0.0, T1, T2, T3;
double Csg, Csd, Css;
double Cdgr, Cddr, Cdsr, Cdbr, Csgr, Csdr, Cssr, Csbr;
double Cdgi, Cddi, Cdsi, Cdbi, Csgi, Csdi, Cssi, Csbi;
double gmr, gmi, gmbsr, gmbsi, gdsr, gdsi;
double FwdSumr, RevSumr, Gmr, Gmbsr;
double FwdSumi, RevSumi, Gmi, Gmbsi;
struct bsim4SizeDependParam *pParam;
double ggidld, ggidlg, ggidlb, ggislg, ggislb, ggisls;
double m;
omega = ckt->CKTomega;
for (; model != NULL; model = model->BSIM4nextModel)
{ for (here = model->BSIM4instances; here!= NULL;
here = here->BSIM4nextInstance)
{
pParam = here->pParam;
capbd = here->BSIM4capbd;
capbs = here->BSIM4capbs;
cgso = here->BSIM4cgso;
cgdo = here->BSIM4cgdo;
cgbo = pParam->BSIM4cgbo;
Csd = -(here->BSIM4cddb + here->BSIM4cgdb + here->BSIM4cbdb);
Csg = -(here->BSIM4cdgb + here->BSIM4cggb + here->BSIM4cbgb);
Css = -(here->BSIM4cdsb + here->BSIM4cgsb + here->BSIM4cbsb);
if (here->BSIM4acnqsMod)
{ T0 = omega * here->BSIM4taunet;
T1 = T0 * T0;
T2 = 1.0 / (1.0 + T1);
T3 = T0 * T2;
gmr = here->BSIM4gm * T2;
gmbsr = here->BSIM4gmbs * T2;
gdsr = here->BSIM4gds * T2;
gmi = -here->BSIM4gm * T3;
gmbsi = -here->BSIM4gmbs * T3;
gdsi = -here->BSIM4gds * T3;
Cddr = here->BSIM4cddb * T2;
Cdgr = here->BSIM4cdgb * T2;
Cdsr = here->BSIM4cdsb * T2;
Cdbr = -(Cddr + Cdgr + Cdsr);
/* WDLiu: Cxyi mulitplied by jomega below, and actually to be of conductance */
Cddi = here->BSIM4cddb * T3 * omega;
Cdgi = here->BSIM4cdgb * T3 * omega;
Cdsi = here->BSIM4cdsb * T3 * omega;
Cdbi = -(Cddi + Cdgi + Cdsi);
Csdr = Csd * T2;
Csgr = Csg * T2;
Cssr = Css * T2;
Csbr = -(Csdr + Csgr + Cssr);
Csdi = Csd * T3 * omega;
Csgi = Csg * T3 * omega;
Cssi = Css * T3 * omega;
Csbi = -(Csdi + Csgi + Cssi);
Cgdr = -(Cddr + Csdr + here->BSIM4cbdb);
Cggr = -(Cdgr + Csgr + here->BSIM4cbgb);
Cgsr = -(Cdsr + Cssr + here->BSIM4cbsb);
Cgbr = -(Cgdr + Cggr + Cgsr);
Cgdi = -(Cddi + Csdi);
Cggi = -(Cdgi + Csgi);
Cgsi = -(Cdsi + Cssi);
Cgbi = -(Cgdi + Cggi + Cgsi);
}
else /* QS */
{ gmr = here->BSIM4gm;
gmbsr = here->BSIM4gmbs;
gdsr = here->BSIM4gds;
gmi = gmbsi = gdsi = 0.0;
Cddr = here->BSIM4cddb;
Cdgr = here->BSIM4cdgb;
Cdsr = here->BSIM4cdsb;
Cdbr = -(Cddr + Cdgr + Cdsr);
Cddi = Cdgi = Cdsi = Cdbi = 0.0;
Csdr = Csd;
Csgr = Csg;
Cssr = Css;
Csbr = -(Csdr + Csgr + Cssr);
Csdi = Csgi = Cssi = Csbi = 0.0;
Cgdr = here->BSIM4cgdb;
Cggr = here->BSIM4cggb;
Cgsr = here->BSIM4cgsb;
Cgbr = -(Cgdr + Cggr + Cgsr);
Cgdi = Cggi = Cgsi = Cgbi = 0.0;
}
if (here->BSIM4mode >= 0)
{ Gmr = gmr;
Gmbsr = gmbsr;
FwdSumr = Gmr + Gmbsr;
RevSumr = 0.0;
Gmi = gmi;
Gmbsi = gmbsi;
FwdSumi = Gmi + Gmbsi;
RevSumi = 0.0;
gbbdp = -(here->BSIM4gbds);
gbbsp = here->BSIM4gbds + here->BSIM4gbgs + here->BSIM4gbbs;
gbdpg = here->BSIM4gbgs;
gbdpdp = here->BSIM4gbds;
gbdpb = here->BSIM4gbbs;
gbdpsp = -(gbdpg + gbdpdp + gbdpb);
gbspdp = 0.0;
gbspg = 0.0;
gbspb = 0.0;
gbspsp = 0.0;
if (model->BSIM4igcMod)
{ gIstotg = here->BSIM4gIgsg + here->BSIM4gIgcsg;
gIstotd = here->BSIM4gIgcsd;
gIstots = here->BSIM4gIgss + here->BSIM4gIgcss;
gIstotb = here->BSIM4gIgcsb;
gIdtotg = here->BSIM4gIgdg + here->BSIM4gIgcdg;
gIdtotd = here->BSIM4gIgdd + here->BSIM4gIgcdd;
gIdtots = here->BSIM4gIgcds;
gIdtotb = here->BSIM4gIgcdb;
}
else
{ gIstotg = gIstotd = gIstots = gIstotb = 0.0;
gIdtotg = gIdtotd = gIdtots = gIdtotb = 0.0;
}
if (model->BSIM4igbMod)
{ gIbtotg = here->BSIM4gIgbg;
gIbtotd = here->BSIM4gIgbd;
gIbtots = here->BSIM4gIgbs;
gIbtotb = here->BSIM4gIgbb;
}
else
gIbtotg = gIbtotd = gIbtots = gIbtotb = 0.0;
if ((model->BSIM4igcMod != 0) || (model->BSIM4igbMod != 0))
{ gIgtotg = gIstotg + gIdtotg + gIbtotg;
gIgtotd = gIstotd + gIdtotd + gIbtotd ;
gIgtots = gIstots + gIdtots + gIbtots;
gIgtotb = gIstotb + gIdtotb + gIbtotb;
}
else
gIgtotg = gIgtotd = gIgtots = gIgtotb = 0.0;
if (here->BSIM4rgateMod == 2)
T0 = *(ckt->CKTstates[0] + here->BSIM4vges)
- *(ckt->CKTstates[0] + here->BSIM4vgs);
else if (here->BSIM4rgateMod == 3)
T0 = *(ckt->CKTstates[0] + here->BSIM4vgms)
- *(ckt->CKTstates[0] + here->BSIM4vgs);
if (here->BSIM4rgateMod > 1)
{ gcrgd = here->BSIM4gcrgd * T0;
gcrgg = here->BSIM4gcrgg * T0;
gcrgs = here->BSIM4gcrgs * T0;
gcrgb = here->BSIM4gcrgb * T0;
gcrgg -= here->BSIM4gcrg;
gcrg = here->BSIM4gcrg;
}
else
gcrg = gcrgd = gcrgg = gcrgs = gcrgb = 0.0;
if (here->BSIM4rgateMod == 3)
{ xcgmgmb = (cgdo + cgso + pParam->BSIM4cgbo) * omega;
xcgmdb = -cgdo * omega;
xcgmsb = -cgso * omega;
xcgmbb = -pParam->BSIM4cgbo * omega;
xcdgmb = xcgmdb;
xcsgmb = xcgmsb;
xcbgmb = xcgmbb;
xcggbr = Cggr * omega;
xcgdbr = Cgdr * omega;
xcgsbr = Cgsr * omega;
xcgbbr = -(xcggbr + xcgdbr + xcgsbr);
xcdgbr = Cdgr * omega;
xcsgbr = Csgr * omega;
xcbgb = here->BSIM4cbgb * omega;
}
else
{ xcggbr = (Cggr + cgdo + cgso + pParam->BSIM4cgbo ) * omega;
xcgdbr = (Cgdr - cgdo) * omega;
xcgsbr = (Cgsr - cgso) * omega;
xcgbbr = -(xcggbr + xcgdbr + xcgsbr);
xcdgbr = (Cdgr - cgdo) * omega;
xcsgbr = (Csgr - cgso) * omega;
xcbgb = (here->BSIM4cbgb - pParam->BSIM4cgbo) * omega;
xcdgmb = xcsgmb = xcbgmb = 0.0;
}
xcddbr = (Cddr + here->BSIM4capbd + cgdo) * omega;
xcdsbr = Cdsr * omega;
xcsdbr = Csdr * omega;
xcssbr = (here->BSIM4capbs + cgso + Cssr) * omega;
if (!here->BSIM4rbodyMod)
{ xcdbbr = -(xcdgbr + xcddbr + xcdsbr + xcdgmb);
xcsbbr = -(xcsgbr + xcsdbr + xcssbr + xcsgmb);
xcbdb = (here->BSIM4cbdb - here->BSIM4capbd) * omega;
xcbsb = (here->BSIM4cbsb - here->BSIM4capbs) * omega;
xcdbdb = 0.0;
}
else
{ xcdbbr = Cdbr * omega;
xcsbbr = -(xcsgbr + xcsdbr + xcssbr + xcsgmb)
+ here->BSIM4capbs * omega;
xcbdb = here->BSIM4cbdb * omega;
xcbsb = here->BSIM4cbsb * omega;
xcdbdb = -here->BSIM4capbd * omega;
xcsbsb = -here->BSIM4capbs * omega;
}
xcbbb = -(xcbdb + xcbgb + xcbsb + xcbgmb);
xcdgbi = Cdgi;
xcsgbi = Csgi;
xcddbi = Cddi;
xcdsbi = Cdsi;
xcsdbi = Csdi;
xcssbi = Cssi;
xcdbbi = Cdbi;
xcsbbi = Csbi;
xcggbi = Cggi;
xcgdbi = Cgdi;
xcgsbi = Cgsi;
xcgbbi = Cgbi;
}
else /* Reverse mode */
{ Gmr = -gmr;
Gmbsr = -gmbsr;
FwdSumr = 0.0;
RevSumr = -(Gmr + Gmbsr);
Gmi = -gmi;
Gmbsi = -gmbsi;
FwdSumi = 0.0;
RevSumi = -(Gmi + Gmbsi);
gbbsp = -(here->BSIM4gbds);
gbbdp = here->BSIM4gbds + here->BSIM4gbgs + here->BSIM4gbbs;
gbdpg = 0.0;
gbdpsp = 0.0;
gbdpb = 0.0;
gbdpdp = 0.0;
gbspg = here->BSIM4gbgs;
gbspsp = here->BSIM4gbds;
gbspb = here->BSIM4gbbs;
gbspdp = -(gbspg + gbspsp + gbspb);
if (model->BSIM4igcMod)
{ gIstotg = here->BSIM4gIgsg + here->BSIM4gIgcdg;
gIstotd = here->BSIM4gIgcds;
gIstots = here->BSIM4gIgss + here->BSIM4gIgcdd;
gIstotb = here->BSIM4gIgcdb;
gIdtotg = here->BSIM4gIgdg + here->BSIM4gIgcsg;
gIdtotd = here->BSIM4gIgdd + here->BSIM4gIgcss;
gIdtots = here->BSIM4gIgcsd;
gIdtotb = here->BSIM4gIgcsb;
}
else
{ gIstotg = gIstotd = gIstots = gIstotb = 0.0;
gIdtotg = gIdtotd = gIdtots = gIdtotb = 0.0;
}
if (model->BSIM4igbMod)
{ gIbtotg = here->BSIM4gIgbg;
gIbtotd = here->BSIM4gIgbs;
gIbtots = here->BSIM4gIgbd;
gIbtotb = here->BSIM4gIgbb;
}
else
gIbtotg = gIbtotd = gIbtots = gIbtotb = 0.0;
if ((model->BSIM4igcMod != 0) || (model->BSIM4igbMod != 0))
{ gIgtotg = gIstotg + gIdtotg + gIbtotg;
gIgtotd = gIstotd + gIdtotd + gIbtotd ;
gIgtots = gIstots + gIdtots + gIbtots;
gIgtotb = gIstotb + gIdtotb + gIbtotb;
}
else
gIgtotg = gIgtotd = gIgtots = gIgtotb = 0.0;
if (here->BSIM4rgateMod == 2)
T0 = *(ckt->CKTstates[0] + here->BSIM4vges)
- *(ckt->CKTstates[0] + here->BSIM4vgs);
else if (here->BSIM4rgateMod == 3)
T0 = *(ckt->CKTstates[0] + here->BSIM4vgms)
- *(ckt->CKTstates[0] + here->BSIM4vgs);
if (here->BSIM4rgateMod > 1)
{ gcrgd = here->BSIM4gcrgs * T0;
gcrgg = here->BSIM4gcrgg * T0;
gcrgs = here->BSIM4gcrgd * T0;
gcrgb = here->BSIM4gcrgb * T0;
gcrgg -= here->BSIM4gcrg;
gcrg = here->BSIM4gcrg;
}
else
gcrg = gcrgd = gcrgg = gcrgs = gcrgb = 0.0;
if (here->BSIM4rgateMod == 3)
{ xcgmgmb = (cgdo + cgso + pParam->BSIM4cgbo) * omega;
xcgmdb = -cgdo * omega;
xcgmsb = -cgso * omega;
xcgmbb = -pParam->BSIM4cgbo * omega;
xcdgmb = xcgmdb;
xcsgmb = xcgmsb;
xcbgmb = xcgmbb;
xcggbr = Cggr * omega;
xcgdbr = Cgsr * omega;
xcgsbr = Cgdr * omega;
xcgbbr = -(xcggbr + xcgdbr + xcgsbr);
xcdgbr = Csgr * omega;
xcsgbr = Cdgr * omega;
xcbgb = here->BSIM4cbgb * omega;
}
else
{ xcggbr = (Cggr + cgdo + cgso + pParam->BSIM4cgbo ) * omega;
xcgdbr = (Cgsr - cgdo) * omega;
xcgsbr = (Cgdr - cgso) * omega;
xcgbbr = -(xcggbr + xcgdbr + xcgsbr);
xcdgbr = (Csgr - cgdo) * omega;
xcsgbr = (Cdgr - cgso) * omega;
xcbgb = (here->BSIM4cbgb - pParam->BSIM4cgbo) * omega;
xcdgmb = xcsgmb = xcbgmb = 0.0;
}
xcddbr = (here->BSIM4capbd + cgdo + Cssr) * omega;
xcdsbr = Csdr * omega;
xcsdbr = Cdsr * omega;
xcssbr = (Cddr + here->BSIM4capbs + cgso) * omega;
if (!here->BSIM4rbodyMod)
{ xcdbbr = -(xcdgbr + xcddbr + xcdsbr + xcdgmb);
xcsbbr = -(xcsgbr + xcsdbr + xcssbr + xcsgmb);
xcbdb = (here->BSIM4cbsb - here->BSIM4capbd) * omega;
xcbsb = (here->BSIM4cbdb - here->BSIM4capbs) * omega;
xcdbdb = 0.0;
}
else
{ xcdbbr = -(xcdgbr + xcddbr + xcdsbr + xcdgmb)
+ here->BSIM4capbd * omega;
xcsbbr = Cdbr * omega;
xcbdb = here->BSIM4cbsb * omega;
xcbsb = here->BSIM4cbdb * omega;
xcdbdb = -here->BSIM4capbd * omega;
xcsbsb = -here->BSIM4capbs * omega;
}
xcbbb = -(xcbgb + xcbdb + xcbsb + xcbgmb);
xcdgbi = Csgi;
xcsgbi = Cdgi;
xcddbi = Cssi;
xcdsbi = Csdi;
xcsdbi = Cdsi;
xcssbi = Cddi;
xcdbbi = Csbi;
xcsbbi = Cdbi;
xcggbi = Cggi;
xcgdbi = Cgsi;
xcgsbi = Cgdi;
xcgbbi = Cgbi;
}
if (model->BSIM4rdsMod == 1)
{ gstot = here->BSIM4gstot;
gstotd = here->BSIM4gstotd;
gstotg = here->BSIM4gstotg;
gstots = here->BSIM4gstots - gstot;
gstotb = here->BSIM4gstotb;
gdtot = here->BSIM4gdtot;
gdtotd = here->BSIM4gdtotd - gdtot;
gdtotg = here->BSIM4gdtotg;
gdtots = here->BSIM4gdtots;
gdtotb = here->BSIM4gdtotb;
}
else
{ gstot = gstotd = gstotg = gstots = gstotb = 0.0;
gdtot = gdtotd = gdtotg = gdtots = gdtotb = 0.0;
}
/*
* Loading AC matrix
*/
m = here->BSIM4m;
if (!model->BSIM4rdsMod)
{ gdpr = here->BSIM4drainConductance;
gspr = here->BSIM4sourceConductance;
}
else
gdpr = gspr = 0.0;
if (!here->BSIM4rbodyMod)
{ gjbd = here->BSIM4gbd;
gjbs = here->BSIM4gbs;
}
else
gjbd = gjbs = 0.0;
geltd = here->BSIM4grgeltd;
if (here->BSIM4rgateMod == 1)
{ *(here->BSIM4GEgePtr) += m * geltd;
*(here->BSIM4GPgePtr) -= m * geltd;
*(here->BSIM4GEgpPtr) -= m * geltd;
*(here->BSIM4GPgpPtr +1) += m * xcggbr;
*(here->BSIM4GPgpPtr) += m * (geltd + xcggbi + gIgtotg);
*(here->BSIM4GPdpPtr +1) += m * xcgdbr;
*(here->BSIM4GPdpPtr) += m * (xcgdbi + gIgtotd);
*(here->BSIM4GPspPtr +1) += m * xcgsbr;
*(here->BSIM4GPspPtr) += m * (xcgsbi + gIgtots);
*(here->BSIM4GPbpPtr +1) += m * xcgbbr;
*(here->BSIM4GPbpPtr) += m * (xcgbbi + gIgtotb);
} /* WDLiu: gcrg already subtracted from all gcrgg below */
else if (here->BSIM4rgateMod == 2)
{ *(here->BSIM4GEgePtr) += m * gcrg;
*(here->BSIM4GEgpPtr) += m * gcrgg;
*(here->BSIM4GEdpPtr) += m * gcrgd;
*(here->BSIM4GEspPtr) += m * gcrgs;
*(here->BSIM4GEbpPtr) += m * gcrgb;
*(here->BSIM4GPgePtr) -= m * gcrg;
*(here->BSIM4GPgpPtr +1) += m * xcggbr;
*(here->BSIM4GPgpPtr) -= m * (gcrgg - xcggbi - gIgtotg);
*(here->BSIM4GPdpPtr +1) += m * xcgdbr;
*(here->BSIM4GPdpPtr) -= m * (gcrgd - xcgdbi - gIgtotd);
*(here->BSIM4GPspPtr +1) += m * xcgsbr;
*(here->BSIM4GPspPtr) -= m * (gcrgs - xcgsbi - gIgtots);
*(here->BSIM4GPbpPtr +1) += m * xcgbbr;
*(here->BSIM4GPbpPtr) -= m * (gcrgb - xcgbbi - gIgtotb);
}
else if (here->BSIM4rgateMod == 3)
{ *(here->BSIM4GEgePtr) += m * geltd;
*(here->BSIM4GEgmPtr) -= m * geltd;
*(here->BSIM4GMgePtr) -= m * geltd;
*(here->BSIM4GMgmPtr) += m * (geltd + gcrg);
*(here->BSIM4GMgmPtr +1) += m * xcgmgmb;
*(here->BSIM4GMdpPtr) += m * gcrgd;
*(here->BSIM4GMdpPtr +1) += m * xcgmdb;
*(here->BSIM4GMgpPtr) += m * gcrgg;
*(here->BSIM4GMspPtr) += m * gcrgs;
*(here->BSIM4GMspPtr +1) += m * xcgmsb;
*(here->BSIM4GMbpPtr) += m * gcrgb;
*(here->BSIM4GMbpPtr +1) += m * xcgmbb;
*(here->BSIM4DPgmPtr +1) += m * xcdgmb;
*(here->BSIM4GPgmPtr) -= m * gcrg;
*(here->BSIM4SPgmPtr +1) += m * xcsgmb;
*(here->BSIM4BPgmPtr +1) += m * xcbgmb;
*(here->BSIM4GPgpPtr) -= m * (gcrgg - xcggbi - gIgtotg);
*(here->BSIM4GPgpPtr +1) += m * xcggbr;
*(here->BSIM4GPdpPtr) -= m * (gcrgd - xcgdbi - gIgtotd);
*(here->BSIM4GPdpPtr +1) += m * xcgdbr;
*(here->BSIM4GPspPtr) -= m * (gcrgs - xcgsbi - gIgtots);
*(here->BSIM4GPspPtr +1) += m * xcgsbr;
*(here->BSIM4GPbpPtr) -= m * (gcrgb - xcgbbi - gIgtotb);
*(here->BSIM4GPbpPtr +1) += m * xcgbbr;
}
else
{ *(here->BSIM4GPgpPtr +1) += m * xcggbr;
*(here->BSIM4GPgpPtr) += m * (xcggbi + gIgtotg);
*(here->BSIM4GPdpPtr +1) += m * xcgdbr;
*(here->BSIM4GPdpPtr) += m * (xcgdbi + gIgtotd);
*(here->BSIM4GPspPtr +1) += m * xcgsbr;
*(here->BSIM4GPspPtr) += m * (xcgsbi + gIgtots);
*(here->BSIM4GPbpPtr +1) += m * xcgbbr;
*(here->BSIM4GPbpPtr) += m * (xcgbbi + gIgtotb);
}
if (model->BSIM4rdsMod)
{ (*(here->BSIM4DgpPtr) += m * gdtotg);
(*(here->BSIM4DspPtr) += m * gdtots);
(*(here->BSIM4DbpPtr) += m * gdtotb);
(*(here->BSIM4SdpPtr) += m * gstotd);
(*(here->BSIM4SgpPtr) += m * gstotg);
(*(here->BSIM4SbpPtr) += m * gstotb);
}
*(here->BSIM4DPdpPtr +1) += m * (xcddbr + gdsi + RevSumi);
*(here->BSIM4DPdpPtr) += m * (gdpr + xcddbi + gdsr + here->BSIM4gbd
- gdtotd + RevSumr + gbdpdp - gIdtotd);
*(here->BSIM4DPdPtr) -= m * (gdpr + gdtot);
*(here->BSIM4DPgpPtr +1) += m * (xcdgbr + Gmi);
*(here->BSIM4DPgpPtr) += m * (Gmr + xcdgbi - gdtotg + gbdpg - gIdtotg);
*(here->BSIM4DPspPtr +1) += m * (xcdsbr - gdsi - FwdSumi);
*(here->BSIM4DPspPtr) -= m * (gdsr - xcdsbi + FwdSumr + gdtots - gbdpsp + gIdtots);
*(here->BSIM4DPbpPtr +1) += m * (xcdbbr + Gmbsi);
*(here->BSIM4DPbpPtr) -= m * (gjbd + gdtotb - xcdbbi - Gmbsr - gbdpb + gIdtotb);
*(here->BSIM4DdpPtr) -= m * (gdpr - gdtotd);
*(here->BSIM4DdPtr) += m * (gdpr + gdtot);
*(here->BSIM4SPdpPtr +1) += m * (xcsdbr - gdsi - RevSumi);
*(here->BSIM4SPdpPtr) -= m * (gdsr - xcsdbi + gstotd + RevSumr - gbspdp + gIstotd);
*(here->BSIM4SPgpPtr +1) += m * (xcsgbr - Gmi);
*(here->BSIM4SPgpPtr) -= m * (Gmr - xcsgbi + gstotg - gbspg + gIstotg);
*(here->BSIM4SPspPtr +1) += m * (xcssbr + gdsi + FwdSumi);
*(here->BSIM4SPspPtr) += m * (gspr + xcssbi + gdsr + here->BSIM4gbs
- gstots + FwdSumr + gbspsp - gIstots);
*(here->BSIM4SPsPtr) -= m * (gspr + gstot);
*(here->BSIM4SPbpPtr +1) += m * (xcsbbr - Gmbsi);
*(here->BSIM4SPbpPtr) -= m * (gjbs + gstotb - xcsbbi + Gmbsr - gbspb + gIstotb);
*(here->BSIM4SspPtr) -= m * (gspr - gstots);
*(here->BSIM4SsPtr) += m * (gspr + gstot);
*(here->BSIM4BPdpPtr +1) += m * xcbdb;
*(here->BSIM4BPdpPtr) -= m * (gjbd - gbbdp + gIbtotd);
*(here->BSIM4BPgpPtr +1) += m * xcbgb;
*(here->BSIM4BPgpPtr) -= m * (here->BSIM4gbgs + gIbtotg);
*(here->BSIM4BPspPtr +1) += m * xcbsb;
*(here->BSIM4BPspPtr) -= m * (gjbs - gbbsp + gIbtots);
*(here->BSIM4BPbpPtr +1) += m * xcbbb;
*(here->BSIM4BPbpPtr) += m * (gjbd + gjbs - here->BSIM4gbbs
- gIbtotb);
ggidld = here->BSIM4ggidld;
ggidlg = here->BSIM4ggidlg;
ggidlb = here->BSIM4ggidlb;
ggislg = here->BSIM4ggislg;
ggisls = here->BSIM4ggisls;
ggislb = here->BSIM4ggislb;
/* stamp gidl */
(*(here->BSIM4DPdpPtr) += m * ggidld);
(*(here->BSIM4DPgpPtr) += m * ggidlg);
(*(here->BSIM4DPspPtr) -= m * ((ggidlg + ggidld) + ggidlb));
(*(here->BSIM4DPbpPtr) += m * ggidlb);
(*(here->BSIM4BPdpPtr) -= m * ggidld);
(*(here->BSIM4BPgpPtr) -= m * ggidlg);
(*(here->BSIM4BPspPtr) += m * ((ggidlg + ggidld) + ggidlb));
(*(here->BSIM4BPbpPtr) -= m * ggidlb);
/* stamp gisl */
(*(here->BSIM4SPdpPtr) -= m * ((ggisls + ggislg) + ggislb));
(*(here->BSIM4SPgpPtr) += m * ggislg);
(*(here->BSIM4SPspPtr) += m * ggisls);
(*(here->BSIM4SPbpPtr) += m * ggislb);
(*(here->BSIM4BPdpPtr) += m * ((ggislg + ggisls) + ggislb));
(*(here->BSIM4BPgpPtr) -= m * ggislg);
(*(here->BSIM4BPspPtr) -= m * ggisls);
(*(here->BSIM4BPbpPtr) -= m * ggislb);
if (here->BSIM4rbodyMod)
{ (*(here->BSIM4DPdbPtr +1) += m * xcdbdb);
(*(here->BSIM4DPdbPtr) -= m * here->BSIM4gbd);
(*(here->BSIM4SPsbPtr +1) += m * xcsbsb);
(*(here->BSIM4SPsbPtr) -= m * here->BSIM4gbs);
(*(here->BSIM4DBdpPtr +1) += m * xcdbdb);
(*(here->BSIM4DBdpPtr) -= m * here->BSIM4gbd);
(*(here->BSIM4DBdbPtr +1) -= m * xcdbdb);
(*(here->BSIM4DBdbPtr) += m * (here->BSIM4gbd + here->BSIM4grbpd
+ here->BSIM4grbdb));
(*(here->BSIM4DBbpPtr) -= m * here->BSIM4grbpd);
(*(here->BSIM4DBbPtr) -= m * here->BSIM4grbdb);
(*(here->BSIM4BPdbPtr) -= m * here->BSIM4grbpd);
(*(here->BSIM4BPbPtr) -= m * here->BSIM4grbpb);
(*(here->BSIM4BPsbPtr) -= m * here->BSIM4grbps);
(*(here->BSIM4BPbpPtr) += m * (here->BSIM4grbpd + here->BSIM4grbps
+ here->BSIM4grbpb));
/* WDLiu: (-here->BSIM4gbbs) already added to BPbpPtr */
(*(here->BSIM4SBspPtr +1) += m * xcsbsb);
(*(here->BSIM4SBspPtr) -= m * here->BSIM4gbs);
(*(here->BSIM4SBbpPtr) -= m * here->BSIM4grbps);
(*(here->BSIM4SBbPtr) -= m * here->BSIM4grbsb);
(*(here->BSIM4SBsbPtr +1) -= m * xcsbsb);
(*(here->BSIM4SBsbPtr) += m * (here->BSIM4gbs
+ here->BSIM4grbps + here->BSIM4grbsb));
(*(here->BSIM4BdbPtr) -= m * here->BSIM4grbdb);
(*(here->BSIM4BbpPtr) -= m * here->BSIM4grbpb);
(*(here->BSIM4BsbPtr) -= m * here->BSIM4grbsb);
(*(here->BSIM4BbPtr) += m * (here->BSIM4grbsb + here->BSIM4grbdb
+ here->BSIM4grbpb));
}
/*
* WDLiu: The internal charge node generated for transient NQS is not needed for
* AC NQS. The following is not doing a real job, but we have to keep it;
* otherwise a singular AC NQS matrix may occur if the transient NQS is on.
* The charge node is isolated from the instance.
*/
if (here->BSIM4trnqsMod)
{ (*(here->BSIM4QqPtr) += m * 1.0);
(*(here->BSIM4QgpPtr) += 0.0);
(*(here->BSIM4QdpPtr) += 0.0);
(*(here->BSIM4QspPtr) += 0.0);
(*(here->BSIM4QbpPtr) += 0.0);
(*(here->BSIM4DPqPtr) += 0.0);
(*(here->BSIM4SPqPtr) += 0.0);
(*(here->BSIM4GPqPtr) += 0.0);
}
}
}
return(OK);
}

View File

@ -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 */
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -0,0 +1,48 @@
/**** BSIM4.7.0 Released by Darsen Lu 04/08/2011 ****/
/**********
* Copyright 2006 Regents of the University of California. All rights reserved.
* File: b4mdel.c of BSIM4.7.0.
* Author: 2000 Weidong Liu
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu.
* Authors: 2006- Mohan Dunga, Ali Niknejad, Chenming Hu
* Authors: 2007- Mohan Dunga, Wenwei Yang, Ali Niknejad, Chenming Hu
* Project Director: Prof. Chenming Hu.
**********/
#include "ngspice/ngspice.h"
#include "bsim4def.h"
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
int
BSIM4mDelete(
GENmodel **inModel,
IFuid modname,
GENmodel *kill)
{
BSIM4model **model = (BSIM4model**)inModel;
BSIM4model *modfast = (BSIM4model*)kill;
BSIM4instance *here;
BSIM4instance *prev = NULL;
BSIM4model **oldmod;
oldmod = model;
for (; *model ; model = &((*model)->BSIM4nextModel))
{ if ((*model)->BSIM4modName == modname ||
(modfast && *model == modfast))
goto delgot;
oldmod = model;
}
return(E_NOMOD);
delgot:
*oldmod = (*model)->BSIM4nextModel; /* cut deleted device out of list */
for (here = (*model)->BSIM4instances; here; here = here->BSIM4nextInstance)
{ if(prev) FREE(prev);
prev = here;
}
if(prev) FREE(prev);
FREE(*model);
return(OK);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,648 @@
/**** BSIM4.7.0 Released by Darsen Lu 04/08/2011 ****/
/**********
* Copyright 2006 Regents of the University of California. All rights reserved.
* File: b4noi.c of BSIM4.7.0.
* Author: 2000 Weidong Liu
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu.
* Authors: 2006- Mohan Dunga, Ali Niknejad, Chenming Hu
* Authors: 2007- Mohan Dunga, Wenwei Yang, Ali Niknejad, Chenming Hu
* Authors: 2008- Wenwei Yang, Ali Niknejad, Chenming Hu
* Project Director: Prof. Chenming Hu.
* Modified by Xuemei Xi, 04/06/2001.
* Modified by Xuemei Xi, 10/05/2001.
* Modified by Xuemei Xi, 05/09/2003.
* Modified by Xuemei Xi, 03/04/2004.
* Modified by Xuemei Xi, 07/29/2005.
* Modified by Mohan Dunga, 12/13/2006
* Modified by Wenwei Yang, 07/31/2008.
* Modified by Tanvir Morshed, Darsen Lu 03/27/2011
**********/
#include "ngspice/ngspice.h"
#include "bsim4def.h"
#include "ngspice/cktdefs.h"
#include "ngspice/iferrmsg.h"
#include "ngspice/noisedef.h"
#include "ngspice/suffix.h"
#include "ngspice/const.h"
/*
* WDL: 1/f noise model has been smoothed out and enhanced with
* bulk charge effect as well as physical N* equ. and necessary
* conversion into the SI unit system.
*/
static double
Eval1ovFNoise(
double Vds,
BSIM4model *model,
BSIM4instance *here,
double freq, double temp)
{
struct bsim4SizeDependParam *pParam;
double cd, esat, DelClm, EffFreq, N0, Nl, Leff, Leffsq;
double T0=0.0, T1, T2, T3, T4, T5, T6, T7, T8, T9, Ssi;
pParam = here->pParam;
cd = fabs(here->BSIM4cd);
Leff = pParam->BSIM4leff - 2.0 * model->BSIM4lintnoi;
Leffsq = Leff * Leff;
esat = 2.0 * here->BSIM4vsattemp / here->BSIM4ueff;
if(model->BSIM4em<=0.0) DelClm = 0.0; /* flicker noise modified -JX */
else {
T0 = ((((Vds - here->BSIM4Vdseff) / pParam->BSIM4litl)
+ model->BSIM4em) / esat);
DelClm = pParam->BSIM4litl * log (MAX(T0, N_MINLOG));
if (DelClm < 0.0) DelClm = 0.0; /* bugfix */
}
EffFreq = pow(freq, model->BSIM4ef);
T1 = CHARGE * CHARGE * CONSTboltz * cd * temp * here->BSIM4ueff;
T2 = 1.0e10 * EffFreq * here->BSIM4Abulk * model->BSIM4coxe * Leffsq;
N0 = model->BSIM4coxe * here->BSIM4Vgsteff / CHARGE;
Nl = model->BSIM4coxe * here->BSIM4Vgsteff
* (1.0 - here->BSIM4AbovVgst2Vtm * here->BSIM4Vdseff) / CHARGE;
T3 = model->BSIM4oxideTrapDensityA
* log(MAX(((N0 + here->BSIM4nstar) / (Nl + here->BSIM4nstar)), N_MINLOG));
T4 = model->BSIM4oxideTrapDensityB * (N0 - Nl);
T5 = model->BSIM4oxideTrapDensityC * 0.5 * (N0 * N0 - Nl * Nl);
T6 = CONSTboltz * temp * cd * cd;
T7 = 1.0e10 * EffFreq * Leffsq * pParam->BSIM4weff * here->BSIM4nf;
T8 = model->BSIM4oxideTrapDensityA + model->BSIM4oxideTrapDensityB * Nl
+ model->BSIM4oxideTrapDensityC * Nl * Nl;
T9 = (Nl + here->BSIM4nstar) * (Nl + here->BSIM4nstar);
Ssi = T1 / T2 * (T3 + T4 + T5) + T6 / T7 * DelClm * T8 / T9;
return Ssi;
}
int
BSIM4noise (
int mode, int operation,
GENmodel *inModel,
CKTcircuit *ckt,
Ndata *data,
double *OnDens)
{
NOISEAN *job = (NOISEAN *) ckt->CKTcurJob;
BSIM4model *model = (BSIM4model *)inModel;
BSIM4instance *here;
struct bsim4SizeDependParam *pParam;
char name[N_MXVLNTH];
double tempOnoise;
double tempInoise;
double noizDens[BSIM4NSRCS];
double lnNdens[BSIM4NSRCS];
double T0, T1, T2, T3, T4, T5, T6, T7, T8, T10, T11;
double Vds, Ssi, Swi;
double tmp=0.0, gdpr, gspr, npart_theta=0.0, npart_beta=0.0, igsquare, bodymode;
/* tnoiMod=2 (v4.7) */
double eta, Leff, Lvsat, gamma, delta, epsilon, GammaGd0=0.0;
double npart_c, sigrat=0.0, C0, omega, ctnoi=0.0;
int i;
double m;
/* define the names of the noise sources */
static char *BSIM4nNames[BSIM4NSRCS] =
{ /* Note that we have to keep the order */
".rd", /* noise due to rd */
".rs", /* noise due to rs */
".rg", /* noise due to rgeltd */
".rbps", /* noise due to rbps */
".rbpd", /* noise due to rbpd */
".rbpb", /* noise due to rbpb */
".rbsb", /* noise due to rbsb */
".rbdb", /* noise due to rbdb */
".id", /* noise due to id (for tnoiMod2: uncorrelated portion only) */
".1overf", /* flicker (1/f) noise */
".igs", /* shot noise due to IGS */
".igd", /* shot noise due to IGD */
".igb", /* shot noise due to IGB */
".corl", /* contribution of correlated drain and induced gate noise */
"" /* total transistor noise */
};
for (; model != NULL; model = model->BSIM4nextModel)
{
if(model->BSIM4tnoiMod != 2) {
noizDens[BSIM4CORLNOIZ] = 0.0;
lnNdens[BSIM4CORLNOIZ] = N_MINLOG;
}
for (here = model->BSIM4instances; here != NULL;
here = here->BSIM4nextInstance)
{ pParam = here->pParam;
switch (operation)
{ case N_OPEN:
/* see if we have to to produce a summary report */
/* if so, name all the noise generators */
if (job->NStpsSm != 0)
{ switch (mode)
{ case N_DENS:
for (i = 0; i < BSIM4NSRCS; i++)
{ (void) sprintf(name, "onoise.%s%s",
here->BSIM4name,
BSIM4nNames[i]);
data->namelist = TREALLOC(IFuid,
data->namelist,
data->numPlots + 1);
if (!data->namelist)
return(E_NOMEM);
SPfrontEnd->IFnewUid (ckt,
&(data->namelist[data->numPlots++]),
NULL, name, UID_OTHER, NULL);
/* we've added one more plot */
}
break;
case INT_NOIZ:
for (i = 0; i < BSIM4NSRCS; i++)
{ (void) sprintf(name, "onoise_total.%s%s",
here->BSIM4name,
BSIM4nNames[i]);
data->namelist = TREALLOC(IFuid,
data->namelist,
data->numPlots + 1);
if (!data->namelist)
return(E_NOMEM);
SPfrontEnd->IFnewUid (ckt,
&(data->namelist[data->numPlots++]),
NULL, name, UID_OTHER, NULL);
/* we've added one more plot */
(void) sprintf(name, "inoise_total.%s%s",
here->BSIM4name,
BSIM4nNames[i]);
data->namelist = TREALLOC(IFuid,
data->namelist,
data->numPlots + 1);
if (!data->namelist)
return(E_NOMEM);
SPfrontEnd->IFnewUid (ckt,
&(data->namelist[data->numPlots++]),
NULL, name, UID_OTHER, NULL);
/* we've added one more plot */
}
break;
}
}
break;
case N_CALC:
m = here->BSIM4m;
switch (mode)
{ case N_DENS:
if (model->BSIM4tnoiMod == 0)
{ if (model->BSIM4rdsMod == 0)
{ gspr = here->BSIM4sourceConductance;
gdpr = here->BSIM4drainConductance;
if (here->BSIM4grdsw > 0.0)
tmp = 1.0 / here->BSIM4grdsw; /* tmp used below */
else
tmp = 0.0;
}
else
{ gspr = here->BSIM4gstot;
gdpr = here->BSIM4gdtot;
tmp = 0.0;
}
}
else if(model->BSIM4tnoiMod == 1)
{ T5 = here->BSIM4Vgsteff / here->BSIM4EsatL;
T5 *= T5;
npart_beta = model->BSIM4rnoia * (1.0 + T5
* model->BSIM4tnoia * pParam->BSIM4leff);
npart_theta = model->BSIM4rnoib * (1.0 + T5
* model->BSIM4tnoib * pParam->BSIM4leff);
if(npart_theta > 0.9)
npart_theta = 0.9;
if(npart_theta > 0.9 * npart_beta)
npart_theta = 0.9 * npart_beta; //4.6.2
if (model->BSIM4rdsMod == 0)
{ gspr = here->BSIM4sourceConductance;
gdpr = here->BSIM4drainConductance;
}
else
{ gspr = here->BSIM4gstot;
gdpr = here->BSIM4gdtot;
}
if ((*(ckt->CKTstates[0] + here->BSIM4vds)) >= 0.0)
gspr = gspr * (1.0 + npart_theta * npart_theta * gspr
/ here->BSIM4IdovVds);
else
gdpr = gdpr * (1.0 + npart_theta * npart_theta * gdpr
/ here->BSIM4IdovVds);
}
else
{ /* tnoiMod=2 (v4.7) */
if (model->BSIM4rdsMod == 0)
{ gspr = here->BSIM4sourceConductance;
gdpr = here->BSIM4drainConductance;
}
else
{ gspr = here->BSIM4gstot;
gdpr = here->BSIM4gdtot;
}
}
NevalSrc(&noizDens[BSIM4RDNOIZ],
&lnNdens[BSIM4RDNOIZ], ckt, THERMNOISE,
here->BSIM4dNodePrime, here->BSIM4dNode,
gdpr * m);
NevalSrc(&noizDens[BSIM4RSNOIZ],
&lnNdens[BSIM4RSNOIZ], ckt, THERMNOISE,
here->BSIM4sNodePrime, here->BSIM4sNode,
gspr * m);
if (here->BSIM4rgateMod == 1)
{ NevalSrc(&noizDens[BSIM4RGNOIZ],
&lnNdens[BSIM4RGNOIZ], ckt, THERMNOISE,
here->BSIM4gNodePrime, here->BSIM4gNodeExt,
here->BSIM4grgeltd * m);
}
else if (here->BSIM4rgateMod == 2)
{
T0 = 1.0 + here->BSIM4grgeltd/here->BSIM4gcrg;
T1 = T0 * T0;
NevalSrc(&noizDens[BSIM4RGNOIZ],
&lnNdens[BSIM4RGNOIZ], ckt, THERMNOISE,
here->BSIM4gNodePrime, here->BSIM4gNodeExt,
here->BSIM4grgeltd * m / T1);
}
else if (here->BSIM4rgateMod == 3)
{ NevalSrc(&noizDens[BSIM4RGNOIZ],
&lnNdens[BSIM4RGNOIZ], ckt, THERMNOISE,
here->BSIM4gNodeMid, here->BSIM4gNodeExt,
here->BSIM4grgeltd * m);
}
else
{ noizDens[BSIM4RGNOIZ] = 0.0;
lnNdens[BSIM4RGNOIZ] =
log(MAX(noizDens[BSIM4RGNOIZ], N_MINLOG));
}
bodymode = 5;
if (here->BSIM4rbodyMod == 2)
{ if( ( !model->BSIM4rbps0Given) ||
( !model->BSIM4rbpd0Given) )
bodymode = 1;
else
if( (!model->BSIM4rbsbx0Given && !model->BSIM4rbsby0Given) ||
(!model->BSIM4rbdbx0Given && !model->BSIM4rbdby0Given) )
bodymode = 3;
}
if (here->BSIM4rbodyMod)
{
if(bodymode == 5)
{
NevalSrc(&noizDens[BSIM4RBPSNOIZ],
&lnNdens[BSIM4RBPSNOIZ], ckt, THERMNOISE,
here->BSIM4bNodePrime, here->BSIM4sbNode,
here->BSIM4grbps * m);
NevalSrc(&noizDens[BSIM4RBPDNOIZ],
&lnNdens[BSIM4RBPDNOIZ], ckt, THERMNOISE,
here->BSIM4bNodePrime, here->BSIM4dbNode,
here->BSIM4grbpd * m);
NevalSrc(&noizDens[BSIM4RBPBNOIZ],
&lnNdens[BSIM4RBPBNOIZ], ckt, THERMNOISE,
here->BSIM4bNodePrime, here->BSIM4bNode,
here->BSIM4grbpb * m);
NevalSrc(&noizDens[BSIM4RBSBNOIZ],
&lnNdens[BSIM4RBSBNOIZ], ckt, THERMNOISE,
here->BSIM4bNode, here->BSIM4sbNode,
here->BSIM4grbsb * m);
NevalSrc(&noizDens[BSIM4RBDBNOIZ],
&lnNdens[BSIM4RBDBNOIZ], ckt, THERMNOISE,
here->BSIM4bNode, here->BSIM4dbNode,
here->BSIM4grbdb * m);
}
if(bodymode == 3)
{
NevalSrc(&noizDens[BSIM4RBPSNOIZ],
&lnNdens[BSIM4RBPSNOIZ], ckt, THERMNOISE,
here->BSIM4bNodePrime, here->BSIM4sbNode,
here->BSIM4grbps * m);
NevalSrc(&noizDens[BSIM4RBPDNOIZ],
&lnNdens[BSIM4RBPDNOIZ], ckt, THERMNOISE,
here->BSIM4bNodePrime, here->BSIM4dbNode,
here->BSIM4grbpd * m);
NevalSrc(&noizDens[BSIM4RBPBNOIZ],
&lnNdens[BSIM4RBPBNOIZ], ckt, THERMNOISE,
here->BSIM4bNodePrime, here->BSIM4bNode,
here->BSIM4grbpb * m);
noizDens[BSIM4RBSBNOIZ] = noizDens[BSIM4RBDBNOIZ] = 0.0;
lnNdens[BSIM4RBSBNOIZ] =
log(MAX(noizDens[BSIM4RBSBNOIZ], N_MINLOG));
lnNdens[BSIM4RBDBNOIZ] =
log(MAX(noizDens[BSIM4RBDBNOIZ], N_MINLOG));
}
if(bodymode == 1)
{
NevalSrc(&noizDens[BSIM4RBPBNOIZ],
&lnNdens[BSIM4RBPBNOIZ], ckt, THERMNOISE,
here->BSIM4bNodePrime, here->BSIM4bNode,
here->BSIM4grbpb * m);
noizDens[BSIM4RBPSNOIZ] = noizDens[BSIM4RBPDNOIZ] = 0.0;
noizDens[BSIM4RBSBNOIZ] = noizDens[BSIM4RBDBNOIZ] = 0.0;
lnNdens[BSIM4RBPSNOIZ] =
log(MAX(noizDens[BSIM4RBPSNOIZ], N_MINLOG));
lnNdens[BSIM4RBPDNOIZ] =
log(MAX(noizDens[BSIM4RBPDNOIZ], N_MINLOG));
lnNdens[BSIM4RBSBNOIZ] =
log(MAX(noizDens[BSIM4RBSBNOIZ], N_MINLOG));
lnNdens[BSIM4RBDBNOIZ] =
log(MAX(noizDens[BSIM4RBDBNOIZ], N_MINLOG));
}
}
else
{ noizDens[BSIM4RBPSNOIZ] = noizDens[BSIM4RBPDNOIZ] = 0.0;
noizDens[BSIM4RBPBNOIZ] = 0.0;
noizDens[BSIM4RBSBNOIZ] = noizDens[BSIM4RBDBNOIZ] = 0.0;
lnNdens[BSIM4RBPSNOIZ] =
log(MAX(noizDens[BSIM4RBPSNOIZ], N_MINLOG));
lnNdens[BSIM4RBPDNOIZ] =
log(MAX(noizDens[BSIM4RBPDNOIZ], N_MINLOG));
lnNdens[BSIM4RBPBNOIZ] =
log(MAX(noizDens[BSIM4RBPBNOIZ], N_MINLOG));
lnNdens[BSIM4RBSBNOIZ] =
log(MAX(noizDens[BSIM4RBSBNOIZ], N_MINLOG));
lnNdens[BSIM4RBDBNOIZ] =
log(MAX(noizDens[BSIM4RBDBNOIZ], N_MINLOG));
}
if(model->BSIM4tnoiMod == 2)
{
eta = 1.0 - here->BSIM4Vdseff * here->BSIM4AbovVgst2Vtm;
T0 = 1.0 - eta;
T1 = 1.0 + eta;
T2 = T1 + 2.0 * here->BSIM4Abulk * model->BSIM4vtm / here->BSIM4Vgsteff;
Leff = pParam->BSIM4leff;
Lvsat = Leff * (1.0 + here->BSIM4Vdseff / here->BSIM4EsatL);
T6 = Leff / Lvsat;
T5 = here->BSIM4Vgsteff / here->BSIM4EsatL;
T5 = T5 * T5;
gamma = T6 * (0.5 * T1 + T0 * T0 / (6.0 * T2));
T3 = T2 * T2;
T4 = T0 * T0;
T5 = T3 * T3;
delta = (T1 / T3 - (5.0 * T1 + T2) * T4 / (15.0 * T5) + T4 * T4 / (9.0 * T5 * T2)) / (6.0 * T6 * T6 * T6);
T7 = T0 / T2;
epsilon = (T7 - T7 * T7 * T7 / 3.0) / (6.0 * T6);
T8 = here->BSIM4Vgsteff / here->BSIM4EsatL;
T8 *= T8;
npart_c = model->BSIM4rnoic * (1.0 + T8
* model->BSIM4tnoic * Leff);
ctnoi = epsilon / sqrt(gamma * delta)
* (2.5316 * npart_c);
npart_beta = model->BSIM4rnoia * (1.0 + T8
* model->BSIM4tnoia * Leff);
npart_theta = model->BSIM4rnoib * (1.0 + T8
* model->BSIM4tnoib * Leff);
gamma = gamma * (3.0 * npart_beta * npart_beta);
delta = delta * (3.75 * npart_theta * npart_theta);
GammaGd0 = gamma * here->BSIM4noiGd0;
C0 = here->BSIM4Coxeff * pParam->BSIM4weffCV * here->BSIM4nf * pParam->BSIM4leffCV;
T0 = C0 / here->BSIM4noiGd0;
sigrat = T0 * sqrt(delta / gamma);
}
switch(model->BSIM4tnoiMod)
{ case 0:
T0 = here->BSIM4ueff * fabs(here->BSIM4qinv);
T1 = T0 * tmp + pParam->BSIM4leff
* pParam->BSIM4leff;
NevalSrc(&noizDens[BSIM4IDNOIZ],
&lnNdens[BSIM4IDNOIZ], ckt,
THERMNOISE, here->BSIM4dNodePrime,
here->BSIM4sNodePrime,
(T0 / T1) * model->BSIM4ntnoi * m);
break;
case 1:
T0 = here->BSIM4gm + here->BSIM4gmbs + here->BSIM4gds;
T0 *= T0;
igsquare = npart_theta * npart_theta * T0 / here->BSIM4IdovVds;
T1 = npart_beta * (here->BSIM4gm
+ here->BSIM4gmbs) + here->BSIM4gds;
T2 = T1 * T1 / here->BSIM4IdovVds;
NevalSrc(&noizDens[BSIM4IDNOIZ],
&lnNdens[BSIM4IDNOIZ], ckt,
THERMNOISE, here->BSIM4dNodePrime,
here->BSIM4sNodePrime, (T2 - igsquare) * m);
break;
case 2:
T2 = GammaGd0;
T3 = ctnoi * ctnoi;
T4 = 1.0 - T3;
NevalSrc(&noizDens[BSIM4IDNOIZ],
&lnNdens[BSIM4IDNOIZ], ckt,
THERMNOISE, here->BSIM4dNodePrime,
here->BSIM4sNodePrime, T2 * T4 * m);
/* Evaluate output noise due to two correlated noise sources */
omega = 2.0 * M_PI * data->freq;
T5 = omega * sigrat;
T6 = T5 * T5;
T7 = T6 / (1.0 + T6);
if (here->BSIM4mode >= 0) {
NevalSrc2(&noizDens[BSIM4CORLNOIZ],
&lnNdens[BSIM4CORLNOIZ], ckt,
THERMNOISE, here->BSIM4dNodePrime,
here->BSIM4sNodePrime, T2 * T3 * m,
here->BSIM4gNodePrime,
here->BSIM4sNodePrime,
T2 * T7 * m, 0.5 * M_PI);
}
else
{
NevalSrc2(&noizDens[BSIM4CORLNOIZ],
&lnNdens[BSIM4CORLNOIZ], ckt,
THERMNOISE, here->BSIM4sNodePrime,
here->BSIM4dNodePrime, T2 * T3 * m,
here->BSIM4gNodePrime,
here->BSIM4dNodePrime,
T2 * T7 * m, 0.5 * M_PI);
}
break;
}
NevalSrc(&noizDens[BSIM4FLNOIZ], (double*) NULL,
ckt, N_GAIN, here->BSIM4dNodePrime,
here->BSIM4sNodePrime, (double) 0.0);
switch(model->BSIM4fnoiMod)
{ case 0:
noizDens[BSIM4FLNOIZ] *= m * model->BSIM4kf
* exp(model->BSIM4af
* log(MAX(fabs(here->BSIM4cd),
N_MINLOG)))
/ (pow(data->freq, model->BSIM4ef)
* pParam->BSIM4leff
* pParam->BSIM4leff
* model->BSIM4coxe);
break;
case 1:
Vds = *(ckt->CKTstates[0] + here->BSIM4vds);
if (Vds < 0.0)
Vds = -Vds;
Ssi = Eval1ovFNoise(Vds, model, here,
data->freq, ckt->CKTtemp);
T10 = model->BSIM4oxideTrapDensityA
* CONSTboltz * ckt->CKTtemp;
T11 = pParam->BSIM4weff * here->BSIM4nf * pParam->BSIM4leff
* pow(data->freq, model->BSIM4ef) * 1.0e10
* here->BSIM4nstar * here->BSIM4nstar;
Swi = T10 / T11 * here->BSIM4cd
* here->BSIM4cd;
T1 = Swi + Ssi;
if (T1 > 0.0)
noizDens[BSIM4FLNOIZ] *= m * (Ssi * Swi) / T1;
else
noizDens[BSIM4FLNOIZ] *= 0.0;
break;
}
lnNdens[BSIM4FLNOIZ] =
log(MAX(noizDens[BSIM4FLNOIZ], N_MINLOG));
if(here->BSIM4mode >= 0) { /* bugfix */
NevalSrc(&noizDens[BSIM4IGSNOIZ],
&lnNdens[BSIM4IGSNOIZ], ckt, SHOTNOISE,
here->BSIM4gNodePrime, here->BSIM4sNodePrime,
m * (here->BSIM4Igs + here->BSIM4Igcs));
NevalSrc(&noizDens[BSIM4IGDNOIZ],
&lnNdens[BSIM4IGDNOIZ], ckt, SHOTNOISE,
here->BSIM4gNodePrime, here->BSIM4dNodePrime,
m * (here->BSIM4Igd + here->BSIM4Igcd));
} else {
NevalSrc(&noizDens[BSIM4IGSNOIZ],
&lnNdens[BSIM4IGSNOIZ], ckt, SHOTNOISE,
here->BSIM4gNodePrime, here->BSIM4sNodePrime,
m * (here->BSIM4Igs + here->BSIM4Igcd));
NevalSrc(&noizDens[BSIM4IGDNOIZ],
&lnNdens[BSIM4IGDNOIZ], ckt, SHOTNOISE,
here->BSIM4gNodePrime, here->BSIM4dNodePrime,
m * (here->BSIM4Igd + here->BSIM4Igcs));
}
NevalSrc(&noizDens[BSIM4IGBNOIZ],
&lnNdens[BSIM4IGBNOIZ], ckt, SHOTNOISE,
here->BSIM4gNodePrime, here->BSIM4bNodePrime,
m * here->BSIM4Igb);
noizDens[BSIM4TOTNOIZ] = noizDens[BSIM4RDNOIZ]
+ noizDens[BSIM4RSNOIZ] + noizDens[BSIM4RGNOIZ]
+ noizDens[BSIM4RBPSNOIZ] + noizDens[BSIM4RBPDNOIZ]
+ noizDens[BSIM4RBPBNOIZ]
+ noizDens[BSIM4RBSBNOIZ] + noizDens[BSIM4RBDBNOIZ]
+ noizDens[BSIM4IDNOIZ] + noizDens[BSIM4FLNOIZ]
+ noizDens[BSIM4IGSNOIZ] + noizDens[BSIM4IGDNOIZ]
+ noizDens[BSIM4IGBNOIZ] + noizDens[BSIM4CORLNOIZ];
lnNdens[BSIM4TOTNOIZ] =
log(MAX(noizDens[BSIM4TOTNOIZ], N_MINLOG));
*OnDens += noizDens[BSIM4TOTNOIZ];
if (data->delFreq == 0.0)
{ /* if we haven't done any previous
integration, we need to initialize our
"history" variables.
*/
for (i = 0; i < BSIM4NSRCS; i++)
{ here->BSIM4nVar[LNLSTDENS][i] =
lnNdens[i];
}
/* clear out our integration variables
if it's the first pass
*/
if (data->freq ==
job->NstartFreq)
{ for (i = 0; i < BSIM4NSRCS; i++)
{ here->BSIM4nVar[OUTNOIZ][i] = 0.0;
here->BSIM4nVar[INNOIZ][i] = 0.0;
}
}
}
else
{ /* data->delFreq != 0.0,
we have to integrate.
*/
for (i = 0; i < BSIM4NSRCS; i++)
{ if (i != BSIM4TOTNOIZ)
{ tempOnoise = Nintegrate(noizDens[i],
lnNdens[i],
here->BSIM4nVar[LNLSTDENS][i],
data);
tempInoise = Nintegrate(noizDens[i]
* data->GainSqInv, lnNdens[i]
+ data->lnGainInv,
here->BSIM4nVar[LNLSTDENS][i]
+ data->lnGainInv, data);
here->BSIM4nVar[LNLSTDENS][i] =
lnNdens[i];
data->outNoiz += tempOnoise;
data->inNoise += tempInoise;
if (job->NStpsSm != 0)
{ here->BSIM4nVar[OUTNOIZ][i]
+= tempOnoise;
here->BSIM4nVar[OUTNOIZ][BSIM4TOTNOIZ]
+= tempOnoise;
here->BSIM4nVar[INNOIZ][i]
+= tempInoise;
here->BSIM4nVar[INNOIZ][BSIM4TOTNOIZ]
+= tempInoise;
}
}
}
}
if (data->prtSummary)
{ for (i = 0; i < BSIM4NSRCS; i++)
{ /* print a summary report */
data->outpVector[data->outNumber++]
= noizDens[i];
}
}
break;
case INT_NOIZ:
/* already calculated, just output */
if (job->NStpsSm != 0)
{ for (i = 0; i < BSIM4NSRCS; i++)
{ data->outpVector[data->outNumber++]
= here->BSIM4nVar[OUTNOIZ][i];
data->outpVector[data->outNumber++]
= here->BSIM4nVar[INNOIZ][i];
}
}
break;
}
break;
case N_CLOSE:
/* do nothing, the main calling routine will close */
return (OK);
break; /* the plots */
} /* switch (operation) */
} /* for here */
} /* for model */
return(OK);
}

View File

@ -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);
}

View File

@ -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

View File

@ -0,0 +1,110 @@
/**********
Copyright 2013 Dietmar Warning. All rights reserved.
Author: 2013 Dietmar Warning
**********/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "bsim4def.h"
#include "ngspice/trandefs.h"
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
#include "ngspice/cpdefs.h"
int
BSIM4soaCheck(CKTcircuit *ckt, GENmodel *inModel)
{
BSIM4model *model = (BSIM4model *) inModel;
BSIM4instance *here;
double vgs, vgd, vgb, vds, vbs, vbd; /* actual mos voltages */
int maxwarns;
static int warns_vgs = 0, warns_vgd = 0, warns_vgb = 0, warns_vds = 0, warns_vbs = 0, warns_vbd = 0;
if (!ckt) {
warns_vgs = 0;
warns_vgd = 0;
warns_vgb = 0;
warns_vds = 0;
warns_vbs = 0;
warns_vbd = 0;
return OK;
}
maxwarns = ckt->CKTsoaMaxWarns;
for (; model; model = model->BSIM4nextModel) {
for (here = model->BSIM4instances; here; here = here->BSIM4nextInstance) {
vgs = fabs(ckt->CKTrhsOld [here->BSIM4gNodePrime] -
ckt->CKTrhsOld [here->BSIM4sNodePrime]);
vgd = fabs(ckt->CKTrhsOld [here->BSIM4gNodePrime] -
ckt->CKTrhsOld [here->BSIM4dNodePrime]);
vgb = fabs(ckt->CKTrhsOld [here->BSIM4gNodePrime] -
ckt->CKTrhsOld [here->BSIM4bNodePrime]);
vds = fabs(ckt->CKTrhsOld [here->BSIM4dNodePrime] -
ckt->CKTrhsOld [here->BSIM4sNodePrime]);
vbs = fabs(ckt->CKTrhsOld [here->BSIM4bNodePrime] -
ckt->CKTrhsOld [here->BSIM4sNodePrime]);
vbd = fabs(ckt->CKTrhsOld [here->BSIM4bNodePrime] -
ckt->CKTrhsOld [here->BSIM4dNodePrime]);
if (vgs > model->BSIM4vgsMax)
if (warns_vgs < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"|Vgs|=%g has exceeded Vgs_max=%g\n",
vgs, model->BSIM4vgsMax);
warns_vgs++;
}
if (vgd > model->BSIM4vgdMax)
if (warns_vgd < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"|Vgd|=%g has exceeded Vgd_max=%g\n",
vgd, model->BSIM4vgdMax);
warns_vgd++;
}
if (vgb > model->BSIM4vgbMax)
if (warns_vgb < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"|Vgb|=%g has exceeded Vgb_max=%g\n",
vgb, model->BSIM4vgbMax);
warns_vgb++;
}
if (vds > model->BSIM4vdsMax)
if (warns_vds < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"|Vds|=%g has exceeded Vds_max=%g\n",
vds, model->BSIM4vdsMax);
warns_vds++;
}
if (vbs > model->BSIM4vbsMax)
if (warns_vbs < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"|Vbs|=%g has exceeded Vbs_max=%g\n",
vbs, model->BSIM4vbsMax);
warns_vbs++;
}
if (vbd > model->BSIM4vbdMax)
if (warns_vbd < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"|Vbd|=%g has exceeded Vbd_max=%g\n",
vbd, model->BSIM4vbdMax);
warns_vbd++;
}
}
}
return OK;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,60 @@
/**** BSIM4.7.0 Released by Darsen Lu 04/08/2011 ****/
/**********
* Copyright 2006 Regents of the University of California. All rights reserved.
* File: b4trunc.c of BSIM4.7.0.
* Author: 2000 Weidong Liu
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu.
* Authors: 2006- Mohan Dunga, Ali Niknejad, Chenming Hu
* Authors: 2007- Mohan Dunga, Wenwei Yang, Ali Niknejad, Chenming Hu
* Project Director: Prof. Chenming Hu.
**********/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "bsim4def.h"
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
int
BSIM4trunc(
GENmodel *inModel,
CKTcircuit *ckt,
double *timeStep)
{
BSIM4model *model = (BSIM4model*)inModel;
BSIM4instance *here;
#ifdef STEPDEBUG
double debugtemp;
#endif /* STEPDEBUG */
for (; model != NULL; model = model->BSIM4nextModel)
{ for (here = model->BSIM4instances; here != NULL;
here = here->BSIM4nextInstance)
{
#ifdef STEPDEBUG
debugtemp = *timeStep;
#endif /* STEPDEBUG */
CKTterr(here->BSIM4qb,ckt,timeStep);
CKTterr(here->BSIM4qg,ckt,timeStep);
CKTterr(here->BSIM4qd,ckt,timeStep);
if (here->BSIM4trnqsMod)
CKTterr(here->BSIM4qcdump,ckt,timeStep);
if (here->BSIM4rbodyMod)
{ CKTterr(here->BSIM4qbs,ckt,timeStep);
CKTterr(here->BSIM4qbd,ckt,timeStep);
}
if (here->BSIM4rgateMod == 3)
CKTterr(here->BSIM4qgmid,ckt,timeStep);
#ifdef STEPDEBUG
if(debugtemp != *timeStep)
{ printf("device %s reduces step from %g to %g\n",
here->BSIM4name,debugtemp,*timeStep);
}
#endif /* STEPDEBUG */
}
}
return(OK);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,31 @@
/**********
Copyright 2004 Regents of the University of California. All rights reserved.
Author: 2000 Weidong Liu
Author: 2001- Xuemei Xi
File: bsim4ext.h
**********/
extern int BSIM4acLoad(GENmodel *,CKTcircuit*);
extern int BSIM4ask(CKTcircuit *,GENinstance*,int,IFvalue*,IFvalue*);
extern int BSIM4convTest(GENmodel *,CKTcircuit*);
extern int BSIM4delete(GENmodel*,IFuid,GENinstance**);
extern void BSIM4destroy(GENmodel**);
extern int BSIM4getic(GENmodel*,CKTcircuit*);
extern int BSIM4load(GENmodel*,CKTcircuit*);
extern int BSIM4mAsk(CKTcircuit*,GENmodel *,int, IFvalue*);
extern int BSIM4mDelete(GENmodel**,IFuid,GENmodel*);
extern int BSIM4mParam(int,IFvalue*,GENmodel*);
extern void BSIM4mosCap(CKTcircuit*, double, double, double, double,
double, double, double, double, double, double, double,
double, double, double, double, double, double, double*,
double*, double*, double*, double*, double*, double*, double*,
double*, double*, double*, double*, double*, double*, double*,
double*);
extern int BSIM4param(int,IFvalue*,GENinstance*,IFvalue*);
extern int BSIM4pzLoad(GENmodel*,CKTcircuit*,SPcomplex*);
extern int BSIM4setup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
extern int BSIM4temp(GENmodel*,CKTcircuit*);
extern int BSIM4trunc(GENmodel*,CKTcircuit*,double*);
extern int BSIM4noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
extern int BSIM4unsetup(GENmodel*,CKTcircuit*);
extern int BSIM4soaCheck(CKTcircuit *, GENmodel *);

View File

@ -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;
}

View File

@ -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

View File

@ -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