From d7ecff455df0120de42b20533bd92d9c037f54ad Mon Sep 17 00:00:00 2001 From: pnenzi Date: Fri, 21 Nov 2003 22:10:46 +0000 Subject: [PATCH] Added noise analysis to bsim1, and parallel multiplier. (Do not rely on distortion analysis). --- src/spicelib/devices/bsim1/Makefile.am | 1 + src/spicelib/devices/bsim1/b1.c | 4 +- src/spicelib/devices/bsim1/b1acld.c | 73 +++++---- src/spicelib/devices/bsim1/b1ask.c | 64 ++++++-- src/spicelib/devices/bsim1/b1cvtest.c | 6 +- src/spicelib/devices/bsim1/b1del.c | 6 +- src/spicelib/devices/bsim1/b1dest.c | 5 +- src/spicelib/devices/bsim1/b1disto.c | 7 +- src/spicelib/devices/bsim1/b1dset.c | 26 ++- src/spicelib/devices/bsim1/b1eval.c | 39 +---- src/spicelib/devices/bsim1/b1getic.c | 6 +- src/spicelib/devices/bsim1/b1ld.c | 62 ++++---- src/spicelib/devices/bsim1/b1mask.c | 13 +- src/spicelib/devices/bsim1/b1mdel.c | 7 +- src/spicelib/devices/bsim1/b1moscap.c | 1 - src/spicelib/devices/bsim1/b1mpar.c | 14 +- src/spicelib/devices/bsim1/b1noi.c | 212 +++++++++++++++++++++++++ src/spicelib/devices/bsim1/b1par.c | 12 +- src/spicelib/devices/bsim1/b1pzld.c | 107 +++++++------ src/spicelib/devices/bsim1/b1set.c | 23 +-- src/spicelib/devices/bsim1/b1temp.c | 7 +- src/spicelib/devices/bsim1/b1trunc.c | 6 +- src/spicelib/devices/bsim1/bsim1def.h | 37 ++++- src/spicelib/devices/bsim1/bsim1ext.h | 24 +-- src/spicelib/devices/bsim1/bsim1init.c | 2 +- 25 files changed, 482 insertions(+), 282 deletions(-) create mode 100644 src/spicelib/devices/bsim1/b1noi.c diff --git a/src/spicelib/devices/bsim1/Makefile.am b/src/spicelib/devices/bsim1/Makefile.am index 73fc90f76..e4037786d 100644 --- a/src/spicelib/devices/bsim1/Makefile.am +++ b/src/spicelib/devices/bsim1/Makefile.am @@ -19,6 +19,7 @@ libbsim1_a_SOURCES = \ b1moscap.c \ b1mpar.c \ b1par.c \ + b1noi.c \ b1pzld.c \ b1set.c \ b1temp.c \ diff --git a/src/spicelib/devices/bsim1/b1.c b/src/spicelib/devices/bsim1/b1.c index 192561af3..9f7e58efa 100644 --- a/src/spicelib/devices/bsim1/b1.c +++ b/src/spicelib/devices/bsim1/b1.c @@ -4,7 +4,6 @@ Author: 1985 Hong J. Park, Thomas L. Quarles **********/ #include "ngspice.h" -#include #include "devdefs.h" #include "bsim1def.h" #include "suffix.h" @@ -12,6 +11,7 @@ Author: 1985 Hong J. Park, Thomas L. Quarles IFparm B1pTable[] = { /* parameters */ IOP( "l", BSIM1_L, IF_REAL , "Length"), IOP( "w", BSIM1_W, IF_REAL , "Width"), + IOP( "m", BSIM1_M, IF_REAL , "Parallel Multiplier"), IOP( "ad", BSIM1_AD, IF_REAL , "Drain area"), IOP( "as", BSIM1_AS, IF_REAL , "Source area"), IOP( "pd", BSIM1_PD, IF_REAL , "Drain perimeter"), @@ -124,6 +124,8 @@ IFparm B1mPTable[] = { /* model parameters */ "Default width of source drain diffusion in um"), IOP( "dell", BSIM1_MOD_DELLENGTH, IF_REAL, "Length reduction of source drain diffusion"), + IOP("kf", BSIM1_MOD_KF, IF_REAL ,"Flicker noise coefficient"), + IOP("af", BSIM1_MOD_AF, IF_REAL ,"Flicker noise exponent"), IP( "nmos", BSIM1_MOD_NMOS, IF_FLAG, "Flag to indicate NMOS"), IP( "pmos", BSIM1_MOD_PMOS, IF_FLAG, "Flag to indicate PMOS"), }; diff --git a/src/spicelib/devices/bsim1/b1acld.c b/src/spicelib/devices/bsim1/b1acld.c index 8ff2919ec..849f59304 100644 --- a/src/spicelib/devices/bsim1/b1acld.c +++ b/src/spicelib/devices/bsim1/b1acld.c @@ -6,7 +6,6 @@ Author: 1985 Hong J. Park, Thomas L. Quarles */ #include "ngspice.h" -#include #include "cktdefs.h" #include "bsim1def.h" #include "sperror.h" @@ -14,9 +13,7 @@ Author: 1985 Hong J. Park, Thomas L. Quarles int -B1acLoad(inModel,ckt) - GENmodel *inModel; - CKTcircuit *ckt; +B1acLoad(GENmodel *inModel, CKTcircuit *ckt) { B1model *model = (B1model*)inModel; B1instance *here; @@ -53,6 +50,7 @@ B1acLoad(inModel,ckt) double cdgb; double cdsb; double omega; /* angular fequency of the signal */ + double m; /* parallel multiplier */ omega = ckt->CKTomega; for( ; model != NULL; model = model->B1nextModel) { @@ -106,40 +104,41 @@ B1acLoad(inModel,ckt) xcbdb = (cbdb - capbd ) * omega; xcbsb = (cbsb - capbs ) * omega; + m = here->B1m; - *(here->B1GgPtr +1) += xcggb; - *(here->B1BbPtr +1) += -xcbgb-xcbdb-xcbsb; - *(here->B1DPdpPtr +1) += xcddb; - *(here->B1SPspPtr +1) += xcssb; - *(here->B1GbPtr +1) += -xcggb-xcgdb-xcgsb; - *(here->B1GdpPtr +1) += xcgdb; - *(here->B1GspPtr +1) += xcgsb; - *(here->B1BgPtr +1) += xcbgb; - *(here->B1BdpPtr +1) += xcbdb; - *(here->B1BspPtr +1) += xcbsb; - *(here->B1DPgPtr +1) += xcdgb; - *(here->B1DPbPtr +1) += -xcdgb-xcddb-xcdsb; - *(here->B1DPspPtr +1) += xcdsb; - *(here->B1SPgPtr +1) += xcsgb; - *(here->B1SPbPtr +1) += -xcsgb-xcsdb-xcssb; - *(here->B1SPdpPtr +1) += xcsdb; - *(here->B1DdPtr) += gdpr; - *(here->B1SsPtr) += gspr; - *(here->B1BbPtr) += gbd+gbs; - *(here->B1DPdpPtr) += gdpr+gds+gbd+xrev*(gm+gmbs); - *(here->B1SPspPtr) += gspr+gds+gbs+xnrm*(gm+gmbs); - *(here->B1DdpPtr) -= gdpr; - *(here->B1SspPtr) -= gspr; - *(here->B1BdpPtr) -= gbd; - *(here->B1BspPtr) -= gbs; - *(here->B1DPdPtr) -= gdpr; - *(here->B1DPgPtr) += (xnrm-xrev)*gm; - *(here->B1DPbPtr) += -gbd+(xnrm-xrev)*gmbs; - *(here->B1DPspPtr) += -gds-xnrm*(gm+gmbs); - *(here->B1SPgPtr) += -(xnrm-xrev)*gm; - *(here->B1SPsPtr) -= gspr; - *(here->B1SPbPtr) += -gbs-(xnrm-xrev)*gmbs; - *(here->B1SPdpPtr) += -gds-xrev*(gm+gmbs); + *(here->B1GgPtr +1) += m * xcggb; + *(here->B1BbPtr +1) += m * (-xcbgb-xcbdb-xcbsb); + *(here->B1DPdpPtr +1) += m * xcddb; + *(here->B1SPspPtr +1) += m * xcssb; + *(here->B1GbPtr +1) += m * (-xcggb-xcgdb-xcgsb); + *(here->B1GdpPtr +1) += m * xcgdb; + *(here->B1GspPtr +1) += m * xcgsb; + *(here->B1BgPtr +1) += m * xcbgb; + *(here->B1BdpPtr +1) += m * xcbdb; + *(here->B1BspPtr +1) += m * xcbsb; + *(here->B1DPgPtr +1) += m * xcdgb; + *(here->B1DPbPtr +1) += m * (-xcdgb-xcddb-xcdsb); + *(here->B1DPspPtr +1) += m * xcdsb; + *(here->B1SPgPtr +1) += m * xcsgb; + *(here->B1SPbPtr +1) += m * (-xcsgb-xcsdb-xcssb); + *(here->B1SPdpPtr +1) += m * xcsdb; + *(here->B1DdPtr) += m * gdpr; + *(here->B1SsPtr) += m * gspr; + *(here->B1BbPtr) += m * (gbd+gbs); + *(here->B1DPdpPtr) += m * (gdpr+gds+gbd+xrev*(gm+gmbs)); + *(here->B1SPspPtr) += m * (gspr+gds+gbs+xnrm*(gm+gmbs)); + *(here->B1DdpPtr) -= m * gdpr; + *(here->B1SspPtr) -= m * gspr; + *(here->B1BdpPtr) -= m * gbd; + *(here->B1BspPtr) -= m * gbs; + *(here->B1DPdPtr) -= m * gdpr; + *(here->B1DPgPtr) += m * (xnrm-xrev)*gm; + *(here->B1DPbPtr) += m * (-gbd+(xnrm-xrev)*gmbs); + *(here->B1DPspPtr) += m * (-gds-xnrm*(gm+gmbs)); + *(here->B1SPgPtr) += m * (-(xnrm-xrev)*gm); + *(here->B1SPsPtr) -= m * gspr; + *(here->B1SPbPtr) += m * (-gbs-(xnrm-xrev)*gmbs); + *(here->B1SPdpPtr) += m * (-gds-xrev*(gm+gmbs)); } } diff --git a/src/spicelib/devices/bsim1/b1ask.c b/src/spicelib/devices/bsim1/b1ask.c index ad4b2d3a8..737d3c9a0 100644 --- a/src/spicelib/devices/bsim1/b1ask.c +++ b/src/spicelib/devices/bsim1/b1ask.c @@ -4,7 +4,6 @@ Author: 1988 Hong J. Park **********/ #include "ngspice.h" -#include #include "ifsim.h" #include "cktdefs.h" #include "devdefs.h" @@ -14,12 +13,8 @@ Author: 1988 Hong J. Park /*ARGSUSED*/ int -B1ask(ckt,inst,which,value,select) - CKTcircuit *ckt; - GENinstance *inst; - int which; - IFvalue *value; - IFvalue *select; +B1ask(CKTcircuit *ckt, GENinstance *inst, int which, + IFvalue *value, IFvalue *select) { B1instance *here = (B1instance*)inst; @@ -29,24 +24,34 @@ B1ask(ckt,inst,which,value,select) return(OK); case BSIM1_W: value->rValue = here->B1w; + value->rValue *= here->B1m; + return(OK); + case BSIM1_M: + value->rValue = here->B1m; return(OK); case BSIM1_AS: value->rValue = here->B1sourceArea; + value->rValue *= here->B1m; return(OK); case BSIM1_AD: value->rValue = here->B1drainArea; + value->rValue *= here->B1m; return(OK); case BSIM1_PS: value->rValue = here->B1sourcePerimeter; + value->rValue *= here->B1m; return(OK); case BSIM1_PD: value->rValue = here->B1drainPerimeter; + value->rValue *= here->B1m; return(OK); case BSIM1_NRS: value->rValue = here->B1sourceSquares; + value->rValue *= here->B1m; return(OK); case BSIM1_NRD: value->rValue = here->B1drainSquares; + value->rValue *= here->B1m; return(OK); case BSIM1_OFF: value->rValue = here->B1off; @@ -80,9 +85,11 @@ B1ask(ckt,inst,which,value,select) return(OK); case BSIM1_SOURCECONDUCT: value->rValue = here->B1sourceConductance; + value->rValue *= here->B1m; return(OK); case BSIM1_DRAINCONDUCT: value->rValue = here->B1drainConductance; + value->rValue *= here->B1m; return(OK); case BSIM1_VBD: value->rValue = *(ckt->CKTstate0 + here->B1vbd); @@ -97,88 +104,115 @@ B1ask(ckt,inst,which,value,select) value->rValue = *(ckt->CKTstate0 + here->B1vds); return(OK); case BSIM1_CD: - value->rValue = *(ckt->CKTstate0 + here->B1cd); + value->rValue = *(ckt->CKTstate0 + here->B1cd); + value->rValue *= here->B1m; return(OK); case BSIM1_CBS: value->rValue = *(ckt->CKTstate0 + here->B1cbs); + value->rValue *= here->B1m; return(OK); case BSIM1_CBD: value->rValue = *(ckt->CKTstate0 + here->B1cbd); + value->rValue *= here->B1m; return(OK); case BSIM1_GM: value->rValue = *(ckt->CKTstate0 + here->B1gm); + value->rValue *= here->B1m; return(OK); case BSIM1_GDS: - value->rValue = *(ckt->CKTstate0 + here->B1gds); + value->rValue = *(ckt->CKTstate0 + here->B1gds); + value->rValue *= here->B1m; return(OK); case BSIM1_GMBS: value->rValue = *(ckt->CKTstate0 + here->B1gmbs); + value->rValue *= here->B1m; return(OK); case BSIM1_GBD: - value->rValue = *(ckt->CKTstate0 + here->B1gbd); + value->rValue = *(ckt->CKTstate0 + here->B1gbd); + value->rValue *= here->B1m; return(OK); case BSIM1_GBS: value->rValue = *(ckt->CKTstate0 + here->B1gbs); + value->rValue *= here->B1m; return(OK); case BSIM1_QB: value->rValue = *(ckt->CKTstate0 + here->B1qb); + value->rValue *= here->B1m; return(OK); case BSIM1_CQB: - value->rValue = *(ckt->CKTstate0 + here->B1cqb); + value->rValue = *(ckt->CKTstate0 + here->B1cqb); + value->rValue *= here->B1m; return(OK); case BSIM1_QG: value->rValue = *(ckt->CKTstate0 + here->B1qg); + value->rValue *= here->B1m; return(OK); case BSIM1_CQG: value->rValue = *(ckt->CKTstate0 + here->B1cqg); + value->rValue *= here->B1m; return(OK); case BSIM1_QD: value->rValue = *(ckt->CKTstate0 + here->B1qd); + value->rValue *= here->B1m; return(OK); case BSIM1_CQD: value->rValue = *(ckt->CKTstate0 + here->B1cqd); + value->rValue *= here->B1m; return(OK); case BSIM1_CGG: - value->rValue = *(ckt->CKTstate0 + here->B1cggb); + value->rValue = *(ckt->CKTstate0 + here->B1cggb); + value->rValue *= here->B1m; return(OK); case BSIM1_CGD: - value->rValue = *(ckt->CKTstate0 + here->B1cgdb); + value->rValue = *(ckt->CKTstate0 + here->B1cgdb); + value->rValue *= here->B1m; return(OK); case BSIM1_CGS: value->rValue = *(ckt->CKTstate0 + here->B1cgsb); + value->rValue *= here->B1m; return(OK); case BSIM1_CBG: value->rValue = *(ckt->CKTstate0 + here->B1cbgb); + value->rValue *= here->B1m; return(OK); case BSIM1_CAPBD: value->rValue = *(ckt->CKTstate0 + here->B1capbd); + value->rValue *= here->B1m; return(OK); case BSIM1_CQBD: value->rValue = *(ckt->CKTstate0 + here->B1cqbd); + value->rValue *= here->B1m; return(OK); case BSIM1_CAPBS: - value->rValue = *(ckt->CKTstate0 + here->B1capbs); + value->rValue = *(ckt->CKTstate0 + here->B1capbs); + value->rValue *= here->B1m; return(OK); case BSIM1_CQBS: - value->rValue = *(ckt->CKTstate0 + here->B1cqbs); + value->rValue = *(ckt->CKTstate0 + here->B1cqbs); + value->rValue *= here->B1m; return(OK); case BSIM1_CDG: value->rValue = *(ckt->CKTstate0 + here->B1cdgb); + value->rValue *= here->B1m; return(OK); case BSIM1_CDD: value->rValue = *(ckt->CKTstate0 + here->B1cddb); + value->rValue *= here->B1m; return(OK); case BSIM1_CDS: value->rValue = *(ckt->CKTstate0 + here->B1cdsb); + value->rValue *= here->B1m; return(OK); case BSIM1_VON: value->rValue = *(ckt->CKTstate0 + here->B1vono); return(OK); case BSIM1_QBS: value->rValue = *(ckt->CKTstate0 + here->B1qbs); + value->rValue *= here->B1m; return(OK); case BSIM1_QBD: value->rValue = *(ckt->CKTstate0 + here->B1qbd); + value->rValue *= here->B1m; return(OK); default: return(E_BADPARM); diff --git a/src/spicelib/devices/bsim1/b1cvtest.c b/src/spicelib/devices/bsim1/b1cvtest.c index b6bfd5805..d104a89d7 100644 --- a/src/spicelib/devices/bsim1/b1cvtest.c +++ b/src/spicelib/devices/bsim1/b1cvtest.c @@ -4,7 +4,6 @@ Author: 1985 Hong J. Park, Thomas L. Quarles **********/ #include "ngspice.h" -#include #include "cktdefs.h" #include "bsim1def.h" #include "trandefs.h" @@ -14,10 +13,7 @@ Author: 1985 Hong J. Park, Thomas L. Quarles #include "suffix.h" int -B1convTest(inModel,ckt) - - GENmodel *inModel; - CKTcircuit *ckt; +B1convTest(GENmodel *inModel, CKTcircuit *ckt) /* actually load the current value into the * sparse matrix previously provided diff --git a/src/spicelib/devices/bsim1/b1del.c b/src/spicelib/devices/bsim1/b1del.c index 25a915f4b..56068a4e0 100644 --- a/src/spicelib/devices/bsim1/b1del.c +++ b/src/spicelib/devices/bsim1/b1del.c @@ -6,7 +6,6 @@ Author: 1985 Hong J. Park, Thomas L. Quarles */ #include "ngspice.h" -#include #include "bsim1def.h" #include "sperror.h" #include "gendefs.h" @@ -14,10 +13,7 @@ Author: 1985 Hong J. Park, Thomas L. Quarles int -B1delete(inModel,name,inInst) - GENmodel *inModel; - IFuid name; - GENinstance **inInst; +B1delete(GENmodel *inModel, IFuid name, GENinstance **inInst) { diff --git a/src/spicelib/devices/bsim1/b1dest.c b/src/spicelib/devices/bsim1/b1dest.c index 577d272af..9e2276442 100644 --- a/src/spicelib/devices/bsim1/b1dest.c +++ b/src/spicelib/devices/bsim1/b1dest.c @@ -6,15 +6,12 @@ Author: 1985 Hong J. Park, Thomas L. Quarles */ #include "ngspice.h" -#include #include "bsim1def.h" #include "suffix.h" void -B1destroy(inModel) - GENmodel **inModel; - +B1destroy(GENmodel **inModel) { B1model **model = (B1model**)inModel; diff --git a/src/spicelib/devices/bsim1/b1disto.c b/src/spicelib/devices/bsim1/b1disto.c index 6855800d7..3e5102d4d 100644 --- a/src/spicelib/devices/bsim1/b1disto.c +++ b/src/spicelib/devices/bsim1/b1disto.c @@ -5,7 +5,6 @@ Modified: AlansFixes **********/ #include "ngspice.h" -#include #include "cktdefs.h" #include "bsim1def.h" #include "sperror.h" @@ -13,11 +12,7 @@ Modified: AlansFixes #include "suffix.h" int -B1disto(mode,genmodel,ckt) - GENmodel *genmodel; - CKTcircuit *ckt; - int mode; - +B1disto(int mode, GENmodel *genmodel, CKTcircuit *ckt) /* assuming here that ckt->CKTomega has been initialised to * the correct value */ diff --git a/src/spicelib/devices/bsim1/b1dset.c b/src/spicelib/devices/bsim1/b1dset.c index 9d664a0a2..57d68cf09 100644 --- a/src/spicelib/devices/bsim1/b1dset.c +++ b/src/spicelib/devices/bsim1/b1dset.c @@ -4,7 +4,6 @@ Author: 1985 Hong J. Park, Thomas L. Quarles **********/ #include "ngspice.h" -#include #include "cktdefs.h" #include "bsim1def.h" #include "trandefs.h" @@ -15,11 +14,7 @@ Author: 1985 Hong J. Park, Thomas L. Quarles #include "devdefs.h" int -B1dSetup(inModel,ckt) - - GENmodel *inModel; - CKTcircuit *ckt; - +B1dSetup(GENmodel *inModel, CKTcircuit *ckt) { B1model* model = (B1model*)inModel; B1instance *here; @@ -135,13 +130,14 @@ B1dSetup(inModel,ckt) /* loop through all the instances of the model */ for (here = model->B1instances; here != NULL ; here=here->B1nextInstance) { - if (here->B1owner != ARCHme) continue; + +if (here->B1owner != ARCHme) continue; EffectiveLength=here->B1l - model->B1deltaL * 1.e-6;/* m */ - DrainArea = here->B1drainArea; - SourceArea = here->B1sourceArea; - DrainPerimeter = here->B1drainPerimeter; - SourcePerimeter = here->B1sourcePerimeter; + DrainArea = here->B1m * here->B1drainArea; + SourceArea = here->B1m * here->B1sourceArea; + DrainPerimeter = here->B1m * here->B1drainPerimeter; + SourcePerimeter = here->B1m * here->B1sourcePerimeter; if( (DrainSatCurrent=DrainArea*model->B1jctSatCurDensity) < 1e-15){ DrainSatCurrent = 1.0e-15; @@ -150,8 +146,8 @@ B1dSetup(inModel,ckt) <1.0e-15){ SourceSatCurrent = 1.0e-15; } - GateSourceOverlapCap = model->B1gateSourceOverlapCap *here->B1w; - GateDrainOverlapCap = model->B1gateDrainOverlapCap * here->B1w; + GateSourceOverlapCap = model->B1gateSourceOverlapCap * here->B1w * here->B1m; + GateDrainOverlapCap = model->B1gateDrainOverlapCap * here->B1w * here-> B1m; GateBulkOverlapCap = model->B1gateBulkOverlapCap *EffectiveLength; vt0 = model->B1type * here->B1vt0; @@ -194,7 +190,7 @@ B1dSetup(inModel,ckt) lgbd2 = lgbd3 = 0.0; } else { evbd = exp(vbd/CONSTvt0); - lgbd1 = DrainSatCurrent*evbd/CONSTvt0 +ckt->CKTgmin; + lgbd1 = DrainSatCurrent*evbd/CONSTvt0 + ckt->CKTgmin; lgbd2 = (lgbd1 - ckt->CKTgmin)/(CONSTvt0*2); lgbd3 = lgbd2/(CONSTvt0*3); } @@ -545,7 +541,7 @@ B1dSetup(inModel,ckt) WLCox = model->B1Cox * (here->B1l - model->B1deltaL * 1.e-6) * - (here->B1w - model->B1deltaW * 1.e-6) * 1.e4; /* F */ + ((here->B1w - model->B1deltaW * 1.e-6) * here->B1m) * 1.e4; /* F */ if( ! ChargeComputationNeeded ) { qg = 0; diff --git a/src/spicelib/devices/bsim1/b1eval.c b/src/spicelib/devices/bsim1/b1eval.c index 6caef6dd3..061a97e26 100644 --- a/src/spicelib/devices/bsim1/b1eval.c +++ b/src/spicelib/devices/bsim1/b1eval.c @@ -4,7 +4,6 @@ Author: 1985 Hong J. Park, Thomas L. Quarles **********/ #include "ngspice.h" -#include #include "cktdefs.h" #include "bsim1def.h" #include "trandefs.h" @@ -16,36 +15,14 @@ Author: 1985 Hong J. Park, Thomas L. Quarles * using the B1 (Berkeley Short-Channel IGFET Model) Equations. */ void -B1evaluate(vds,vbs,vgs,here,model,gmPointer,gdsPointer,gmbsPointer, - qgPointer,qbPointer,qdPointer,cggbPointer,cgdbPointer,cgsbPointer, - cbgbPointer,cbdbPointer,cbsbPointer,cdgbPointer,cddbPointer, - cdsbPointer,cdrainPointer,vonPointer,vdsatPointer,ckt) - - CKTcircuit *ckt; - B1model *model; - B1instance *here; - double vds; - double vbs; - double vgs; - double *gmPointer; - double *gdsPointer; - double *gmbsPointer; - double *qgPointer; - double *qbPointer; - double *qdPointer; - double *cggbPointer; - double *cgdbPointer; - double *cgsbPointer; - double *cbgbPointer; - double *cbdbPointer; - double *cbsbPointer; - double *cdgbPointer; - double *cddbPointer; - double *cdsbPointer; - double *cdrainPointer; - double *vonPointer; - double *vdsatPointer; - +B1evaluate(double vds, double vbs, double vgs, B1instance *here, B1model *model, + double *gmPointer, double *gdsPointer, double *gmbsPointer, + double *qgPointer, double *qbPointer, double *qdPointer, + double *cggbPointer, double *cgdbPointer, double *cgsbPointer, + double *cbgbPointer, double *cbdbPointer, double *cbsbPointer, + double *cdgbPointer, double *cddbPointer, double *cdsbPointer, + double *cdrainPointer, double *vonPointer, double *vdsatPointer, + CKTcircuit *ckt) { double gm; double gds; diff --git a/src/spicelib/devices/bsim1/b1getic.c b/src/spicelib/devices/bsim1/b1getic.c index 5ff7c92ff..72b00b70f 100644 --- a/src/spicelib/devices/bsim1/b1getic.c +++ b/src/spicelib/devices/bsim1/b1getic.c @@ -6,7 +6,6 @@ Author: 1985 Hong J. Park, Thomas L. Quarles */ #include "ngspice.h" -#include #include "cktdefs.h" #include "bsim1def.h" #include "sperror.h" @@ -14,10 +13,7 @@ Author: 1985 Hong J. Park, Thomas L. Quarles int -B1getic(inModel,ckt) - GENmodel *inModel; - CKTcircuit *ckt; - +B1getic(GENmodel *inModel, CKTcircuit *ckt) { B1model *model = (B1model*)inModel; diff --git a/src/spicelib/devices/bsim1/b1ld.c b/src/spicelib/devices/bsim1/b1ld.c index 05a8b38c6..e268dee91 100644 --- a/src/spicelib/devices/bsim1/b1ld.c +++ b/src/spicelib/devices/bsim1/b1ld.c @@ -4,7 +4,6 @@ Author: 1985 Hong J. Park, Thomas L. Quarles **********/ #include "ngspice.h" -#include #include "cktdefs.h" #include "bsim1def.h" #include "trandefs.h" @@ -14,10 +13,7 @@ Author: 1985 Hong J. Park, Thomas L. Quarles #include "suffix.h" int -B1load(inModel,ckt) - - GENmodel *inModel; - CKTcircuit *ckt; +B1load(GENmodel *inModel, CKTcircuit *ckt) /* actually load the current value into the * sparse matrix previously provided @@ -126,6 +122,7 @@ B1load(inModel,ckt) double tempv = 0.0; int error = 0; + double m; /* parallel multiplier */ /* loop through all the B1 device models */ for( ; model != NULL; model = model->B1nextModel ) { @@ -661,7 +658,8 @@ line860: * load current vector */ line900: - + m = here->B1m; + ceqbs = model->B1type * (cbs-(gbs-ckt->CKTgmin)*vbs); ceqbd = model->B1type * (cbd-(gbd-ckt->CKTgmin)*vbd); @@ -678,41 +676,41 @@ line900: cdreq = -(model->B1type)*(cdrain+gds*vds-gm*vgd-gmbs*vbd); } - *(ckt->CKTrhs + here->B1gNode) -= ceqqg; - *(ckt->CKTrhs + here->B1bNode) -=(ceqbs+ceqbd+ceqqb); + *(ckt->CKTrhs + here->B1gNode) -= m * ceqqg; + *(ckt->CKTrhs + here->B1bNode) -= m * (ceqbs+ceqbd+ceqqb); *(ckt->CKTrhs + here->B1dNodePrime) += - (ceqbd-cdreq-ceqqd); + m * (ceqbd-cdreq-ceqqd); *(ckt->CKTrhs + here->B1sNodePrime) += - (cdreq+ceqbs+ceqqg+ceqqb+ceqqd); + m * (cdreq+ceqbs+ceqqg+ceqqb+ceqqd); /* * load y matrix */ - *(here->B1DdPtr) += (here->B1drainConductance); - *(here->B1GgPtr) += (gcggb); - *(here->B1SsPtr) += (here->B1sourceConductance); - *(here->B1BbPtr) += (gbd+gbs-gcbgb-gcbdb-gcbsb); + *(here->B1DdPtr) += m * (here->B1drainConductance); + *(here->B1GgPtr) += m * (gcggb); + *(here->B1SsPtr) += m * (here->B1sourceConductance); + *(here->B1BbPtr) += m * (gbd+gbs-gcbgb-gcbdb-gcbsb); *(here->B1DPdpPtr) += - (here->B1drainConductance+gds+gbd+xrev*(gm+gmbs)+gcddb); + m * (here->B1drainConductance+gds+gbd+xrev*(gm+gmbs)+gcddb); *(here->B1SPspPtr) += - (here->B1sourceConductance+gds+gbs+xnrm*(gm+gmbs)+gcssb); - *(here->B1DdpPtr) += (-here->B1drainConductance); - *(here->B1GbPtr) += (-gcggb-gcgdb-gcgsb); - *(here->B1GdpPtr) += (gcgdb); - *(here->B1GspPtr) += (gcgsb); - *(here->B1SspPtr) += (-here->B1sourceConductance); - *(here->B1BgPtr) += (gcbgb); - *(here->B1BdpPtr) += (-gbd+gcbdb); - *(here->B1BspPtr) += (-gbs+gcbsb); - *(here->B1DPdPtr) += (-here->B1drainConductance); - *(here->B1DPgPtr) += ((xnrm-xrev)*gm+gcdgb); - *(here->B1DPbPtr) += (-gbd+(xnrm-xrev)*gmbs-gcdgb-gcddb-gcdsb); - *(here->B1DPspPtr) += (-gds-xnrm*(gm+gmbs)+gcdsb); - *(here->B1SPgPtr) += (-(xnrm-xrev)*gm+gcsgb); - *(here->B1SPsPtr) += (-here->B1sourceConductance); - *(here->B1SPbPtr) += (-gbs-(xnrm-xrev)*gmbs-gcsgb-gcsdb-gcssb); - *(here->B1SPdpPtr) += (-gds-xrev*(gm+gmbs)+gcsdb); + m * (here->B1sourceConductance+gds+gbs+xnrm*(gm+gmbs)+gcssb); + *(here->B1DdpPtr) += m * (-here->B1drainConductance); + *(here->B1GbPtr) += m * (-gcggb-gcgdb-gcgsb); + *(here->B1GdpPtr) += m * (gcgdb); + *(here->B1GspPtr) += m * (gcgsb); + *(here->B1SspPtr) += m * (-here->B1sourceConductance); + *(here->B1BgPtr) += m * (gcbgb); + *(here->B1BdpPtr) += m * (-gbd+gcbdb); + *(here->B1BspPtr) += m * (-gbs+gcbsb); + *(here->B1DPdPtr) += m * (-here->B1drainConductance); + *(here->B1DPgPtr) += m * ((xnrm-xrev)*gm+gcdgb); + *(here->B1DPbPtr) += m * (-gbd+(xnrm-xrev)*gmbs-gcdgb-gcddb-gcdsb); + *(here->B1DPspPtr) += m * (-gds-xnrm*(gm+gmbs)+gcdsb); + *(here->B1SPgPtr) += m * (-(xnrm-xrev)*gm+gcsgb); + *(here->B1SPsPtr) += m * (-here->B1sourceConductance); + *(here->B1SPbPtr) += m * (-gbs-(xnrm-xrev)*gmbs-gcsgb-gcsdb-gcssb); + *(here->B1SPdpPtr) += m * (-gds-xrev*(gm+gmbs)+gcsdb); line1000: ; diff --git a/src/spicelib/devices/bsim1/b1mask.c b/src/spicelib/devices/bsim1/b1mask.c index fc70b05e6..6dcbb345c 100644 --- a/src/spicelib/devices/bsim1/b1mask.c +++ b/src/spicelib/devices/bsim1/b1mask.c @@ -6,7 +6,6 @@ Author: 1988 Hong J. Park */ #include "ngspice.h" -#include #include "ifsim.h" #include "cktdefs.h" #include "devdefs.h" @@ -17,11 +16,7 @@ Author: 1988 Hong J. Park /*ARGSUSED*/ int -B1mAsk(ckt,inst,which,value) - CKTcircuit *ckt; - GENmodel *inst; - int which; - IFvalue *value; +B1mAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value) { B1model *model = (B1model *)inst; switch(which) { @@ -256,6 +251,12 @@ B1mAsk(ckt,inst,which,value) case BSIM1_MOD_DELLENGTH: value->rValue = model->B1deltaLength; return(OK); + case BSIM1_MOD_AF: + value->rValue = model->B1fNexp; + return(OK); + case BSIM1_MOD_KF: + value->rValue = model->B1fNcoef; + return(OK); default: return(E_BADPARM); } diff --git a/src/spicelib/devices/bsim1/b1mdel.c b/src/spicelib/devices/bsim1/b1mdel.c index e4cd68a57..7233277f5 100644 --- a/src/spicelib/devices/bsim1/b1mdel.c +++ b/src/spicelib/devices/bsim1/b1mdel.c @@ -6,18 +6,13 @@ Author: 1985 Hong J. Park, Thomas L. Quarles */ #include "ngspice.h" -#include #include "bsim1def.h" #include "sperror.h" #include "suffix.h" int -B1mDelete(inModel,modname,kill) - GENmodel **inModel; - IFuid modname; - GENmodel *kill; - +B1mDelete(GENmodel **inModel, IFuid modname, GENmodel *kill) { B1model **model = (B1model**)inModel; B1model *modfast = (B1model*)kill; diff --git a/src/spicelib/devices/bsim1/b1moscap.c b/src/spicelib/devices/bsim1/b1moscap.c index ad1d96b41..976ee9369 100644 --- a/src/spicelib/devices/bsim1/b1moscap.c +++ b/src/spicelib/devices/bsim1/b1moscap.c @@ -4,7 +4,6 @@ Author: 1985 Hong J. Park, Thomas L. Quarles **********/ #include "ngspice.h" -#include #include "cktdefs.h" #include "bsim1def.h" #include "suffix.h" diff --git a/src/spicelib/devices/bsim1/b1mpar.c b/src/spicelib/devices/bsim1/b1mpar.c index de6b1802b..027604959 100644 --- a/src/spicelib/devices/bsim1/b1mpar.c +++ b/src/spicelib/devices/bsim1/b1mpar.c @@ -6,7 +6,6 @@ Author: 1985 Hong J. Park, Thomas L. Quarles */ #include "ngspice.h" -#include #include "bsim1def.h" #include "ifsim.h" #include "sperror.h" @@ -14,10 +13,7 @@ Author: 1985 Hong J. Park, Thomas L. Quarles int -B1mParam(param,value,inMod) - int param; - IFvalue *value; - GENmodel *inMod; +B1mParam(int param, IFvalue *value, GENmodel *inMod) { B1model *mod = (B1model*)inMod; switch(param) { @@ -329,6 +325,14 @@ B1mParam(param,value,inMod) mod->B1deltaLength = value->rValue; mod->B1deltaLengthGiven = TRUE; break; + case BSIM1_MOD_AF : + mod->B1fNexp = value->rValue; + mod->B1fNexpGiven = TRUE; + break; + case BSIM1_MOD_KF : + mod->B1fNcoef = value->rValue; + mod->B1fNcoefGiven = TRUE; + break; case BSIM1_MOD_NMOS : if(value->iValue) { mod->B1type = 1; diff --git a/src/spicelib/devices/bsim1/b1noi.c b/src/spicelib/devices/bsim1/b1noi.c new file mode 100644 index 000000000..bacc8c97a --- /dev/null +++ b/src/spicelib/devices/bsim1/b1noi.c @@ -0,0 +1,212 @@ +/********** +Copyright 2003 ??. All rights reserved. +Author: 2003 Paolo Nenzi +**********/ + +#include "ngspice.h" +#include "bsim1def.h" +#include "cktdefs.h" +#include "iferrmsg.h" +#include "noisedef.h" +#include "suffix.h" + +/* + * B1noise (mode, operation, firstModel, ckt, data, OnDens) + * This routine names and evaluates all of the noise sources + * associated with MOSFET's. It starts with the model *firstModel and + * traverses all of its insts. It then proceeds to any other models + * on the linked list. The total output noise density generated by + * all of the MOSFET's is summed with the variable "OnDens". + */ + +extern void NevalSrc(); +extern double Nintegrate(); + +int +B1noise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, + Ndata *data, double *OnDens) +{ + B1model *firstModel = (B1model *) genmodel; + B1model *model; + B1instance *inst; + char name[N_MXVLNTH]; + double tempOnoise; + double tempInoise; + double noizDens[B1NSRCS]; + double lnNdens[B1NSRCS]; + int i; + + /* define the names of the noise sources */ + + static char *B1nNames[B1NSRCS] = { /* Note that we have to keep the order */ + "_rd", /* noise due to rd */ /* consistent with thestrchr definitions */ + "_rs", /* noise due to rs */ /* in bsim1defs.h */ + "_id", /* noise due to id */ + "_1overf", /* flicker (1/f) noise */ + "" /* total transistor noise */ + }; + + for (model=firstModel; model != NULL; model=model->B1nextModel) { + for (inst=model->B1instances; inst != NULL; inst=inst->B1nextInstance) { + if (inst->B1owner != ARCHme) continue; + + switch (operation) { + + case N_OPEN: + + /* see if we have to to produce a summary report */ + /* if so, name all the noise generators */ + + if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) { + switch (mode) { + + case N_DENS: + for (i=0; i < B1NSRCS; i++) { + (void)sprintf(name,"onoise_%s%s",inst->B1name,B1nNames[i]); + + +data->namelist = (IFuid *)trealloc((char *)data->namelist,(data->numPlots + 1)*sizeof(IFuid)); +if (!data->namelist) return(E_NOMEM); + (*(SPfrontEnd->IFnewUid))(ckt, + &(data->namelist[data->numPlots++]), + (IFuid)NULL,name,UID_OTHER,(void **)NULL); + /* we've added one more plot */ + + + } + break; + + case INT_NOIZ: + for (i=0; i < B1NSRCS; i++) { + (void)sprintf(name,"onoise_total_%s%s",inst->B1name,B1nNames[i]); + + +data->namelist = (IFuid *)trealloc((char *)data->namelist,(data->numPlots + 1)*sizeof(IFuid)); +if (!data->namelist) return(E_NOMEM); + (*(SPfrontEnd->IFnewUid))(ckt, + &(data->namelist[data->numPlots++]), + (IFuid)NULL,name,UID_OTHER,(void **)NULL); + /* we've added one more plot */ + + + (void)sprintf(name,"inoise_total_%s%s",inst->B1name,B1nNames[i]); + + +data->namelist = (IFuid *)trealloc((char *)data->namelist,(data->numPlots + 1)*sizeof(IFuid)); +if (!data->namelist) return(E_NOMEM); + (*(SPfrontEnd->IFnewUid))(ckt, + &(data->namelist[data->numPlots++]), + (IFuid)NULL,name,UID_OTHER,(void **)NULL); + /* we've added one more plot */ + + + + } + break; + } + } + break; + + case N_CALC: + switch (mode) { + + case N_DENS: + NevalSrc(&noizDens[B1RDNOIZ],&lnNdens[B1RDNOIZ], + ckt,THERMNOISE,inst->B1dNodePrime,inst->B1dNode, + inst->B1drainConductance * inst->B1m); + + NevalSrc(&noizDens[B1RSNOIZ],&lnNdens[B1RSNOIZ], + ckt,THERMNOISE,inst->B1sNodePrime,inst->B1sNode, + inst->B1sourceConductance * inst->B1m); + + NevalSrc(&noizDens[B1IDNOIZ],&lnNdens[B1IDNOIZ], + ckt,THERMNOISE,inst->B1dNodePrime,inst->B1sNodePrime, + (2.0/3.0 * fabs(inst->B1gm * inst->B1m))); + + NevalSrc(&noizDens[B1FLNOIZ],(double*)NULL,ckt, + N_GAIN,inst->B1dNodePrime, inst->B1sNodePrime, + (double)0.0); + noizDens[B1FLNOIZ] *= model->B1fNcoef * inst->B1m * + exp(model->B1fNexp * + log(MAX(fabs(inst->B1cd),N_MINLOG))) / + (data->freq * + (inst->B1w - model->B1deltaW * 1e-6) * + (inst->B1l - model->B1deltaL * 1e-6) * + model->B1Cox * model->B1Cox); + lnNdens[B1FLNOIZ] = + log(MAX(noizDens[B1FLNOIZ],N_MINLOG)); + + noizDens[B1TOTNOIZ] = noizDens[B1RDNOIZ] + + noizDens[B1RSNOIZ] + + noizDens[B1IDNOIZ] + + noizDens[B1FLNOIZ]; + lnNdens[B1TOTNOIZ] = + log(MAX(noizDens[B1TOTNOIZ], N_MINLOG)); + + *OnDens += noizDens[B1TOTNOIZ]; + + if (data->delFreq == 0.0) { + + /* if we haven't done any previous integration, we need to */ + /* initialize our "history" variables */ + + for (i=0; i < B1NSRCS; i++) { + inst->B1nVar[LNLSTDENS][i] = lnNdens[i]; + } + + /* clear out our integration variables if it's the first pass */ + + if (data->freq == ((NOISEAN*)ckt->CKTcurJob)->NstartFreq) { + for (i=0; i < B1NSRCS; i++) { + inst->B1nVar[OUTNOIZ][i] = 0.0; + inst->B1nVar[INNOIZ][i] = 0.0; + } + } + } else { /* data->delFreq != 0.0 (we have to integrate) */ + for (i=0; i < B1NSRCS; i++) { + if (i != B1TOTNOIZ) { + tempOnoise = Nintegrate(noizDens[i], lnNdens[i], + inst->B1nVar[LNLSTDENS][i], data); + tempInoise = Nintegrate(noizDens[i] * data->GainSqInv , + lnNdens[i] + data->lnGainInv, + inst->B1nVar[LNLSTDENS][i] + data->lnGainInv, + data); + inst->B1nVar[LNLSTDENS][i] = lnNdens[i]; + data->outNoiz += tempOnoise; + data->inNoise += tempInoise; + if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) { + inst->B1nVar[OUTNOIZ][i] += tempOnoise; + inst->B1nVar[OUTNOIZ][B1TOTNOIZ] += tempOnoise; + inst->B1nVar[INNOIZ][i] += tempInoise; + inst->B1nVar[INNOIZ][B1TOTNOIZ] += tempInoise; + } + } + } + } + if (data->prtSummary) { + for (i=0; i < B1NSRCS; i++) { /* print a summary report */ + data->outpVector[data->outNumber++] = noizDens[i]; + } + } + break; + + case INT_NOIZ: /* already calculated, just output */ + if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) { + for (i=0; i < B1NSRCS; i++) { + data->outpVector[data->outNumber++] = inst->B1nVar[OUTNOIZ][i]; + data->outpVector[data->outNumber++] = inst->B1nVar[INNOIZ][i]; + } + } /* if */ + break; + } /* switch (mode) */ + break; + + case N_CLOSE: + return (OK); /* do nothing, the main calling routine will close */ + break; /* the plots */ + } /* switch (operation) */ + } /* for inst */ + } /* for model */ + +return(OK); +} diff --git a/src/spicelib/devices/bsim1/b1par.c b/src/spicelib/devices/bsim1/b1par.c index 0e5f2a4f8..501696286 100644 --- a/src/spicelib/devices/bsim1/b1par.c +++ b/src/spicelib/devices/bsim1/b1par.c @@ -6,7 +6,6 @@ Author: 1985 Hong J. Park, Thomas L. Quarles */ #include "ngspice.h" -#include #include "ifsim.h" #include "bsim1def.h" #include "sperror.h" @@ -15,11 +14,8 @@ Author: 1985 Hong J. Park, Thomas L. Quarles /* ARGSUSED */ int -B1param(param,value,inst,select) - int param; - IFvalue *value; - GENinstance *inst; - IFvalue *select; +B1param(int param, IFvalue *value, GENinstance *inst, + IFvalue *select) { B1instance *here = (B1instance*)inst; switch(param) { @@ -31,6 +27,10 @@ B1param(param,value,inst,select) here->B1l = value->rValue; here->B1lGiven = TRUE; break; + case BSIM1_M: + here->B1m = value->rValue; + here->B1mGiven = TRUE; + break; case BSIM1_AS: here->B1sourceArea = value->rValue; here->B1sourceAreaGiven = TRUE; diff --git a/src/spicelib/devices/bsim1/b1pzld.c b/src/spicelib/devices/bsim1/b1pzld.c index 3df57b7cd..8d370629d 100644 --- a/src/spicelib/devices/bsim1/b1pzld.c +++ b/src/spicelib/devices/bsim1/b1pzld.c @@ -6,7 +6,6 @@ Author: 1985 Thomas L. Quarles */ #include "ngspice.h" -#include #include "cktdefs.h" #include "complex.h" #include "sperror.h" @@ -15,10 +14,7 @@ Author: 1985 Thomas L. Quarles int -B1pzLoad(inModel,ckt,s) - GENmodel *inModel; - CKTcircuit *ckt; - SPcomplex *s; +B1pzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s) { B1model *model = (B1model*)inModel; B1instance *here; @@ -55,6 +51,8 @@ B1pzLoad(inModel,ckt,s) double cdgb; double cdsb; + double m; + for( ; model != NULL; model = model->B1nextModel) { for(here = model->B1instances; here!= NULL; here = here->B1nextInstance) { @@ -106,56 +104,57 @@ B1pzLoad(inModel,ckt,s) xcbdb = (cbdb - capbd ) ; xcbsb = (cbsb - capbs ) ; + m = here->B1m; - *(here->B1GgPtr ) += xcggb * s->real; - *(here->B1GgPtr +1) += xcggb * s->imag; - *(here->B1BbPtr ) += (-xcbgb-xcbdb-xcbsb) * s->real; - *(here->B1BbPtr +1) += (-xcbgb-xcbdb-xcbsb) * s->imag; - *(here->B1DPdpPtr ) += xcddb * s->real; - *(here->B1DPdpPtr +1) += xcddb * s->imag; - *(here->B1SPspPtr ) += xcssb * s->real; - *(here->B1SPspPtr +1) += xcssb * s->imag; - *(here->B1GbPtr ) += (-xcggb-xcgdb-xcgsb) * s->real; - *(here->B1GbPtr +1) += (-xcggb-xcgdb-xcgsb) * s->imag; - *(here->B1GdpPtr ) += xcgdb * s->real; - *(here->B1GdpPtr +1) += xcgdb * s->imag; - *(here->B1GspPtr ) += xcgsb * s->real; - *(here->B1GspPtr +1) += xcgsb * s->imag; - *(here->B1BgPtr ) += xcbgb * s->real; - *(here->B1BgPtr +1) += xcbgb * s->imag; - *(here->B1BdpPtr ) += xcbdb * s->real; - *(here->B1BdpPtr +1) += xcbdb * s->imag; - *(here->B1BspPtr ) += xcbsb * s->real; - *(here->B1BspPtr +1) += xcbsb * s->imag; - *(here->B1DPgPtr ) += xcdgb * s->real; - *(here->B1DPgPtr +1) += xcdgb * s->imag; - *(here->B1DPbPtr ) += (-xcdgb-xcddb-xcdsb) * s->real; - *(here->B1DPbPtr +1) += (-xcdgb-xcddb-xcdsb) * s->imag; - *(here->B1DPspPtr ) += xcdsb * s->real; - *(here->B1DPspPtr +1) += xcdsb * s->imag; - *(here->B1SPgPtr ) += xcsgb * s->real; - *(here->B1SPgPtr +1) += xcsgb * s->imag; - *(here->B1SPbPtr ) += (-xcsgb-xcsdb-xcssb) * s->real; - *(here->B1SPbPtr +1) += (-xcsgb-xcsdb-xcssb) * s->imag; - *(here->B1SPdpPtr ) += xcsdb * s->real; - *(here->B1SPdpPtr +1) += xcsdb * s->imag; - *(here->B1DdPtr) += gdpr; - *(here->B1SsPtr) += gspr; - *(here->B1BbPtr) += gbd+gbs; - *(here->B1DPdpPtr) += gdpr+gds+gbd+xrev*(gm+gmbs); - *(here->B1SPspPtr) += gspr+gds+gbs+xnrm*(gm+gmbs); - *(here->B1DdpPtr) -= gdpr; - *(here->B1SspPtr) -= gspr; - *(here->B1BdpPtr) -= gbd; - *(here->B1BspPtr) -= gbs; - *(here->B1DPdPtr) -= gdpr; - *(here->B1DPgPtr) += (xnrm-xrev)*gm; - *(here->B1DPbPtr) += -gbd+(xnrm-xrev)*gmbs; - *(here->B1DPspPtr) += -gds-xnrm*(gm+gmbs); - *(here->B1SPgPtr) += -(xnrm-xrev)*gm; - *(here->B1SPsPtr) -= gspr; - *(here->B1SPbPtr) += -gbs-(xnrm-xrev)*gmbs; - *(here->B1SPdpPtr) += -gds-xrev*(gm+gmbs); + *(here->B1GgPtr ) += m * (xcggb * s->real); + *(here->B1GgPtr +1) += m * (xcggb * s->imag); + *(here->B1BbPtr ) += m * ((-xcbgb-xcbdb-xcbsb) * s->real); + *(here->B1BbPtr +1) += m * ((-xcbgb-xcbdb-xcbsb) * s->imag); + *(here->B1DPdpPtr ) += m * (xcddb * s->real); + *(here->B1DPdpPtr +1) += m * (xcddb * s->imag); + *(here->B1SPspPtr ) += m * (xcssb * s->real); + *(here->B1SPspPtr +1) += m * (xcssb * s->imag); + *(here->B1GbPtr ) += m * ((-xcggb-xcgdb-xcgsb) * s->real); + *(here->B1GbPtr +1) += m * ((-xcggb-xcgdb-xcgsb) * s->imag); + *(here->B1GdpPtr ) += m * (xcgdb * s->real); + *(here->B1GdpPtr +1) += m * (xcgdb * s->imag); + *(here->B1GspPtr ) += m * (xcgsb * s->real); + *(here->B1GspPtr +1) += m * (xcgsb * s->imag); + *(here->B1BgPtr ) += m * (xcbgb * s->real); + *(here->B1BgPtr +1) += m * (xcbgb * s->imag); + *(here->B1BdpPtr ) += m * (xcbdb * s->real); + *(here->B1BdpPtr +1) += m * (xcbdb * s->imag); + *(here->B1BspPtr ) += m * (xcbsb * s->real); + *(here->B1BspPtr +1) += m * (xcbsb * s->imag); + *(here->B1DPgPtr ) += m * (xcdgb * s->real); + *(here->B1DPgPtr +1) += m * (xcdgb * s->imag); + *(here->B1DPbPtr ) += m * ((-xcdgb-xcddb-xcdsb) * s->real); + *(here->B1DPbPtr +1) += m * ((-xcdgb-xcddb-xcdsb) * s->imag); + *(here->B1DPspPtr ) += m * (xcdsb * s->real); + *(here->B1DPspPtr +1) += m * (xcdsb * s->imag); + *(here->B1SPgPtr ) += m * (xcsgb * s->real); + *(here->B1SPgPtr +1) += m * (xcsgb * s->imag); + *(here->B1SPbPtr ) += m * ((-xcsgb-xcsdb-xcssb) * s->real); + *(here->B1SPbPtr +1) += m * ((-xcsgb-xcsdb-xcssb) * s->imag); + *(here->B1SPdpPtr ) += m * (xcsdb * s->real); + *(here->B1SPdpPtr +1) += m * (xcsdb * s->imag); + *(here->B1DdPtr) += m * (gdpr); + *(here->B1SsPtr) += m * (gspr); + *(here->B1BbPtr) += m * (gbd+gbs); + *(here->B1DPdpPtr) += m * (gdpr+gds+gbd+xrev*(gm+gmbs)); + *(here->B1SPspPtr) += m * (gspr+gds+gbs+xnrm*(gm+gmbs)); + *(here->B1DdpPtr) -= m * (gdpr); + *(here->B1SspPtr) -= m * (gspr); + *(here->B1BdpPtr) -= m * (gbd); + *(here->B1BspPtr) -= m * (gbs); + *(here->B1DPdPtr) -= m * (gdpr); + *(here->B1DPgPtr) += m * ((xnrm-xrev)*gm); + *(here->B1DPbPtr) += m * (-gbd+(xnrm-xrev)*gmbs); + *(here->B1DPspPtr) += m * (-gds-xnrm*(gm+gmbs)); + *(here->B1SPgPtr) += m * (-(xnrm-xrev)*gm); + *(here->B1SPsPtr) -= m * (gspr); + *(here->B1SPbPtr) += m * (-gbs-(xnrm-xrev)*gmbs); + *(here->B1SPdpPtr) += m * (-gds-xrev*(gm+gmbs)); } } diff --git a/src/spicelib/devices/bsim1/b1set.c b/src/spicelib/devices/bsim1/b1set.c index 2a697fbd8..18ff36c7a 100644 --- a/src/spicelib/devices/bsim1/b1set.c +++ b/src/spicelib/devices/bsim1/b1set.c @@ -4,7 +4,6 @@ Author: 1985 Hong J. Park, Thomas L. Quarles **********/ #include "ngspice.h" -#include #include "smpdefs.h" #include "cktdefs.h" #include "bsim1def.h" @@ -13,11 +12,8 @@ Author: 1985 Hong J. Park, Thomas L. Quarles #include "suffix.h" int -B1setup(matrix,inModel,ckt,states) - SMPmatrix *matrix; - GENmodel *inModel; - CKTcircuit *ckt; - int *states; +B1setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, + int *states) /* load the B1 device structure with those pointers needed later * for fast matrix loading */ @@ -266,6 +262,12 @@ B1setup(matrix,inModel,ckt,states) if( ! model->B1deltaLengthGiven) { model->B1deltaLength = 0.0; } + if( ! model->B1fNcoefGiven) { + model->B1fNcoef = 0.0; + } + if( ! model->B1fNexpGiven) { + model->B1fNexp = 1.0; + } /* loop through all the instances of the model */ for (here = model->B1instances; here != NULL ; @@ -320,7 +322,10 @@ B1setup(matrix,inModel,ckt,states) if(!here->B1wGiven) { here->B1w = 5e-6; } - + if(!here->B1mGiven) { + here->B1m = 1.0; + } + /* process drain series resistance */ if( (model->B1sheetResistance != 0) && (here->B1drainSquares != 0.0 ) && @@ -398,9 +403,7 @@ if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\ } int -B1unsetup(inModel,ckt) - GENmodel *inModel; - CKTcircuit *ckt; +B1unsetup(GENmodel *inModel, CKTcircuit *ckt) { B1model *model; B1instance *here; diff --git a/src/spicelib/devices/bsim1/b1temp.c b/src/spicelib/devices/bsim1/b1temp.c index a399e0da8..ee872e289 100644 --- a/src/spicelib/devices/bsim1/b1temp.c +++ b/src/spicelib/devices/bsim1/b1temp.c @@ -4,7 +4,6 @@ Author: 1985 Hong J. Park, Thomas L. Quarles **********/ #include "ngspice.h" -#include #include "smpdefs.h" #include "cktdefs.h" #include "bsim1def.h" @@ -14,13 +13,10 @@ Author: 1985 Hong J. Park, Thomas L. Quarles /* ARGSUSED */ int -B1temp(inModel,ckt) - GENmodel *inModel; - CKTcircuit *ckt; +B1temp(GENmodel *inModel, CKTcircuit *ckt) /* load the B1 device structure with those pointers needed later * for fast matrix loading */ - { B1model *model = (B1model*) inModel; B1instance *here; @@ -49,6 +45,7 @@ B1temp(inModel,ckt) /* loop through all the instances of the model */ for (here = model->B1instances; here != NULL ; here=here->B1nextInstance) { + if (here->B1owner != ARCHme) continue; if( (EffChanLength = here->B1l - model->B1deltaL *1e-6 )<=0) { diff --git a/src/spicelib/devices/bsim1/b1trunc.c b/src/spicelib/devices/bsim1/b1trunc.c index 240005a32..17d51acf5 100644 --- a/src/spicelib/devices/bsim1/b1trunc.c +++ b/src/spicelib/devices/bsim1/b1trunc.c @@ -4,17 +4,13 @@ Author: 1985 Hong J. Park, Thomas L. Quarles **********/ #include "ngspice.h" -#include #include "cktdefs.h" #include "bsim1def.h" #include "sperror.h" #include "suffix.h" int -B1trunc(inModel,ckt,timeStep) - GENmodel *inModel; - CKTcircuit *ckt; - double *timeStep; +B1trunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep) { B1model *model = (B1model*)inModel; diff --git a/src/spicelib/devices/bsim1/bsim1def.h b/src/spicelib/devices/bsim1/bsim1def.h index 5177d3158..970905b28 100644 --- a/src/spicelib/devices/bsim1/bsim1def.h +++ b/src/spicelib/devices/bsim1/bsim1def.h @@ -10,6 +10,7 @@ Author: 1985 Hong June Park, Thomas L. Quarles #include "gendefs.h" #include "cktdefs.h" #include "complex.h" +#include "noisedef.h" /* declarations for B1 MOSFETs */ @@ -34,7 +35,8 @@ typedef struct sBSIM1instance { int B1sNodePrime; /* number of the internal source node of the mosfet */ double B1l; /* the length of the channel region */ - double B1w; /* the width of the channel region */ + double B1w; /* the width of the channel region */ + double B1m; /* the parallel multiplier */ double B1drainArea; /* the area of the drain diffusion */ double B1sourceArea; /* the area of the source diffusion */ double B1drainSquares; /* the length of the drain in squares */ @@ -82,6 +84,7 @@ typedef struct sBSIM1instance { unsigned B1channelChargePartitionFlag :1; unsigned B1lGiven :1; unsigned B1wGiven :1; + unsigned B1mGiven :1; unsigned B1drainAreaGiven :1; unsigned B1sourceAreaGiven :1; unsigned B1drainSquaresGiven :1; @@ -148,6 +151,22 @@ typedef struct sBSIM1instance { #else /* NODISTO */ double *B1dCoeffs; #endif /* NODISTO */ +/* indices to the array of BSIM1 noise sources */ + +#define B1RDNOIZ 0 +#define B1RSNOIZ 1 +#define B1IDNOIZ 2 +#define B1FLNOIZ 3 +#define B1TOTNOIZ 4 + +#define B1NSRCS 5 /* the number of BSIM1 noise sources */ + +#ifndef NONOISE + double B1nVar[NSTATVARS][B1NSRCS]; +#else /* NONOISE */ + double **B1nVar; +#endif /* NONOISE */ + } B1instance ; @@ -385,6 +404,10 @@ typedef struct sBSIM1model { /* model structure for a resistor */ double B1defaultWidth; double B1deltaLength; + double B1fNcoef; + double B1fNexp; + + unsigned B1vfb0Given :1; unsigned B1vfbLGiven :1; @@ -463,6 +486,10 @@ typedef struct sBSIM1model { /* model structure for a resistor */ unsigned B1unitLengthSidewallJctCapGiven :1; unsigned B1defaultWidthGiven :1; unsigned B1deltaLengthGiven :1; + + unsigned B1fNcoefGiven :1; + unsigned B1fNexpGiven :1; + unsigned B1typeGiven :1; } B1model; @@ -488,6 +515,7 @@ typedef struct sBSIM1model { /* model structure for a resistor */ #define BSIM1_IC_VDS 11 #define BSIM1_IC_VGS 12 #define BSIM1_IC 13 +#define BSIM1_M 14 /* model parameters */ #define BSIM1_MOD_VFB0 101 @@ -570,6 +598,9 @@ typedef struct sBSIM1model { /* model structure for a resistor */ #define BSIM1_MOD_NMOS 178 #define BSIM1_MOD_PMOS 179 +#define BSIM1_MOD_KF 180 +#define BSIM1_MOD_AF 181 + /* device questions */ #define BSIM1_DNODE 201 #define BSIM1_GNODE 202 @@ -616,13 +647,9 @@ typedef struct sBSIM1model { /* model structure for a resistor */ #include "bsim1ext.h" -#ifdef __STDC__ extern void B1evaluate(double,double,double,B1instance*,B1model*, double*,double*,double*, double*, double*, double*, double*, double*, double*, double*, double*, double*, double*, double*, double*, double*, double*, double*, CKTcircuit*); -#else /* stdc */ -extern void B1evaluate(); -#endif /* stdc */ #endif /*B1*/ diff --git a/src/spicelib/devices/bsim1/bsim1ext.h b/src/spicelib/devices/bsim1/bsim1ext.h index 96f6b43b7..e859e3009 100644 --- a/src/spicelib/devices/bsim1/bsim1ext.h +++ b/src/spicelib/devices/bsim1/bsim1ext.h @@ -4,7 +4,7 @@ Author: 1985 Hong June Park, Thomas L. Quarles Modified: 2000 AlansFixes **********/ -#ifdef __STDC__ + extern int B1acLoad(GENmodel *,CKTcircuit*); extern int B1ask(CKTcircuit *,GENinstance*,int,IFvalue*,IFvalue*); extern int B1convTest(GENmodel *,CKTcircuit*); @@ -20,6 +20,7 @@ extern void B1mosCap(CKTcircuit*, double, double, double, double*, double*, double*, double*, double*, double*, double*, double*, double*, double*, double*, double*, double*, double*, double*, double*, double*); +extern int B1noise (int, int, GENmodel *, CKTcircuit *, Ndata *, double *); extern int B1param(int,IFvalue*,GENinstance*,IFvalue*); extern int B1pzLoad(GENmodel*,CKTcircuit*,SPcomplex*); extern int B1setup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); @@ -28,24 +29,3 @@ extern int B1temp(GENmodel*,CKTcircuit*); extern int B1trunc(GENmodel*,CKTcircuit*,double*); extern int B1disto(int,GENmodel*,CKTcircuit*); extern int B1dSetup(GENmodel*, register CKTcircuit*); -#else /* stdc */ -extern int B1acLoad(); -extern int B1ask(); -extern int B1convTest(); -extern int B1delete(); -extern void B1destroy(); -extern int B1getic(); -extern int B1load(); -extern int B1mAsk(); -extern int B1mDelete(); -extern int B1mParam(); -extern void B1mosCap(); -extern int B1param(); -extern int B1pzLoad(); -extern int B1setup(); -extern int B1unsetup(); -extern int B1temp(); -extern int B1trunc(); -extern int B1disto(); -#endif /* stdc */ - diff --git a/src/spicelib/devices/bsim1/bsim1init.c b/src/spicelib/devices/bsim1/bsim1init.c index b069c386f..39b51c5a9 100644 --- a/src/spicelib/devices/bsim1/bsim1init.c +++ b/src/spicelib/devices/bsim1/bsim1init.c @@ -66,7 +66,7 @@ SPICEdev B1info = { DEVsenPrint : NULL, DEVsenTrunc : NULL, DEVdisto : B1disto, - DEVnoise : NULL, /* NOISE */ + DEVnoise : B1noise, /* NOISE */ #ifdef CIDER DEVdump : NULL, DEVacct : NULL,