From 36b3c18401082b914ad96e5015f5228501b12323 Mon Sep 17 00:00:00 2001 From: dwarning Date: Thu, 5 May 2011 20:09:24 +0000 Subject: [PATCH] delvto and mulu0 instance parameter --- ChangeLog | 4 + src/spicelib/devices/bsim3v32/b3v32.c | 20 +- src/spicelib/devices/bsim3v32/b3v32ask.c | 6 + src/spicelib/devices/bsim3v32/b3v32check.c | 306 ++++---- src/spicelib/devices/bsim3v32/b3v32ld.c | 46 +- src/spicelib/devices/bsim3v32/b3v32par.c | 18 +- src/spicelib/devices/bsim3v32/b3v32set.c | 11 +- src/spicelib/devices/bsim3v32/b3v32temp.c | 731 ++++++++++---------- src/spicelib/devices/bsim3v32/bsim3v32def.h | 13 +- 9 files changed, 597 insertions(+), 558 deletions(-) diff --git a/ChangeLog b/ChangeLog index c4aabc9cb..83206311b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-05-05 Dietmar Warning + * spicelib/devices/bsim3v32/*.c, *.h: allow delvto and mulu0 as instance + parameter, usefull for stress amn mismatch simulations + 2011-05-04 Dietmar Warning * spicelib/parser/inpdomod.c: vbic now accept level 4 and 9 * DEVICES: update and include HiSIM HV model. diff --git a/src/spicelib/devices/bsim3v32/b3v32.c b/src/spicelib/devices/bsim3v32/b3v32.c index c9fab3895..f3b205f5e 100644 --- a/src/spicelib/devices/bsim3v32/b3v32.c +++ b/src/spicelib/devices/bsim3v32/b3v32.c @@ -26,16 +26,18 @@ IOP( "nrd", BSIM3v32_NRD, IF_REAL , "Number of squares in drain"), IOP( "nrs", BSIM3v32_NRS, IF_REAL , "Number of squares in source"), IOP( "off", BSIM3v32_OFF, IF_FLAG , "Device is initially off"), IOP( "nqsmod", BSIM3v32_NQSMOD, IF_INTEGER, "Non-quasi-static model selector"), +IOP( "delvto", BSIM3v32_DELVTO, IF_REAL , "Zero bias threshold voltage variation"), +IOP( "mulu0", BSIM3v32_MULU0, IF_REAL , "Low field mobility multiplier"), IP( "ic", BSIM3v32_IC, IF_REALVEC , "Vector of DS,GS,BS initial voltages"), -OP( "gmbs", BSIM3v32_GMBS, IF_REAL, "Gmb"), -OP( "gm", BSIM3v32_GM, IF_REAL, "Gm"), -OP( "gds", BSIM3v32_GDS, IF_REAL, "Gds"), -OP( "vdsat", BSIM3v32_VDSAT, IF_REAL, "Vdsat"), -OP( "vth", BSIM3v32_VON, IF_REAL, "Vth"), -OP( "id", BSIM3v32_CD, IF_REAL, "Ids"), -OP( "vbs", BSIM3v32_VBS, IF_REAL, "Vbs"), -OP( "vgs", BSIM3v32_VGS, IF_REAL, "Vgs"), -OP( "vds", BSIM3v32_VDS, IF_REAL, "Vds"), +OP( "gmbs", BSIM3v32_GMBS, IF_REAL, "Gmb"), +OP( "gm", BSIM3v32_GM, IF_REAL, "Gm"), +OP( "gds", BSIM3v32_GDS, IF_REAL, "Gds"), +OP( "vdsat",BSIM3v32_VDSAT, IF_REAL, "Vdsat"), +OP( "vth", BSIM3v32_VON, IF_REAL, "Vth"), +OP( "id", BSIM3v32_CD, IF_REAL, "Ids"), +OP( "vbs", BSIM3v32_VBS, IF_REAL, "Vbs"), +OP( "vgs", BSIM3v32_VGS, IF_REAL, "Vgs"), +OP( "vds", BSIM3v32_VDS, IF_REAL, "Vds"), }; IFparm BSIM3v32mPTable[] = { /* model parameters */ diff --git a/src/spicelib/devices/bsim3v32/b3v32ask.c b/src/spicelib/devices/bsim3v32/b3v32ask.c index a5e725572..c3e07f2f2 100644 --- a/src/spicelib/devices/bsim3v32/b3v32ask.c +++ b/src/spicelib/devices/bsim3v32/b3v32ask.c @@ -59,6 +59,12 @@ BSIM3v32instance *here = (BSIM3v32instance*)inst; case BSIM3v32_NQSMOD: value->iValue = here->BSIM3v32nqsMod; return(OK); + case BSIM3v32_DELVTO: + value->rValue = here->BSIM3v32delvto; + return(OK); + case BSIM3v32_MULU0: + value->rValue = here->BSIM3v32mulu0; + return(OK); case BSIM3v32_IC_VBS: value->rValue = here->BSIM3v32icVBS; return(OK); diff --git a/src/spicelib/devices/bsim3v32/b3v32check.c b/src/spicelib/devices/bsim3v32/b3v32check.c index 5280d4a43..4c89efc60 100644 --- a/src/spicelib/devices/bsim3v32/b3v32check.c +++ b/src/spicelib/devices/bsim3v32/b3v32check.c @@ -3,7 +3,7 @@ /********** * Copyright 2001 Regents of the University of California. All rights reserved. * File: b3check.c of BSIM3v3.2.4 - * Author: 1995 Min-Chie Jeng + * Author: 1995 Min-Chie Jeng * Author: 1997-1999 Weidong Liu. * Author: 2001 Xuemei Xi * Modified by Xuemei Xi, 10/05, 12/14, 2001. @@ -25,11 +25,11 @@ BSIM3v32checkModel (BSIM3v32model *model, BSIM3v32instance *here, CKTcircuit *ck struct bsim3SizeDependParam *pParam; int Fatal_Flag = 0; FILE *fplog; - - NG_IGNORE(ckt); - if ((fplog = fopen("b3v3check.log", "w")) != NULL) - { pParam = here->pParam; + NG_IGNORE(ckt); + + if ((fplog = fopen("b3v3check.log", "w")) != NULL) + { pParam = here->pParam; fprintf (fplog, "BSIM3 Model (Supports: v3.2, v3.2.2, v3.2.3, v3.2.4)\n"); @@ -51,13 +51,13 @@ FILE *fplog; printf ("You specified a wrong version number. Working now with BSIM3v3.2.4.\n"); } - if (pParam->BSIM3v32nlx < -pParam->BSIM3v32leff) + if (pParam->BSIM3v32nlx < -pParam->BSIM3v32leff) { fprintf(fplog, "Fatal: Nlx = %g is less than -Leff.\n", pParam->BSIM3v32nlx); printf("Fatal: Nlx = %g is less than -Leff.\n", pParam->BSIM3v32nlx); Fatal_Flag = 1; - } + } if (model->BSIM3v32tox <= 0.0) { fprintf(fplog, "Fatal: Tox = %g is not positive.\n", @@ -66,12 +66,12 @@ FILE *fplog; Fatal_Flag = 1; } - if (model->BSIM3v32toxm <= 0.0) - { fprintf(fplog, "Fatal: Toxm = %g is not positive.\n", - model->BSIM3v32toxm); - printf("Fatal: Toxm = %g is not positive.\n", model->BSIM3v32toxm); - Fatal_Flag = 1; - } + if (model->BSIM3v32toxm <= 0.0) + { fprintf(fplog, "Fatal: Toxm = %g is not positive.\n", + model->BSIM3v32toxm); + printf("Fatal: Toxm = %g is not positive.\n", model->BSIM3v32toxm); + Fatal_Flag = 1; + } if (pParam->BSIM3v32npeak <= 0.0) { fprintf(fplog, "Fatal: Nch = %g is not positive.\n", @@ -110,23 +110,23 @@ FILE *fplog; if (pParam->BSIM3v32dvt1 < 0.0) { fprintf(fplog, "Fatal: Dvt1 = %g is negative.\n", - pParam->BSIM3v32dvt1); - printf("Fatal: Dvt1 = %g is negative.\n", pParam->BSIM3v32dvt1); + pParam->BSIM3v32dvt1); + printf("Fatal: Dvt1 = %g is negative.\n", pParam->BSIM3v32dvt1); Fatal_Flag = 1; } - + if (pParam->BSIM3v32dvt1w < 0.0) { fprintf(fplog, "Fatal: Dvt1w = %g is negative.\n", pParam->BSIM3v32dvt1w); printf("Fatal: Dvt1w = %g is negative.\n", pParam->BSIM3v32dvt1w); Fatal_Flag = 1; } - + if (pParam->BSIM3v32w0 == -pParam->BSIM3v32weff) { 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->BSIM3v32dsub < 0.0) { fprintf(fplog, "Fatal: Dsub = %g is negative.\n", pParam->BSIM3v32dsub); @@ -137,21 +137,21 @@ FILE *fplog; { 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 (pParam->BSIM3v32u0temp <= 0.0) + } + if (pParam->BSIM3v32u0temp <= 0.0) { fprintf(fplog, "Fatal: u0 at current temperature = %g is not positive.\n", pParam->BSIM3v32u0temp); printf("Fatal: u0 at current temperature = %g is not positive.\n", pParam->BSIM3v32u0temp); Fatal_Flag = 1; - } - -/* Check delta parameter */ - if (pParam->BSIM3v32delta < 0.0) + } + +/* Check delta parameter */ + if (pParam->BSIM3v32delta < 0.0) { fprintf(fplog, "Fatal: Delta = %g is less than zero.\n", pParam->BSIM3v32delta); printf("Fatal: Delta = %g is less than zero.\n", pParam->BSIM3v32delta); Fatal_Flag = 1; - } + } if (pParam->BSIM3v32vsattemp <= 0.0) { fprintf(fplog, "Fatal: Vsat at current temperature = %g is not positive.\n", pParam->BSIM3v32vsattemp); @@ -172,178 +172,178 @@ FILE *fplog; Fatal_Flag = 1; } - if (pParam->BSIM3v32pscbe2 <= 0.0) - { fprintf(fplog, "Warning: Pscbe2 = %g is not positive.\n", - pParam->BSIM3v32pscbe2); - printf("Warning: Pscbe2 = %g is not positive.\n", pParam->BSIM3v32pscbe2); - } + if (pParam->BSIM3v32pscbe2 <= 0.0) + { fprintf(fplog, "Warning: Pscbe2 = %g is not positive.\n", + pParam->BSIM3v32pscbe2); + printf("Warning: Pscbe2 = %g is not positive.\n", pParam->BSIM3v32pscbe2); + } /* acm model */ - if (model->BSIM3v32acmMod == 0) { - if (model->BSIM3v32unitLengthSidewallJctCap > 0.0 || - model->BSIM3v32unitLengthGateSidewallJctCap > 0.0) - { - if (here->BSIM3v32drainPerimeter < pParam->BSIM3v32weff) - { fprintf(fplog, "Warning: Pd = %g is less than W.\n", - here->BSIM3v32drainPerimeter); - printf("Warning: Pd = %g is less than W.\n", - here->BSIM3v32drainPerimeter); - } - if (here->BSIM3v32sourcePerimeter < pParam->BSIM3v32weff) - { fprintf(fplog, "Warning: Ps = %g is less than W.\n", - here->BSIM3v32sourcePerimeter); - printf("Warning: Ps = %g is less than W.\n", - here->BSIM3v32sourcePerimeter); - } - } - } - - if (pParam->BSIM3v32noff < 0.1) - { fprintf(fplog, "Warning: Noff = %g is too small.\n", - pParam->BSIM3v32noff); - printf("Warning: Noff = %g is too small.\n", pParam->BSIM3v32noff); - } - if (pParam->BSIM3v32noff > 4.0) - { fprintf(fplog, "Warning: Noff = %g is too large.\n", - pParam->BSIM3v32noff); - printf("Warning: Noff = %g is too large.\n", pParam->BSIM3v32noff); - } - - if (pParam->BSIM3v32voffcv < -0.5) - { fprintf(fplog, "Warning: Voffcv = %g is too small.\n", - pParam->BSIM3v32voffcv); - printf("Warning: Voffcv = %g is too small.\n", pParam->BSIM3v32voffcv); - } - if (pParam->BSIM3v32voffcv > 0.5) - { fprintf(fplog, "Warning: Voffcv = %g is too large.\n", - pParam->BSIM3v32voffcv); - printf("Warning: Voffcv = %g is too large.\n", pParam->BSIM3v32voffcv); - } - - if (model->BSIM3v32ijth < 0.0) - { fprintf(fplog, "Fatal: Ijth = %g cannot be negative.\n", - model->BSIM3v32ijth); - printf("Fatal: Ijth = %g cannot be negative.\n", model->BSIM3v32ijth); - Fatal_Flag = 1; - } + if (model->BSIM3v32acmMod == 0) { + if (model->BSIM3v32unitLengthSidewallJctCap > 0.0 || + model->BSIM3v32unitLengthGateSidewallJctCap > 0.0) + { + if (here->BSIM3v32drainPerimeter < pParam->BSIM3v32weff) + { fprintf(fplog, "Warning: Pd = %g is less than W.\n", + here->BSIM3v32drainPerimeter); + printf("Warning: Pd = %g is less than W.\n", + here->BSIM3v32drainPerimeter); + } + if (here->BSIM3v32sourcePerimeter < pParam->BSIM3v32weff) + { fprintf(fplog, "Warning: Ps = %g is less than W.\n", + here->BSIM3v32sourcePerimeter); + printf("Warning: Ps = %g is less than W.\n", + here->BSIM3v32sourcePerimeter); + } + } + } + + if (pParam->BSIM3v32noff < 0.1) + { fprintf(fplog, "Warning: Noff = %g is too small.\n", + pParam->BSIM3v32noff); + printf("Warning: Noff = %g is too small.\n", pParam->BSIM3v32noff); + } + if (pParam->BSIM3v32noff > 4.0) + { fprintf(fplog, "Warning: Noff = %g is too large.\n", + pParam->BSIM3v32noff); + printf("Warning: Noff = %g is too large.\n", pParam->BSIM3v32noff); + } + + if (pParam->BSIM3v32voffcv < -0.5) + { fprintf(fplog, "Warning: Voffcv = %g is too small.\n", + pParam->BSIM3v32voffcv); + printf("Warning: Voffcv = %g is too small.\n", pParam->BSIM3v32voffcv); + } + if (pParam->BSIM3v32voffcv > 0.5) + { fprintf(fplog, "Warning: Voffcv = %g is too large.\n", + pParam->BSIM3v32voffcv); + printf("Warning: Voffcv = %g is too large.\n", pParam->BSIM3v32voffcv); + } + + if (model->BSIM3v32ijth < 0.0) + { fprintf(fplog, "Fatal: Ijth = %g cannot be negative.\n", + model->BSIM3v32ijth); + printf("Fatal: Ijth = %g cannot be negative.\n", model->BSIM3v32ijth); + Fatal_Flag = 1; + } /* Check capacitance parameters */ - if (pParam->BSIM3v32clc < 0.0) + if (pParam->BSIM3v32clc < 0.0) { fprintf(fplog, "Fatal: Clc = %g is negative.\n", pParam->BSIM3v32clc); printf("Fatal: Clc = %g is negative.\n", pParam->BSIM3v32clc); Fatal_Flag = 1; - } - - if (pParam->BSIM3v32moin < 5.0) - { fprintf(fplog, "Warning: Moin = %g is too small.\n", - pParam->BSIM3v32moin); - printf("Warning: Moin = %g is too small.\n", pParam->BSIM3v32moin); - } - if (pParam->BSIM3v32moin > 25.0) - { fprintf(fplog, "Warning: Moin = %g is too large.\n", - pParam->BSIM3v32moin); - printf("Warning: Moin = %g is too large.\n", pParam->BSIM3v32moin); - } + } + + if (pParam->BSIM3v32moin < 5.0) + { fprintf(fplog, "Warning: Moin = %g is too small.\n", + pParam->BSIM3v32moin); + printf("Warning: Moin = %g is too small.\n", pParam->BSIM3v32moin); + } + if (pParam->BSIM3v32moin > 25.0) + { fprintf(fplog, "Warning: Moin = %g is too large.\n", + pParam->BSIM3v32moin); + printf("Warning: Moin = %g is too large.\n", pParam->BSIM3v32moin); + } if(model->BSIM3v32capMod ==3) { - if (pParam->BSIM3v32acde < 0.4) - { fprintf(fplog, "Warning: Acde = %g is too small.\n", - pParam->BSIM3v32acde); - printf("Warning: Acde = %g is too small.\n", pParam->BSIM3v32acde); - } - if (pParam->BSIM3v32acde > 1.6) - { fprintf(fplog, "Warning: Acde = %g is too large.\n", - pParam->BSIM3v32acde); - printf("Warning: Acde = %g is too large.\n", pParam->BSIM3v32acde); - } - } - - if (model->BSIM3v32paramChk ==1) - { -/* Check L and W parameters */ + if (pParam->BSIM3v32acde < 0.4) + { fprintf(fplog, "Warning: Acde = %g is too small.\n", + pParam->BSIM3v32acde); + printf("Warning: Acde = %g is too small.\n", pParam->BSIM3v32acde); + } + if (pParam->BSIM3v32acde > 1.6) + { fprintf(fplog, "Warning: Acde = %g is too large.\n", + pParam->BSIM3v32acde); + printf("Warning: Acde = %g is too large.\n", pParam->BSIM3v32acde); + } + } + + if (model->BSIM3v32paramChk ==1) + { +/* Check L and W parameters */ if (pParam->BSIM3v32leff <= 5.0e-8) { fprintf(fplog, "Warning: Leff = %g may be too small.\n", - pParam->BSIM3v32leff); + pParam->BSIM3v32leff); printf("Warning: Leff = %g may be too small.\n", pParam->BSIM3v32leff); - } - + } + if (pParam->BSIM3v32leffCV <= 5.0e-8) { fprintf(fplog, "Warning: Leff for CV = %g may be too small.\n", pParam->BSIM3v32leffCV); printf("Warning: Leff for CV = %g may be too small.\n", pParam->BSIM3v32leffCV); - } - - if (pParam->BSIM3v32weff <= 1.0e-7) + } + + if (pParam->BSIM3v32weff <= 1.0e-7) { fprintf(fplog, "Warning: Weff = %g may be too small.\n", pParam->BSIM3v32weff); printf("Warning: Weff = %g may be too small.\n", pParam->BSIM3v32weff); - } - + } + if (pParam->BSIM3v32weffCV <= 1.0e-7) { fprintf(fplog, "Warning: Weff for CV = %g may be too small.\n", pParam->BSIM3v32weffCV); printf("Warning: Weff for CV = %g may be too small.\n", pParam->BSIM3v32weffCV); - } - + } + /* Check threshold voltage parameters */ if (pParam->BSIM3v32nlx < 0.0) { fprintf(fplog, "Warning: Nlx = %g is negative.\n", pParam->BSIM3v32nlx); printf("Warning: Nlx = %g is negative.\n", pParam->BSIM3v32nlx); - } + } if (model->BSIM3v32tox < 1.0e-9) { fprintf(fplog, "Warning: Tox = %g is less than 10A.\n", - model->BSIM3v32tox); + model->BSIM3v32tox); printf("Warning: Tox = %g is less than 10A.\n", model->BSIM3v32tox); - } + } - if (pParam->BSIM3v32npeak <= 1.0e15) + if (pParam->BSIM3v32npeak <= 1.0e15) { fprintf(fplog, "Warning: Nch = %g may be too small.\n", - pParam->BSIM3v32npeak); + pParam->BSIM3v32npeak); printf("Warning: Nch = %g may be too small.\n", - pParam->BSIM3v32npeak); + pParam->BSIM3v32npeak); } else if (pParam->BSIM3v32npeak >= 1.0e21) { fprintf(fplog, "Warning: Nch = %g may be too large.\n", - pParam->BSIM3v32npeak); + pParam->BSIM3v32npeak); printf("Warning: Nch = %g may be too large.\n", - pParam->BSIM3v32npeak); + pParam->BSIM3v32npeak); } if (pParam->BSIM3v32nsub <= 1.0e14) { fprintf(fplog, "Warning: Nsub = %g may be too small.\n", - pParam->BSIM3v32nsub); + pParam->BSIM3v32nsub); printf("Warning: Nsub = %g may be too small.\n", - pParam->BSIM3v32nsub); + pParam->BSIM3v32nsub); } else if (pParam->BSIM3v32nsub >= 1.0e21) { fprintf(fplog, "Warning: Nsub = %g may be too large.\n", - pParam->BSIM3v32nsub); + pParam->BSIM3v32nsub); printf("Warning: Nsub = %g may be too large.\n", - pParam->BSIM3v32nsub); + pParam->BSIM3v32nsub); } if ((pParam->BSIM3v32ngate > 0.0) && (pParam->BSIM3v32ngate <= 1.e18)) { fprintf(fplog, "Warning: Ngate = %g is less than 1.E18cm^-3.\n", - pParam->BSIM3v32ngate); + pParam->BSIM3v32ngate); printf("Warning: Ngate = %g is less than 1.E18cm^-3.\n", - pParam->BSIM3v32ngate); + pParam->BSIM3v32ngate); } - - if (pParam->BSIM3v32dvt0 < 0.0) + + if (pParam->BSIM3v32dvt0 < 0.0) { fprintf(fplog, "Warning: Dvt0 = %g is negative.\n", - pParam->BSIM3v32dvt0); - printf("Warning: Dvt0 = %g is negative.\n", pParam->BSIM3v32dvt0); + pParam->BSIM3v32dvt0); + printf("Warning: Dvt0 = %g is negative.\n", pParam->BSIM3v32dvt0); } - + if (fabs(1.0e-6 / (pParam->BSIM3v32w0 + pParam->BSIM3v32weff)) > 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->BSIM3v32nfactor < 0.0) @@ -364,16 +364,16 @@ FILE *fplog; /* Check DIBL parameters */ if (pParam->BSIM3v32eta0 < 0.0) { fprintf(fplog, "Warning: Eta0 = %g is negative.\n", - pParam->BSIM3v32eta0); - printf("Warning: Eta0 = %g is negative.\n", pParam->BSIM3v32eta0); + pParam->BSIM3v32eta0); + printf("Warning: Eta0 = %g is negative.\n", pParam->BSIM3v32eta0); } - -/* Check Abulk parameters */ + +/* Check Abulk parameters */ if (fabs(1.0e-6 / (pParam->BSIM3v32b1 + pParam->BSIM3v32weff)) > 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->BSIM3v32a2 < 0.01) @@ -423,29 +423,29 @@ FILE *fplog; printf("Warning: Pdibl2 = %g is negative.\n", pParam->BSIM3v32pdibl2); } /* Check overlap capacitance parameters */ - if (model->BSIM3v32cgdo < 0.0) + if (model->BSIM3v32cgdo < 0.0) { fprintf(fplog, "Warning: cgdo = %g is negative. Set to zero.\n", model->BSIM3v32cgdo); printf("Warning: cgdo = %g is negative. Set to zero.\n", model->BSIM3v32cgdo); model->BSIM3v32cgdo = 0.0; - } - if (model->BSIM3v32cgso < 0.0) + } + if (model->BSIM3v32cgso < 0.0) { fprintf(fplog, "Warning: cgso = %g is negative. Set to zero.\n", model->BSIM3v32cgso); printf("Warning: cgso = %g is negative. Set to zero.\n", model->BSIM3v32cgso); model->BSIM3v32cgso = 0.0; - } - if (model->BSIM3v32cgbo < 0.0) + } + if (model->BSIM3v32cgbo < 0.0) { fprintf(fplog, "Warning: cgbo = %g is negative. Set to zero.\n", model->BSIM3v32cgbo); printf("Warning: cgbo = %g is negative. Set to zero.\n", model->BSIM3v32cgbo); model->BSIM3v32cgbo = 0.0; - } + } - }/* loop for the parameter check for warning messages */ + }/* loop for the parameter check for warning messages */ fclose(fplog); - } - else - { fprintf(stderr, "Warning: Can't open log file. Parameter checking skipped.\n"); - } + } + else + { fprintf(stderr, "Warning: Can't open log file. Parameter checking skipped.\n"); + } - return(Fatal_Flag); + return(Fatal_Flag); } diff --git a/src/spicelib/devices/bsim3v32/b3v32ld.c b/src/spicelib/devices/bsim3v32/b3v32ld.c index b1ba23f0b..0cecad9fd 100644 --- a/src/spicelib/devices/bsim3v32/b3v32ld.c +++ b/src/spicelib/devices/bsim3v32/b3v32ld.c @@ -172,7 +172,7 @@ for (; model != NULL; model = model->BSIM3v32nextModel) ((ckt->CKTmode & (MODETRAN | MODEAC|MODEDCOP | MODEDCTRANCURVE)) || (!(ckt->CKTmode & MODEUIC)))) { vbs = 0.0; - vgs = model->BSIM3v32type * pParam->BSIM3v32vth0 + 0.1; + vgs = model->BSIM3v32type * here->BSIM3v32vth0 + 0.1; vds = 0.1; } } @@ -606,7 +606,7 @@ for (; model != NULL; model = model->BSIM3v32nextModel) dDIBL_Sft_dVd = T3 * pParam->BSIM3v32theta0vb0; DIBL_Sft = dDIBL_Sft_dVd * Vds; - Vth = model->BSIM3v32type * pParam->BSIM3v32vth0 - pParam->BSIM3v32k1 + Vth = model->BSIM3v32type * here->BSIM3v32vth0 - pParam->BSIM3v32k1 * pParam->BSIM3v32sqrtPhi + pParam->BSIM3v32k1ox * sqrtPhis - pParam->BSIM3v32k2ox * Vbseff - Delt_vth - T2 + (pParam->BSIM3v32k3 + pParam->BSIM3v32k3b * Vbseff) * tmp2 + T1 - DIBL_Sft; @@ -641,7 +641,7 @@ for (; model != NULL; model = model->BSIM3v32nextModel) } /* Poly Gate Si Depletion Effect */ - T0 = pParam->BSIM3v32vfb + pParam->BSIM3v32phi; + T0 = here->BSIM3v32vfb + pParam->BSIM3v32phi; if ((pParam->BSIM3v32ngate > 1.e18) && (pParam->BSIM3v32ngate < 1.e25) && (Vgs > T0)) /* added to avoid the problem caused by ngate */ @@ -857,7 +857,7 @@ for (; model != NULL; model = model->BSIM3v32nextModel) dDenomi_dVb *= T9; } - here->BSIM3v32ueff = ueff = pParam->BSIM3v32u0temp / Denomi; + here->BSIM3v32ueff = ueff = here->BSIM3v32u0temp / Denomi; T9 = -ueff / Denomi; dueff_dVg = T9 * dDenomi_dVg; dueff_dVd = T9 * dDenomi_dVd; @@ -1664,10 +1664,10 @@ for (; model != NULL; model = model->BSIM3v32nextModel) case BSIM3v32V324: case BSIM3v32V323: case BSIM3v32V322: - Vfb = pParam->BSIM3v32vfbzb; + Vfb = here->BSIM3v32vfbzb; break; case BSIM3v32V32: - Vfb = pParam->BSIM3v32vfbzb; + Vfb = here->BSIM3v32vfbzb; dVfb_dVb = dVfb_dVd = 0.0; break; default: @@ -1865,10 +1865,10 @@ for (; model != NULL; model = model->BSIM3v32nextModel) case BSIM3v32V324: case BSIM3v32V323: case BSIM3v32V322: - Vfb = pParam->BSIM3v32vfbzb; + Vfb = here->BSIM3v32vfbzb; break; case BSIM3v32V32: - Vfb = pParam->BSIM3v32vfbzb; + Vfb = here->BSIM3v32vfbzb; dVfb_dVb = dVfb_dVd = 0.0; break; default: /* old code prior to v3.2 */ @@ -2124,24 +2124,24 @@ for (; model != NULL; model = model->BSIM3v32nextModel) /* New Charge-Thickness capMod (CTM) begins */ else if (model->BSIM3v32capMod == 3) - { V3 = pParam->BSIM3v32vfbzb - Vgs_eff + VbseffCV - DELTA_3; - if (pParam->BSIM3v32vfbzb <= 0.0) - { T0 = sqrt(V3 * V3 - 4.0 * DELTA_3 * pParam->BSIM3v32vfbzb); + { V3 = here->BSIM3v32vfbzb - Vgs_eff + VbseffCV - DELTA_3; + if (here->BSIM3v32vfbzb <= 0.0) + { T0 = sqrt(V3 * V3 - 4.0 * DELTA_3 * here->BSIM3v32vfbzb); T2 = -DELTA_3 / T0; } else - { T0 = sqrt(V3 * V3 + 4.0 * DELTA_3 * pParam->BSIM3v32vfbzb); + { T0 = sqrt(V3 * V3 + 4.0 * DELTA_3 * here->BSIM3v32vfbzb); T2 = DELTA_3 / T0; } T1 = 0.5 * (1.0 + V3 / T0); - Vfbeff = pParam->BSIM3v32vfbzb - 0.5 * (V3 + T0); + Vfbeff = here->BSIM3v32vfbzb - 0.5 * (V3 + T0); dVfbeff_dVg = T1 * dVgs_eff_dVg; dVfbeff_dVb = -T1 * dVbseffCV_dVb; Cox = model->BSIM3v32cox; Tox = 1.0e8 * model->BSIM3v32tox; - T0 = (Vgs_eff - VbseffCV - pParam->BSIM3v32vfbzb) / Tox; + T0 = (Vgs_eff - VbseffCV - here->BSIM3v32vfbzb) / Tox; dT0_dVg = dVgs_eff_dVg / Tox; dT0_dVb = -dVbseffCV_dVb / Tox; @@ -2178,7 +2178,7 @@ for (; model != NULL; model = model->BSIM3v32nextModel) dCoxeff_dVg *= dTcen_dVg; CoxWLcen = CoxWL * Coxeff / Cox; - Qac0 = CoxWLcen * (Vfbeff - pParam->BSIM3v32vfbzb); + Qac0 = CoxWLcen * (Vfbeff - here->BSIM3v32vfbzb); QovCox = Qac0 / Coxeff; dQac0_dVg = CoxWLcen * dVfbeff_dVg + QovCox * dCoxeff_dVg; @@ -2226,7 +2226,7 @@ for (; model != NULL; model = model->BSIM3v32nextModel) dDeltaPhi_dVb = dDeltaPhi_dVg * dVgsteff_dVb; /* End of delta Phis */ - T3 = 4.0 * (Vth - pParam->BSIM3v32vfbzb - pParam->BSIM3v32phi); + T3 = 4.0 * (Vth - here->BSIM3v32vfbzb - pParam->BSIM3v32phi); Tox += Tox; if (T3 >= 0.0) { @@ -2697,9 +2697,9 @@ line755: here->BSIM3v32cqbb = -(here->BSIM3v32cqgb + here->BSIM3v32cqdb + here->BSIM3v32cqsb); - gtau_drift = fabs(pParam->BSIM3v32tconst * qcheq) * ScalingFactor; + gtau_drift = fabs(here->BSIM3v32tconst * qcheq) * ScalingFactor; T0 = pParam->BSIM3v32leffCV * pParam->BSIM3v32leffCV; - gtau_diff = 16.0 * pParam->BSIM3v32u0temp * model->BSIM3v32vtm / T0 + gtau_diff = 16.0 * here->BSIM3v32u0temp * model->BSIM3v32vtm / T0 * ScalingFactor; here->BSIM3v32gtau = gtau_drift + gtau_diff; } @@ -2836,9 +2836,9 @@ line755: } else { if (qcheq > 0.0) - T0 = pParam->BSIM3v32tconst * qdef * ScalingFactor; + T0 = here->BSIM3v32tconst * qdef * ScalingFactor; else - T0 = -pParam->BSIM3v32tconst * qdef * ScalingFactor; + T0 = -here->BSIM3v32tconst * qdef * ScalingFactor; ggtg = here->BSIM3v32gtg = T0 * here->BSIM3v32cqgb; ggtd = here->BSIM3v32gtd = T0 * here->BSIM3v32cqdb; ggts = here->BSIM3v32gts = T0 * here->BSIM3v32cqsb; @@ -2952,9 +2952,9 @@ line755: } else { if (qcheq > 0.0) - T0 = pParam->BSIM3v32tconst * qdef * ScalingFactor; + T0 = here->BSIM3v32tconst * qdef * ScalingFactor; else - T0 = -pParam->BSIM3v32tconst * qdef * ScalingFactor; + T0 = -here->BSIM3v32tconst * qdef * ScalingFactor; ggtg = here->BSIM3v32gtg = T0 * here->BSIM3v32cqgb; ggts = here->BSIM3v32gtd = T0 * here->BSIM3v32cqdb; ggtd = here->BSIM3v32gts = T0 * here->BSIM3v32cqsb; @@ -3105,7 +3105,7 @@ line850: dsxpart_dVd = dsxpart_dVg = dsxpart_dVb = dsxpart_dVs = 0.0; if (here->BSIM3v32nqsMod) - here->BSIM3v32gtau = 16.0 * pParam->BSIM3v32u0temp * model->BSIM3v32vtm + here->BSIM3v32gtau = 16.0 * here->BSIM3v32u0temp * model->BSIM3v32vtm / pParam->BSIM3v32leffCV / pParam->BSIM3v32leffCV * ScalingFactor; else diff --git a/src/spicelib/devices/bsim3v32/b3v32par.c b/src/spicelib/devices/bsim3v32/b3v32par.c index aa5a9e269..9a5a5107e 100644 --- a/src/spicelib/devices/bsim3v32/b3v32par.c +++ b/src/spicelib/devices/bsim3v32/b3v32par.c @@ -37,10 +37,10 @@ BSIM3v32param (int param, IFvalue *value, GENinstance *inst, IFvalue *select) here->BSIM3v32l = value->rValue*scale; here->BSIM3v32lGiven = TRUE; break; - case BSIM3v32_M: - here->BSIM3v32m = value->rValue; - here->BSIM3v32mGiven = TRUE; - break; + case BSIM3v32_M: + here->BSIM3v32m = value->rValue; + here->BSIM3v32mGiven = TRUE; + break; case BSIM3v32_AS: here->BSIM3v32sourceArea = value->rValue*scale*scale; here->BSIM3v32sourceAreaGiven = TRUE; @@ -84,6 +84,14 @@ BSIM3v32param (int param, IFvalue *value, GENinstance *inst, IFvalue *select) here->BSIM3v32nqsMod = value->iValue; here->BSIM3v32nqsModGiven = TRUE; break; + case BSIM3v32_DELVTO: + here->BSIM3v32delvto = value->rValue; + here->BSIM3v32delvtoGiven = TRUE; + break; + case BSIM3v32_MULU0: + here->BSIM3v32mulu0 = value->rValue; + here->BSIM3v32mulu0Given = TRUE; + break; case BSIM3v32_IC: switch(value->v.numValue){ case 3: @@ -106,5 +114,3 @@ BSIM3v32param (int param, IFvalue *value, GENinstance *inst, IFvalue *select) return(OK); } - - diff --git a/src/spicelib/devices/bsim3v32/b3v32set.c b/src/spicelib/devices/bsim3v32/b3v32set.c index 56c407c8c..902bccfc6 100644 --- a/src/spicelib/devices/bsim3v32/b3v32set.c +++ b/src/spicelib/devices/bsim3v32/b3v32set.c @@ -93,7 +93,7 @@ IFuid tmpName; model->BSIM3v32cdsc = 2.4e-4; /* unit Q/V/m^2 */ if (!model->BSIM3v32cdscbGiven) model->BSIM3v32cdscb = 0.0; /* unit Q/V/m^2 */ - if (!model->BSIM3v32cdscdGiven) + if (!model->BSIM3v32cdscdGiven) model->BSIM3v32cdscd = 0.0; /* unit Q/V/m^2 */ if (!model->BSIM3v32citGiven) model->BSIM3v32cit = 0.0; /* unit Q/V/m^2 */ @@ -185,7 +185,6 @@ IFuid tmpName; model->BSIM3v32prwg = 0.0; /* unit 1/V */ if (!model->BSIM3v32prwbGiven) model->BSIM3v32prwb = 0.0; - if (!model->BSIM3v32prtGiven) if (!model->BSIM3v32prtGiven) model->BSIM3v32prt = 0.0; if (!model->BSIM3v32eta0Given) @@ -281,7 +280,7 @@ IFuid tmpName; model->BSIM3v32lcdsc = 0.0; if (!model->BSIM3v32lcdscbGiven) model->BSIM3v32lcdscb = 0.0; - if (!model->BSIM3v32lcdscdGiven) + if (!model->BSIM3v32lcdscdGiven) model->BSIM3v32lcdscd = 0.0; if (!model->BSIM3v32lcitGiven) model->BSIM3v32lcit = 0.0; @@ -599,7 +598,7 @@ IFuid tmpName; model->BSIM3v32pcdsc = 0.0; if (!model->BSIM3v32pcdscbGiven) model->BSIM3v32pcdscb = 0.0; - if (!model->BSIM3v32pcdscdGiven) + if (!model->BSIM3v32pcdscdGiven) model->BSIM3v32pcdscd = 0.0; if (!model->BSIM3v32pcitGiven) model->BSIM3v32pcit = 0.0; @@ -916,6 +915,10 @@ IFuid tmpName; else here->BSIM3v32drainSquares = 0.0; } + if (!here->BSIM3v32delvtoGiven) + here->BSIM3v32delvto = 0.0; + if (!here->BSIM3v32mulu0Given) + here->BSIM3v32mulu0 = 1.0; if (!here->BSIM3v32icVBSGiven) here->BSIM3v32icVBS = 0.0; if (!here->BSIM3v32icVDSGiven) diff --git a/src/spicelib/devices/bsim3v32/b3v32temp.c b/src/spicelib/devices/bsim3v32/b3v32temp.c index cff3492d9..4b80733cf 100644 --- a/src/spicelib/devices/bsim3v32/b3v32temp.c +++ b/src/spicelib/devices/bsim3v32/b3v32temp.c @@ -3,7 +3,7 @@ /********** * Copyright 2001 Regents of the University of California. All rights reserved. * File: b3temp.c of BSIM3v3.2.4 - * Author: 1995 Min-Chie Jeng and Mansun Chan. + * Author: 1995 Min-Chie Jeng and Mansun Chan. * Author: 1997-1999 Weidong Liu. * Author: 2001 Xuemei Xi * Modified by Paolo Nenzi 2002 and Dietmar Warning 2003 @@ -42,7 +42,7 @@ int Size_Not_Found; /* loop through all the BSIM3v32 device models */ for (; model != NULL; model = model->BSIM3v32nextModel) { Temp = ckt->CKTtemp; - if (model->BSIM3v32bulkJctPotential < 0.1) + if (model->BSIM3v32bulkJctPotential < 0.1) { model->BSIM3v32bulkJctPotential = 0.1; fprintf(stderr, "Given pb is less than 0.1. Pb is set to 0.1.\n"); } @@ -65,7 +65,7 @@ int Size_Not_Found; Vtm0 = KboQ * Tnom; Eg0 = 1.16 - 7.02e-4 * Tnom * Tnom / (Tnom + 1108.0); - ni = 1.45e10 * (Tnom / 300.15) * sqrt(Tnom / 300.15) + ni = 1.45e10 * (Tnom / 300.15) * sqrt(Tnom / 300.15) * exp(21.5565981 - Eg0 / (2.0 * Vtm0)); model->BSIM3v32vtm = KboQ * Temp; @@ -94,7 +94,7 @@ int Size_Not_Found; delTemp = ckt->CKTtemp - model->BSIM3v32tnom; T0 = model->BSIM3v32tcj * delTemp; if (T0 >= -1.0) - { + { /* Added revision dependent code */ switch (model->BSIM3v32intVersion) { case BSIM3v32V324: @@ -109,7 +109,7 @@ int Size_Not_Found; } } else if (model->BSIM3v32unitAreaJctCap > 0.0) - { + { /* Added revision dependent code */ switch (model->BSIM3v32intVersion) { case BSIM3v32V324: @@ -125,7 +125,7 @@ int Size_Not_Found; } T0 = model->BSIM3v32tcjsw * delTemp; if (T0 >= -1.0) - { + { /* Added revision dependent code */ switch (model->BSIM3v32intVersion) { case BSIM3v32V324: @@ -140,7 +140,7 @@ int Size_Not_Found; } } else if (model->BSIM3v32unitLengthSidewallJctCap > 0.0) - { + { /* Added revision dependent code */ switch (model->BSIM3v32intVersion) { case BSIM3v32V324: @@ -156,7 +156,7 @@ int Size_Not_Found; } T0 = model->BSIM3v32tcjswg * delTemp; if (T0 >= -1.0) - { + { /* Added revision dependent code */ switch (model->BSIM3v32intVersion) { case BSIM3v32V324: @@ -171,7 +171,7 @@ int Size_Not_Found; } } else if (model->BSIM3v32unitLengthGateSidewallJctCap > 0.0) - { + { /* Added revision dependent code */ switch (model->BSIM3v32intVersion) { case BSIM3v32V324: @@ -206,11 +206,11 @@ int Size_Not_Found; } /* End of junction capacitance */ - /* loop through all the instances of the model */ + /* loop through all the instances of the model */ /* MCJ: Length and Width not initialized */ - for (here = model->BSIM3v32instances; here != NULL; - here = here->BSIM3v32nextInstance) - { + for (here = model->BSIM3v32instances; here != NULL; + here = here->BSIM3v32nextInstance) + { if (here->BSIM3v32owner != ARCHme) continue; pSizeDependParamKnot = model->pSizeDependParamKnot; Size_Not_Found = 1; @@ -243,7 +243,7 @@ int Size_Not_Found; Wdrn = here->BSIM3v32w; pParam->Length = Ldrn; pParam->Width = Wdrn; - + T0 = pow(Ldrn, model->BSIM3v32Lln); T1 = pow(Wdrn, model->BSIM3v32Lwn); tmp1 = model->BSIM3v32Ll / T0 + model->BSIM3v32Lw / T1 @@ -326,13 +326,13 @@ int Size_Not_Found; pParam->BSIM3v32cdscb = model->BSIM3v32cdscb + model->BSIM3v32lcdscb * Inv_L + model->BSIM3v32wcdscb * Inv_W - + model->BSIM3v32pcdscb * Inv_LW; - + + model->BSIM3v32pcdscb * Inv_LW; + pParam->BSIM3v32cdscd = model->BSIM3v32cdscd + model->BSIM3v32lcdscd * Inv_L + model->BSIM3v32wcdscd * Inv_W - + model->BSIM3v32pcdscd * Inv_LW; - + + model->BSIM3v32pcdscd * Inv_LW; + pParam->BSIM3v32cit = model->BSIM3v32cit + model->BSIM3v32lcit * Inv_L + model->BSIM3v32wcit * Inv_W @@ -356,13 +356,13 @@ int Size_Not_Found; pParam->BSIM3v32a0 = model->BSIM3v32a0 + model->BSIM3v32la0 * Inv_L + model->BSIM3v32wa0 * Inv_W - + model->BSIM3v32pa0 * Inv_LW; - + + model->BSIM3v32pa0 * Inv_LW; + pParam->BSIM3v32ags = model->BSIM3v32ags + model->BSIM3v32lags * Inv_L + model->BSIM3v32wags * Inv_W + model->BSIM3v32pags * Inv_LW; - + pParam->BSIM3v32a1 = model->BSIM3v32a1 + model->BSIM3v32la1 * Inv_L + model->BSIM3v32wa1 * Inv_W @@ -407,10 +407,10 @@ int Size_Not_Found; + model->BSIM3v32lxt * Inv_L + model->BSIM3v32wxt * Inv_W + model->BSIM3v32pxt * Inv_LW; - pParam->BSIM3v32vfb = model->BSIM3v32vfb - + model->BSIM3v32lvfb * Inv_L - + model->BSIM3v32wvfb * Inv_W - + model->BSIM3v32pvfb * Inv_LW; + pParam->BSIM3v32vfb = model->BSIM3v32vfb + + model->BSIM3v32lvfb * Inv_L + + model->BSIM3v32wvfb * Inv_W + + model->BSIM3v32pvfb * Inv_LW; pParam->BSIM3v32k1 = model->BSIM3v32k1 + model->BSIM3v32lk1 * Inv_L + model->BSIM3v32wk1 * Inv_W @@ -599,10 +599,10 @@ int Size_Not_Found; + model->BSIM3v32lalpha0 * Inv_L + model->BSIM3v32walpha0 * Inv_W + model->BSIM3v32palpha0 * Inv_LW; - pParam->BSIM3v32alpha1 = model->BSIM3v32alpha1 - + model->BSIM3v32lalpha1 * Inv_L - + model->BSIM3v32walpha1 * Inv_W - + model->BSIM3v32palpha1 * Inv_LW; + pParam->BSIM3v32alpha1 = model->BSIM3v32alpha1 + + model->BSIM3v32lalpha1 * Inv_L + + model->BSIM3v32walpha1 * Inv_W + + model->BSIM3v32palpha1 * Inv_LW; pParam->BSIM3v32beta0 = model->BSIM3v32beta0 + model->BSIM3v32lbeta0 * Inv_L + model->BSIM3v32wbeta0 * Inv_W @@ -640,150 +640,152 @@ int Size_Not_Found; + model->BSIM3v32lvfbcv * Inv_L + model->BSIM3v32wvfbcv * Inv_W + model->BSIM3v32pvfbcv * Inv_LW; - pParam->BSIM3v32acde = model->BSIM3v32acde - + model->BSIM3v32lacde * Inv_L - + model->BSIM3v32wacde * Inv_W - + model->BSIM3v32pacde * Inv_LW; - pParam->BSIM3v32moin = model->BSIM3v32moin - + model->BSIM3v32lmoin * Inv_L - + model->BSIM3v32wmoin * Inv_W - + model->BSIM3v32pmoin * Inv_LW; - pParam->BSIM3v32noff = model->BSIM3v32noff - + model->BSIM3v32lnoff * Inv_L - + model->BSIM3v32wnoff * Inv_W - + model->BSIM3v32pnoff * Inv_LW; - pParam->BSIM3v32voffcv = model->BSIM3v32voffcv - + model->BSIM3v32lvoffcv * Inv_L - + model->BSIM3v32wvoffcv * Inv_W - + model->BSIM3v32pvoffcv * Inv_LW; + pParam->BSIM3v32acde = model->BSIM3v32acde + + model->BSIM3v32lacde * Inv_L + + model->BSIM3v32wacde * Inv_W + + model->BSIM3v32pacde * Inv_LW; + pParam->BSIM3v32moin = model->BSIM3v32moin + + model->BSIM3v32lmoin * Inv_L + + model->BSIM3v32wmoin * Inv_W + + model->BSIM3v32pmoin * Inv_LW; + pParam->BSIM3v32noff = model->BSIM3v32noff + + model->BSIM3v32lnoff * Inv_L + + model->BSIM3v32wnoff * Inv_W + + model->BSIM3v32pnoff * Inv_LW; + pParam->BSIM3v32voffcv = model->BSIM3v32voffcv + + model->BSIM3v32lvoffcv * Inv_L + + model->BSIM3v32wvoffcv * Inv_W + + model->BSIM3v32pvoffcv * Inv_LW; - pParam->BSIM3v32abulkCVfactor = 1.0 + pow((pParam->BSIM3v32clc - / pParam->BSIM3v32leffCV), - pParam->BSIM3v32cle); + pParam->BSIM3v32abulkCVfactor = 1.0 + pow((pParam->BSIM3v32clc + / pParam->BSIM3v32leffCV), + pParam->BSIM3v32cle); - T0 = (TRatio - 1.0); - pParam->BSIM3v32ua = pParam->BSIM3v32ua + pParam->BSIM3v32ua1 * T0; - pParam->BSIM3v32ub = pParam->BSIM3v32ub + pParam->BSIM3v32ub1 * T0; - pParam->BSIM3v32uc = pParam->BSIM3v32uc + pParam->BSIM3v32uc1 * T0; - if (pParam->BSIM3v32u0 > 1.0) - pParam->BSIM3v32u0 = pParam->BSIM3v32u0 / 1.0e4; + T0 = (TRatio - 1.0); + pParam->BSIM3v32ua = pParam->BSIM3v32ua + pParam->BSIM3v32ua1 * T0; + pParam->BSIM3v32ub = pParam->BSIM3v32ub + pParam->BSIM3v32ub1 * T0; + pParam->BSIM3v32uc = pParam->BSIM3v32uc + pParam->BSIM3v32uc1 * T0; + if (pParam->BSIM3v32u0 > 1.0) + pParam->BSIM3v32u0 = pParam->BSIM3v32u0 / 1.0e4; + pParam->BSIM3v32u0 *= here->BSIM3v32mulu0; /* Low field mobility multiplier */ - pParam->BSIM3v32u0temp = pParam->BSIM3v32u0 - * pow(TRatio, pParam->BSIM3v32ute); - pParam->BSIM3v32vsattemp = pParam->BSIM3v32vsat - pParam->BSIM3v32at - * T0; - pParam->BSIM3v32rds0 = (pParam->BSIM3v32rdsw + pParam->BSIM3v32prt * T0) - / pow(pParam->BSIM3v32weff * 1E6, pParam->BSIM3v32wr); + pParam->BSIM3v32u0temp = pParam->BSIM3v32u0 + * pow(TRatio, pParam->BSIM3v32ute); + here->BSIM3v32u0temp = pParam->BSIM3v32u0temp; + pParam->BSIM3v32vsattemp = pParam->BSIM3v32vsat - pParam->BSIM3v32at + * T0; + pParam->BSIM3v32rds0 = (pParam->BSIM3v32rdsw + pParam->BSIM3v32prt * T0) + / pow(pParam->BSIM3v32weff * 1E6, pParam->BSIM3v32wr); if (BSIM3v32checkModel(model, here, ckt)) { IFuid namarray[2]; - namarray[0] = model->BSIM3v32modName; - namarray[1] = here->BSIM3v32name; - SPfrontEnd->IFerror (ERR_FATAL, "Fatal error(s) detected during BSIM3v32V3.2 parameter checking for %s in model %s", namarray); - return(E_BADPARM); + namarray[0] = model->BSIM3v32modName; + namarray[1] = here->BSIM3v32name; + SPfrontEnd->IFerror (ERR_FATAL, "Fatal error(s) detected during BSIM3v32V3.2 parameter checking for %s in model %s", namarray); + return(E_BADPARM); } - pParam->BSIM3v32cgdo = (model->BSIM3v32cgdo + pParam->BSIM3v32cf) + pParam->BSIM3v32cgdo = (model->BSIM3v32cgdo + pParam->BSIM3v32cf) * pParam->BSIM3v32weffCV; - pParam->BSIM3v32cgso = (model->BSIM3v32cgso + pParam->BSIM3v32cf) + pParam->BSIM3v32cgso = (model->BSIM3v32cgso + pParam->BSIM3v32cf) * pParam->BSIM3v32weffCV; - pParam->BSIM3v32cgbo = model->BSIM3v32cgbo * pParam->BSIM3v32leffCV; + pParam->BSIM3v32cgbo = model->BSIM3v32cgbo * pParam->BSIM3v32leffCV; - T0 = pParam->BSIM3v32leffCV * pParam->BSIM3v32leffCV; - pParam->BSIM3v32tconst = pParam->BSIM3v32u0temp * pParam->BSIM3v32elm / (model->BSIM3v32cox - * pParam->BSIM3v32weffCV * pParam->BSIM3v32leffCV * T0); + T0 = pParam->BSIM3v32leffCV * pParam->BSIM3v32leffCV; + here->BSIM3v32tconst = here->BSIM3v32u0temp * pParam->BSIM3v32elm / (model->BSIM3v32cox + * pParam->BSIM3v32weffCV * pParam->BSIM3v32leffCV * T0); - if (!model->BSIM3v32npeakGiven && model->BSIM3v32gamma1Given) - { T0 = pParam->BSIM3v32gamma1 * model->BSIM3v32cox; - pParam->BSIM3v32npeak = 3.021E22 * T0 * T0; - } + if (!model->BSIM3v32npeakGiven && model->BSIM3v32gamma1Given) + { T0 = pParam->BSIM3v32gamma1 * model->BSIM3v32cox; + pParam->BSIM3v32npeak = 3.021E22 * T0 * T0; + } - pParam->BSIM3v32phi = 2.0 * Vtm0 - * log(pParam->BSIM3v32npeak / ni); + pParam->BSIM3v32phi = 2.0 * Vtm0 + * log(pParam->BSIM3v32npeak / ni); - pParam->BSIM3v32sqrtPhi = sqrt(pParam->BSIM3v32phi); - pParam->BSIM3v32phis3 = pParam->BSIM3v32sqrtPhi * pParam->BSIM3v32phi; + pParam->BSIM3v32sqrtPhi = sqrt(pParam->BSIM3v32phi); + pParam->BSIM3v32phis3 = pParam->BSIM3v32sqrtPhi * pParam->BSIM3v32phi; - pParam->BSIM3v32Xdep0 = sqrt(2.0 * EPSSI / (Charge_q + pParam->BSIM3v32Xdep0 = sqrt(2.0 * EPSSI / (Charge_q * pParam->BSIM3v32npeak * 1.0e6)) - * pParam->BSIM3v32sqrtPhi; - pParam->BSIM3v32sqrtXdep0 = sqrt(pParam->BSIM3v32Xdep0); - pParam->BSIM3v32litl = sqrt(3.0 * pParam->BSIM3v32xj + * pParam->BSIM3v32sqrtPhi; + pParam->BSIM3v32sqrtXdep0 = sqrt(pParam->BSIM3v32Xdep0); + pParam->BSIM3v32litl = sqrt(3.0 * pParam->BSIM3v32xj * model->BSIM3v32tox); - pParam->BSIM3v32vbi = Vtm0 * log(1.0e20 - * pParam->BSIM3v32npeak / (ni * ni)); - pParam->BSIM3v32cdep0 = sqrt(Charge_q * EPSSI + pParam->BSIM3v32vbi = Vtm0 * log(1.0e20 + * pParam->BSIM3v32npeak / (ni * ni)); + pParam->BSIM3v32cdep0 = sqrt(Charge_q * EPSSI * pParam->BSIM3v32npeak * 1.0e6 / 2.0 / pParam->BSIM3v32phi); - pParam->BSIM3v32ldeb = sqrt(EPSSI * Vtm0 / (Charge_q - * pParam->BSIM3v32npeak * 1.0e6)) / 3.0; - pParam->BSIM3v32acde *= pow((pParam->BSIM3v32npeak / 2.0e16), -0.25); + pParam->BSIM3v32ldeb = sqrt(EPSSI * Vtm0 / (Charge_q + * pParam->BSIM3v32npeak * 1.0e6)) / 3.0; + pParam->BSIM3v32acde *= pow((pParam->BSIM3v32npeak / 2.0e16), -0.25); - if (model->BSIM3v32k1Given || model->BSIM3v32k2Given) - { if (!model->BSIM3v32k1Given) - { - if ((!ckt->CKTcurJob) || (ckt->CKTcurJob->JOBtype < 9)) /* don't print in sensitivity */ - fprintf(stdout, "Warning: k1 should be specified with k2.\n"); - pParam->BSIM3v32k1 = 0.53; - } - if (!model->BSIM3v32k2Given) - { - if ((!ckt->CKTcurJob) || (ckt->CKTcurJob->JOBtype < 9)) /* don't print in sensitivity */ - fprintf(stdout, "Warning: k2 should be specified with k1.\n"); - pParam->BSIM3v32k2 = -0.0186; - } - if ((!ckt->CKTcurJob) || (ckt->CKTcurJob->JOBtype < 9)) { /* don't print in sensitivity */ - if (model->BSIM3v32nsubGiven) - fprintf(stdout, "Warning: nsub is ignored because k1 or k2 is given.\n"); - if (model->BSIM3v32xtGiven) - fprintf(stdout, "Warning: xt is ignored because k1 or k2 is given.\n"); - if (model->BSIM3v32vbxGiven) - fprintf(stdout, "Warning: vbx is ignored because k1 or k2 is given.\n"); - if (model->BSIM3v32gamma1Given) - fprintf(stdout, "Warning: gamma1 is ignored because k1 or k2 is given.\n"); - if (model->BSIM3v32gamma2Given) - fprintf(stdout, "Warning: gamma2 is ignored because k1 or k2 is given.\n"); - } - } - else - { if (!model->BSIM3v32vbxGiven) - pParam->BSIM3v32vbx = pParam->BSIM3v32phi - 7.7348e-4 - * pParam->BSIM3v32npeak + if (model->BSIM3v32k1Given || model->BSIM3v32k2Given) + { if (!model->BSIM3v32k1Given) + { + if ((!ckt->CKTcurJob) || (ckt->CKTcurJob->JOBtype < 9)) /* don't print in sensitivity */ + fprintf(stdout, "Warning: k1 should be specified with k2.\n"); + pParam->BSIM3v32k1 = 0.53; + } + if (!model->BSIM3v32k2Given) + { + if ((!ckt->CKTcurJob) || (ckt->CKTcurJob->JOBtype < 9)) /* don't print in sensitivity */ + fprintf(stdout, "Warning: k2 should be specified with k1.\n"); + pParam->BSIM3v32k2 = -0.0186; + } + if ((!ckt->CKTcurJob) || (ckt->CKTcurJob->JOBtype < 9)) { /* don't print in sensitivity */ + if (model->BSIM3v32nsubGiven) + fprintf(stdout, "Warning: nsub is ignored because k1 or k2 is given.\n"); + if (model->BSIM3v32xtGiven) + fprintf(stdout, "Warning: xt is ignored because k1 or k2 is given.\n"); + if (model->BSIM3v32vbxGiven) + fprintf(stdout, "Warning: vbx is ignored because k1 or k2 is given.\n"); + if (model->BSIM3v32gamma1Given) + fprintf(stdout, "Warning: gamma1 is ignored because k1 or k2 is given.\n"); + if (model->BSIM3v32gamma2Given) + fprintf(stdout, "Warning: gamma2 is ignored because k1 or k2 is given.\n"); + } + } + else + { if (!model->BSIM3v32vbxGiven) + pParam->BSIM3v32vbx = pParam->BSIM3v32phi - 7.7348e-4 + * pParam->BSIM3v32npeak * pParam->BSIM3v32xt * pParam->BSIM3v32xt; - if (pParam->BSIM3v32vbx > 0.0) - pParam->BSIM3v32vbx = -pParam->BSIM3v32vbx; - if (pParam->BSIM3v32vbm > 0.0) - pParam->BSIM3v32vbm = -pParam->BSIM3v32vbm; - - if (!model->BSIM3v32gamma1Given) - pParam->BSIM3v32gamma1 = 5.753e-12 + if (pParam->BSIM3v32vbx > 0.0) + pParam->BSIM3v32vbx = -pParam->BSIM3v32vbx; + if (pParam->BSIM3v32vbm > 0.0) + pParam->BSIM3v32vbm = -pParam->BSIM3v32vbm; + + if (!model->BSIM3v32gamma1Given) + pParam->BSIM3v32gamma1 = 5.753e-12 * sqrt(pParam->BSIM3v32npeak) - / model->BSIM3v32cox; - if (!model->BSIM3v32gamma2Given) - pParam->BSIM3v32gamma2 = 5.753e-12 + / model->BSIM3v32cox; + if (!model->BSIM3v32gamma2Given) + pParam->BSIM3v32gamma2 = 5.753e-12 * sqrt(pParam->BSIM3v32nsub) - / model->BSIM3v32cox; + / model->BSIM3v32cox; - T0 = pParam->BSIM3v32gamma1 - pParam->BSIM3v32gamma2; - T1 = sqrt(pParam->BSIM3v32phi - pParam->BSIM3v32vbx) + T0 = pParam->BSIM3v32gamma1 - pParam->BSIM3v32gamma2; + T1 = sqrt(pParam->BSIM3v32phi - pParam->BSIM3v32vbx) - pParam->BSIM3v32sqrtPhi; - T2 = sqrt(pParam->BSIM3v32phi * (pParam->BSIM3v32phi + T2 = sqrt(pParam->BSIM3v32phi * (pParam->BSIM3v32phi - pParam->BSIM3v32vbm)) - pParam->BSIM3v32phi; - pParam->BSIM3v32k2 = T0 * T1 / (2.0 * T2 + pParam->BSIM3v32vbm); - pParam->BSIM3v32k1 = pParam->BSIM3v32gamma2 - 2.0 + pParam->BSIM3v32k2 = T0 * T1 / (2.0 * T2 + pParam->BSIM3v32vbm); + pParam->BSIM3v32k1 = pParam->BSIM3v32gamma2 - 2.0 * pParam->BSIM3v32k2 * sqrt(pParam->BSIM3v32phi - pParam->BSIM3v32vbm); - } - + } + if (pParam->BSIM3v32k2 < 0.0) { T0 = 0.5 * pParam->BSIM3v32k1 / pParam->BSIM3v32k2; - pParam->BSIM3v32vbsc = 0.9 * (pParam->BSIM3v32phi - T0 * T0); + pParam->BSIM3v32vbsc = 0.9 * (pParam->BSIM3v32phi - T0 * T0); if (pParam->BSIM3v32vbsc > -3.0) - pParam->BSIM3v32vbsc = -3.0; + pParam->BSIM3v32vbsc = -3.0; else if (pParam->BSIM3v32vbsc < -30.0) - pParam->BSIM3v32vbsc = -30.0; + pParam->BSIM3v32vbsc = -30.0; } else { pParam->BSIM3v32vbsc = -30.0; @@ -791,249 +793,254 @@ int Size_Not_Found; if (pParam->BSIM3v32vbsc > pParam->BSIM3v32vbm) pParam->BSIM3v32vbsc = pParam->BSIM3v32vbm; - if (!model->BSIM3v32vfbGiven) - { if (model->BSIM3v32vth0Given) - { pParam->BSIM3v32vfb = model->BSIM3v32type * pParam->BSIM3v32vth0 - - pParam->BSIM3v32phi - pParam->BSIM3v32k1 - * pParam->BSIM3v32sqrtPhi; - } - else - { pParam->BSIM3v32vfb = -1.0; - } - } - if (!model->BSIM3v32vth0Given) - { pParam->BSIM3v32vth0 = model->BSIM3v32type * (pParam->BSIM3v32vfb - + pParam->BSIM3v32phi + pParam->BSIM3v32k1 - * pParam->BSIM3v32sqrtPhi); - } + if (!model->BSIM3v32vfbGiven) + { if (model->BSIM3v32vth0Given) + { pParam->BSIM3v32vfb = model->BSIM3v32type * pParam->BSIM3v32vth0 + - pParam->BSIM3v32phi - pParam->BSIM3v32k1 + * pParam->BSIM3v32sqrtPhi; + } + else + { pParam->BSIM3v32vfb = -1.0; + } + } + if (!model->BSIM3v32vth0Given) + { pParam->BSIM3v32vth0 = model->BSIM3v32type * (pParam->BSIM3v32vfb + + pParam->BSIM3v32phi + pParam->BSIM3v32k1 + * pParam->BSIM3v32sqrtPhi); + } - pParam->BSIM3v32k1ox = pParam->BSIM3v32k1 * model->BSIM3v32tox - / model->BSIM3v32toxm; - pParam->BSIM3v32k2ox = pParam->BSIM3v32k2 * model->BSIM3v32tox - / model->BSIM3v32toxm; + pParam->BSIM3v32k1ox = pParam->BSIM3v32k1 * model->BSIM3v32tox + / model->BSIM3v32toxm; + pParam->BSIM3v32k2ox = pParam->BSIM3v32k2 * model->BSIM3v32tox + / model->BSIM3v32toxm; - T1 = sqrt(EPSSI / EPSOX * model->BSIM3v32tox + T1 = sqrt(EPSSI / EPSOX * model->BSIM3v32tox * pParam->BSIM3v32Xdep0); - T0 = exp(-0.5 * pParam->BSIM3v32dsub * pParam->BSIM3v32leff / T1); - pParam->BSIM3v32theta0vb0 = (T0 + 2.0 * T0 * T0); + T0 = exp(-0.5 * pParam->BSIM3v32dsub * pParam->BSIM3v32leff / T1); + pParam->BSIM3v32theta0vb0 = (T0 + 2.0 * T0 * T0); - T0 = exp(-0.5 * pParam->BSIM3v32drout * pParam->BSIM3v32leff / T1); - T2 = (T0 + 2.0 * T0 * T0); - pParam->BSIM3v32thetaRout = pParam->BSIM3v32pdibl1 * T2 - + pParam->BSIM3v32pdibl2; + T0 = exp(-0.5 * pParam->BSIM3v32drout * pParam->BSIM3v32leff / T1); + T2 = (T0 + 2.0 * T0 * T0); + pParam->BSIM3v32thetaRout = pParam->BSIM3v32pdibl1 * T2 + + pParam->BSIM3v32pdibl2; - tmp = sqrt(pParam->BSIM3v32Xdep0); - tmp1 = pParam->BSIM3v32vbi - pParam->BSIM3v32phi; - tmp2 = model->BSIM3v32factor1 * tmp; + tmp = sqrt(pParam->BSIM3v32Xdep0); + tmp1 = pParam->BSIM3v32vbi - pParam->BSIM3v32phi; + tmp2 = model->BSIM3v32factor1 * tmp; - T0 = -0.5 * pParam->BSIM3v32dvt1w * pParam->BSIM3v32weff - * pParam->BSIM3v32leff / tmp2; - if (T0 > -EXP_THRESHOLD) - { T1 = exp(T0); - T2 = T1 * (1.0 + 2.0 * T1); - } - else - { T1 = MIN_EXP; - T2 = T1 * (1.0 + 2.0 * T1); - } - T0 = pParam->BSIM3v32dvt0w * T2; - T2 = T0 * tmp1; + T0 = -0.5 * pParam->BSIM3v32dvt1w * pParam->BSIM3v32weff + * pParam->BSIM3v32leff / tmp2; + if (T0 > -EXP_THRESHOLD) + { T1 = exp(T0); + T2 = T1 * (1.0 + 2.0 * T1); + } + else + { T1 = MIN_EXP; + T2 = T1 * (1.0 + 2.0 * T1); + } + T0 = pParam->BSIM3v32dvt0w * T2; + T2 = T0 * tmp1; - T0 = -0.5 * pParam->BSIM3v32dvt1 * pParam->BSIM3v32leff / tmp2; - if (T0 > -EXP_THRESHOLD) - { T1 = exp(T0); - T3 = T1 * (1.0 + 2.0 * T1); - } - else - { T1 = MIN_EXP; - T3 = T1 * (1.0 + 2.0 * T1); - } - T3 = pParam->BSIM3v32dvt0 * T3 * tmp1; + T0 = -0.5 * pParam->BSIM3v32dvt1 * pParam->BSIM3v32leff / tmp2; + if (T0 > -EXP_THRESHOLD) + { T1 = exp(T0); + T3 = T1 * (1.0 + 2.0 * T1); + } + else + { T1 = MIN_EXP; + T3 = T1 * (1.0 + 2.0 * T1); + } + T3 = pParam->BSIM3v32dvt0 * T3 * tmp1; - T4 = model->BSIM3v32tox * pParam->BSIM3v32phi - / (pParam->BSIM3v32weff + pParam->BSIM3v32w0); + T4 = model->BSIM3v32tox * pParam->BSIM3v32phi + / (pParam->BSIM3v32weff + pParam->BSIM3v32w0); - T0 = sqrt(1.0 + pParam->BSIM3v32nlx / pParam->BSIM3v32leff); - T5 = pParam->BSIM3v32k1ox * (T0 - 1.0) * pParam->BSIM3v32sqrtPhi - + (pParam->BSIM3v32kt1 + pParam->BSIM3v32kt1l / pParam->BSIM3v32leff) - * (TRatio - 1.0); + T0 = sqrt(1.0 + pParam->BSIM3v32nlx / pParam->BSIM3v32leff); + T5 = pParam->BSIM3v32k1ox * (T0 - 1.0) * pParam->BSIM3v32sqrtPhi + + (pParam->BSIM3v32kt1 + pParam->BSIM3v32kt1l / pParam->BSIM3v32leff) + * (TRatio - 1.0); - tmp3 = model->BSIM3v32type * pParam->BSIM3v32vth0 - - T2 - T3 + pParam->BSIM3v32k3 * T4 + T5; - pParam->BSIM3v32vfbzb = tmp3 - pParam->BSIM3v32phi - pParam->BSIM3v32k1 - * pParam->BSIM3v32sqrtPhi; - /* End of vfbzb */ - } + tmp3 = model->BSIM3v32type * pParam->BSIM3v32vth0 + - T2 - T3 + pParam->BSIM3v32k3 * T4 + T5; + pParam->BSIM3v32vfbzb = tmp3 - pParam->BSIM3v32phi - pParam->BSIM3v32k1 + * pParam->BSIM3v32sqrtPhi; + /* End of vfbzb */ + } - /* process source/drain series resistance */ - /* acm model */ - if (model->BSIM3v32acmMod == 0) - { - here->BSIM3v32drainConductance = model->BSIM3v32sheetResistance - * here->BSIM3v32drainSquares; - here->BSIM3v32sourceConductance = model->BSIM3v32sheetResistance - * here->BSIM3v32sourceSquares; - } - else - { - if (here->BSIM3v32drainSquaresGiven) - { - here->BSIM3v32drainConductance = (model->BSIM3v32ld + model->BSIM3v32ldif)/(here->BSIM3v32w + model->BSIM3v32xw)*model->BSIM3v32rd - + model->BSIM3v32sheetResistance * here->BSIM3v32drainSquares + model->BSIM3v32rdc; - } - else - { - here->BSIM3v32drainConductance = ((model->BSIM3v32ld + model->BSIM3v32ldif)*model->BSIM3v32rd - + model->BSIM3v32hdif*model->BSIM3v32sheetResistance)/(here->BSIM3v32w + model->BSIM3v32xw) + model->BSIM3v32rdc; - } - if (here->BSIM3v32sourceSquaresGiven) - { - here->BSIM3v32sourceConductance = (model->BSIM3v32ld + model->BSIM3v32ldif)/(here->BSIM3v32w + model->BSIM3v32xw)*model->BSIM3v32rs - + model->BSIM3v32sheetResistance * here->BSIM3v32sourceSquares + model->BSIM3v32rsc; - } - else - { - here->BSIM3v32sourceConductance = ((model->BSIM3v32ld + model->BSIM3v32ldif)*model->BSIM3v32rs - + model->BSIM3v32hdif*model->BSIM3v32sheetResistance)/(here->BSIM3v32w + model->BSIM3v32xw) + model->BSIM3v32rsc; - } - } - if (here->BSIM3v32drainConductance > 0.0) - here->BSIM3v32drainConductance = 1.0 - / here->BSIM3v32drainConductance; + /* adding delvto */ + here->BSIM3v32vth0 = pParam->BSIM3v32vth0 + here->BSIM3v32delvto; + here->BSIM3v32vfb = pParam->BSIM3v32vfb + model->BSIM3v32type * here->BSIM3v32delvto; + here->BSIM3v32vfbzb = pParam->BSIM3v32vfbzb + model->BSIM3v32type * here->BSIM3v32delvto; + + /* process source/drain series resistance */ + /* acm model */ + if (model->BSIM3v32acmMod == 0) + { + here->BSIM3v32drainConductance = model->BSIM3v32sheetResistance + * here->BSIM3v32drainSquares; + here->BSIM3v32sourceConductance = model->BSIM3v32sheetResistance + * here->BSIM3v32sourceSquares; + } else - here->BSIM3v32drainConductance = 0.0; + { + if (here->BSIM3v32drainSquaresGiven) + { + here->BSIM3v32drainConductance = (model->BSIM3v32ld + model->BSIM3v32ldif)/(here->BSIM3v32w + model->BSIM3v32xw)*model->BSIM3v32rd + + model->BSIM3v32sheetResistance * here->BSIM3v32drainSquares + model->BSIM3v32rdc; + } + else + { + here->BSIM3v32drainConductance = ((model->BSIM3v32ld + model->BSIM3v32ldif)*model->BSIM3v32rd + + model->BSIM3v32hdif*model->BSIM3v32sheetResistance)/(here->BSIM3v32w + model->BSIM3v32xw) + model->BSIM3v32rdc; + } + if (here->BSIM3v32sourceSquaresGiven) + { + here->BSIM3v32sourceConductance = (model->BSIM3v32ld + model->BSIM3v32ldif)/(here->BSIM3v32w + model->BSIM3v32xw)*model->BSIM3v32rs + + model->BSIM3v32sheetResistance * here->BSIM3v32sourceSquares + model->BSIM3v32rsc; + } + else + { + here->BSIM3v32sourceConductance = ((model->BSIM3v32ld + model->BSIM3v32ldif)*model->BSIM3v32rs + + model->BSIM3v32hdif*model->BSIM3v32sheetResistance)/(here->BSIM3v32w + model->BSIM3v32xw) + model->BSIM3v32rsc; + } + } + if (here->BSIM3v32drainConductance > 0.0) + here->BSIM3v32drainConductance = 1.0 + / here->BSIM3v32drainConductance; + else + here->BSIM3v32drainConductance = 0.0; - if (here->BSIM3v32sourceConductance > 0.0) - here->BSIM3v32sourceConductance = 1.0 + if (here->BSIM3v32sourceConductance > 0.0) + here->BSIM3v32sourceConductance = 1.0 / here->BSIM3v32sourceConductance; else - here->BSIM3v32sourceConductance = 0.0; + here->BSIM3v32sourceConductance = 0.0; here->BSIM3v32cgso = pParam->BSIM3v32cgso; here->BSIM3v32cgdo = pParam->BSIM3v32cgdo; - Nvtm = model->BSIM3v32vtm * model->BSIM3v32jctEmissionCoeff; - if (model->BSIM3v32acmMod == 0) - { - if ((here->BSIM3v32sourceArea <= 0.0) && - (here->BSIM3v32sourcePerimeter <= 0.0)) - { SourceSatCurrent = 1.0e-14; - } - else - { SourceSatCurrent = here->BSIM3v32sourceArea - * model->BSIM3v32jctTempSatCurDensity - + here->BSIM3v32sourcePerimeter - * model->BSIM3v32jctSidewallTempSatCurDensity; - } - if ((SourceSatCurrent > 0.0) && (model->BSIM3v32ijth > 0.0)) - { here->BSIM3v32vjsm = Nvtm * log(model->BSIM3v32ijth - / SourceSatCurrent + 1.0); - /* Added revision dependent code */ - switch (model->BSIM3v32intVersion) { - case BSIM3v32V324: - case BSIM3v32V323: - case BSIM3v32V322: - here->BSIM3v32IsEvjsm = - SourceSatCurrent * exp(here->BSIM3v32vjsm / Nvtm); - break; - case BSIM3v32V32: - default: - /* Do nothing */ - break; - } - } - - if ((here->BSIM3v32drainArea <= 0.0) && - (here->BSIM3v32drainPerimeter <= 0.0)) - { DrainSatCurrent = 1.0e-14; - } - else - { DrainSatCurrent = here->BSIM3v32drainArea - * model->BSIM3v32jctTempSatCurDensity - + here->BSIM3v32drainPerimeter - * model->BSIM3v32jctSidewallTempSatCurDensity; - } - if ((DrainSatCurrent > 0.0) && (model->BSIM3v32ijth > 0.0)) - { here->BSIM3v32vjdm = Nvtm * log(model->BSIM3v32ijth - / DrainSatCurrent + 1.0); - /* Added revision dependent code */ - switch (model->BSIM3v32intVersion) { - case BSIM3v32V324: - case BSIM3v32V323: - case BSIM3v32V322: - here->BSIM3v32IsEvjdm = - DrainSatCurrent * exp(here->BSIM3v32vjdm / Nvtm); - break; - case BSIM3v32V32: - default: - /* Do nothing */ - break; - } - } - } - else - { - SourceSatCurrent = 0.0; - if (!here->BSIM3v32sourceAreaGiven) - { - here->BSIM3v32sourceArea = 2.0 * model->BSIM3v32hdif * pParam->BSIM3v32weff; - } - SourceSatCurrent = here->BSIM3v32sourceArea * model->BSIM3v32jctTempSatCurDensity; - if (!here->BSIM3v32sourcePerimeterGiven) - { - here->BSIM3v32sourcePerimeter = 4.0 * model->BSIM3v32hdif + 2.0 * pParam->BSIM3v32weff; - } - SourceSatCurrent = SourceSatCurrent + here->BSIM3v32sourcePerimeter * model->BSIM3v32jctSidewallTempSatCurDensity; - if (SourceSatCurrent <= 0.0) SourceSatCurrent = 1.0e-14; - if ((SourceSatCurrent > 0.0) && (model->BSIM3v32ijth > 0.0)) - { here->BSIM3v32vjsm = Nvtm * log(model->BSIM3v32ijth - / SourceSatCurrent + 1.0); - /* Added revision dependent code */ - switch (model->BSIM3v32intVersion) { - case BSIM3v32V324: - case BSIM3v32V323: - case BSIM3v32V322: - here->BSIM3v32IsEvjsm = - SourceSatCurrent * exp(here->BSIM3v32vjsm / Nvtm); - break; - case BSIM3v32V32: - default: - /* Do nothing */ - break; - } - } + Nvtm = model->BSIM3v32vtm * model->BSIM3v32jctEmissionCoeff; + if (model->BSIM3v32acmMod == 0) + { + if ((here->BSIM3v32sourceArea <= 0.0) && + (here->BSIM3v32sourcePerimeter <= 0.0)) + { SourceSatCurrent = 1.0e-14; + } + else + { SourceSatCurrent = here->BSIM3v32sourceArea + * model->BSIM3v32jctTempSatCurDensity + + here->BSIM3v32sourcePerimeter + * model->BSIM3v32jctSidewallTempSatCurDensity; + } + if ((SourceSatCurrent > 0.0) && (model->BSIM3v32ijth > 0.0)) + { here->BSIM3v32vjsm = Nvtm * log(model->BSIM3v32ijth + / SourceSatCurrent + 1.0); + /* Added revision dependent code */ + switch (model->BSIM3v32intVersion) { + case BSIM3v32V324: + case BSIM3v32V323: + case BSIM3v32V322: + here->BSIM3v32IsEvjsm = + SourceSatCurrent * exp(here->BSIM3v32vjsm / Nvtm); + break; + case BSIM3v32V32: + default: + /* Do nothing */ + break; + } + } - DrainSatCurrent = 0.0; - if (!here->BSIM3v32drainAreaGiven) - { - here->BSIM3v32drainArea = 2.0 * model->BSIM3v32hdif * pParam->BSIM3v32weff; - } - DrainSatCurrent = here->BSIM3v32drainArea * model->BSIM3v32jctTempSatCurDensity; - if (!here->BSIM3v32drainPerimeterGiven) - { - here->BSIM3v32drainPerimeter = 4.0 * model->BSIM3v32hdif + 2.0 * pParam->BSIM3v32weff; - } - DrainSatCurrent = DrainSatCurrent + here->BSIM3v32drainPerimeter * model->BSIM3v32jctSidewallTempSatCurDensity; - if (DrainSatCurrent <= 0.0) DrainSatCurrent = 1.0e-14; - if ((DrainSatCurrent > 0.0) && (model->BSIM3v32ijth > 0.0)) - { here->BSIM3v32vjdm = Nvtm * log(model->BSIM3v32ijth - / DrainSatCurrent + 1.0); - /* Added revision dependent code */ - switch (model->BSIM3v32intVersion) { - case BSIM3v32V324: - case BSIM3v32V323: - case BSIM3v32V322: - here->BSIM3v32IsEvjdm = - DrainSatCurrent * exp(here->BSIM3v32vjdm / Nvtm); - break; - case BSIM3v32V32: - default: - /* Do nothing */ - break; - } - } - } - } + if ((here->BSIM3v32drainArea <= 0.0) && + (here->BSIM3v32drainPerimeter <= 0.0)) + { DrainSatCurrent = 1.0e-14; + } + else + { DrainSatCurrent = here->BSIM3v32drainArea + * model->BSIM3v32jctTempSatCurDensity + + here->BSIM3v32drainPerimeter + * model->BSIM3v32jctSidewallTempSatCurDensity; + } + if ((DrainSatCurrent > 0.0) && (model->BSIM3v32ijth > 0.0)) + { here->BSIM3v32vjdm = Nvtm * log(model->BSIM3v32ijth + / DrainSatCurrent + 1.0); + /* Added revision dependent code */ + switch (model->BSIM3v32intVersion) { + case BSIM3v32V324: + case BSIM3v32V323: + case BSIM3v32V322: + here->BSIM3v32IsEvjdm = + DrainSatCurrent * exp(here->BSIM3v32vjdm / Nvtm); + break; + case BSIM3v32V32: + default: + /* Do nothing */ + break; + } + } + } + else + { + SourceSatCurrent = 0.0; + if (!here->BSIM3v32sourceAreaGiven) + { + here->BSIM3v32sourceArea = 2.0 * model->BSIM3v32hdif * pParam->BSIM3v32weff; + } + SourceSatCurrent = here->BSIM3v32sourceArea * model->BSIM3v32jctTempSatCurDensity; + if (!here->BSIM3v32sourcePerimeterGiven) + { + here->BSIM3v32sourcePerimeter = 4.0 * model->BSIM3v32hdif + 2.0 * pParam->BSIM3v32weff; + } + SourceSatCurrent = SourceSatCurrent + here->BSIM3v32sourcePerimeter * model->BSIM3v32jctSidewallTempSatCurDensity; + if (SourceSatCurrent <= 0.0) SourceSatCurrent = 1.0e-14; + if ((SourceSatCurrent > 0.0) && (model->BSIM3v32ijth > 0.0)) + { here->BSIM3v32vjsm = Nvtm * log(model->BSIM3v32ijth + / SourceSatCurrent + 1.0); + /* Added revision dependent code */ + switch (model->BSIM3v32intVersion) { + case BSIM3v32V324: + case BSIM3v32V323: + case BSIM3v32V322: + here->BSIM3v32IsEvjsm = + SourceSatCurrent * exp(here->BSIM3v32vjsm / Nvtm); + break; + case BSIM3v32V32: + default: + /* Do nothing */ + break; + } + } + + DrainSatCurrent = 0.0; + if (!here->BSIM3v32drainAreaGiven) + { + here->BSIM3v32drainArea = 2.0 * model->BSIM3v32hdif * pParam->BSIM3v32weff; + } + DrainSatCurrent = here->BSIM3v32drainArea * model->BSIM3v32jctTempSatCurDensity; + if (!here->BSIM3v32drainPerimeterGiven) + { + here->BSIM3v32drainPerimeter = 4.0 * model->BSIM3v32hdif + 2.0 * pParam->BSIM3v32weff; + } + DrainSatCurrent = DrainSatCurrent + here->BSIM3v32drainPerimeter * model->BSIM3v32jctSidewallTempSatCurDensity; + if (DrainSatCurrent <= 0.0) DrainSatCurrent = 1.0e-14; + if ((DrainSatCurrent > 0.0) && (model->BSIM3v32ijth > 0.0)) + { here->BSIM3v32vjdm = Nvtm * log(model->BSIM3v32ijth + / DrainSatCurrent + 1.0); + /* Added revision dependent code */ + switch (model->BSIM3v32intVersion) { + case BSIM3v32V324: + case BSIM3v32V323: + case BSIM3v32V322: + here->BSIM3v32IsEvjdm = + DrainSatCurrent * exp(here->BSIM3v32vjdm / Nvtm); + break; + case BSIM3v32V32: + default: + /* Do nothing */ + break; + } + } + } + } } return(OK); } diff --git a/src/spicelib/devices/bsim3v32/bsim3v32def.h b/src/spicelib/devices/bsim3v32/bsim3v32def.h index bb4aceaab..006cc2b09 100644 --- a/src/spicelib/devices/bsim3v32/bsim3v32def.h +++ b/src/spicelib/devices/bsim3v32/bsim3v32def.h @@ -54,6 +54,13 @@ typedef struct sBSIM3v32instance double BSIM3v32sourcePerimeter; double BSIM3v32sourceConductance; double BSIM3v32drainConductance; + double BSIM3v32delvto; + double BSIM3v32mulu0; + double BSIM3v32vth0; + double BSIM3v32vfb; + double BSIM3v32vfbzb; + double BSIM3v32u0temp; + double BSIM3v32tconst; double BSIM3v32icVBS; double BSIM3v32icVDS; @@ -121,6 +128,8 @@ typedef struct sBSIM3v32instance unsigned BSIM3v32sourceSquaresGiven :1; unsigned BSIM3v32drainPerimeterGiven :1; unsigned BSIM3v32sourcePerimeterGiven :1; + unsigned BSIM3v32delvtoGiven :1; + unsigned BSIM3v32mulu0Given :1; unsigned BSIM3v32dNodePrimeSet :1; unsigned BSIM3v32sNodePrimeSet :1; unsigned BSIM3v32icVBSGiven :1; @@ -1259,7 +1268,6 @@ typedef struct sBSIM3v32model /* device parameters */ #define BSIM3v32_W 1 #define BSIM3v32_L 2 -#define BSIM3v32_M 15 #define BSIM3v32_AS 3 #define BSIM3v32_AD 4 #define BSIM3v32_PS 5 @@ -1272,6 +1280,9 @@ typedef struct sBSIM3v32model #define BSIM3v32_IC_VGS 12 #define BSIM3v32_IC 13 #define BSIM3v32_NQSMOD 14 +#define BSIM3v32_M 15 +#define BSIM3v32_DELVTO 16 +#define BSIM3v32_MULU0 17 /* model parameters */ #define BSIM3v32_MOD_CAPMOD 101