From 48262e5c0aadb6082e5548c94216a8eb83b5acac Mon Sep 17 00:00:00 2001 From: dwarning Date: Tue, 11 Apr 2017 21:31:54 +0200 Subject: [PATCH] extend safe operation area check (SOA) to polarity check for mosfets by additional parameters --- src/spicelib/devices/bsim3/b3.c | 5 + src/spicelib/devices/bsim3/b3mask.c | 15 + src/spicelib/devices/bsim3/b3mpar.c | 20 ++ src/spicelib/devices/bsim3/b3set.c | 10 + src/spicelib/devices/bsim3/b3soachk.c | 323 ++++++++++++++++--- src/spicelib/devices/bsim3/bsim3def.h | 27 +- src/spicelib/devices/bsim3v32/b3v32.c | 5 + src/spicelib/devices/bsim3v32/b3v32mask.c | 15 + src/spicelib/devices/bsim3v32/b3v32mpar.c | 20 ++ src/spicelib/devices/bsim3v32/b3v32set.c | 10 + src/spicelib/devices/bsim3v32/b3v32soachk.c | 323 ++++++++++++++++--- src/spicelib/devices/bsim3v32/bsim3v32def.h | 15 + src/spicelib/devices/bsim4/b4.c | 5 + src/spicelib/devices/bsim4/b4mask.c | 15 + src/spicelib/devices/bsim4/b4mpar.c | 20 ++ src/spicelib/devices/bsim4/b4set.c | 10 + src/spicelib/devices/bsim4/b4soachk.c | 321 +++++++++++++++--- src/spicelib/devices/bsim4/bsim4def.h | 27 +- src/spicelib/devices/bsim4v5/b4v5.c | 5 + src/spicelib/devices/bsim4v5/b4v5mask.c | 15 + src/spicelib/devices/bsim4v5/b4v5mpar.c | 20 ++ src/spicelib/devices/bsim4v5/b4v5set.c | 10 + src/spicelib/devices/bsim4v5/b4v5soachk.c | 321 +++++++++++++++--- src/spicelib/devices/bsim4v5/bsim4v5def.h | 27 +- src/spicelib/devices/bsim4v6/b4v6.c | 5 + src/spicelib/devices/bsim4v6/b4v6mask.c | 15 + src/spicelib/devices/bsim4v6/b4v6mpar.c | 20 ++ src/spicelib/devices/bsim4v6/b4v6set.c | 10 + src/spicelib/devices/bsim4v6/b4v6soachk.c | 321 +++++++++++++++--- src/spicelib/devices/bsim4v6/bsim4v6def.h | 15 + src/spicelib/devices/bsim4v7/b4v7.c | 5 + src/spicelib/devices/bsim4v7/b4v7mask.c | 15 + src/spicelib/devices/bsim4v7/b4v7mpar.c | 20 ++ src/spicelib/devices/bsim4v7/b4v7set.c | 10 + src/spicelib/devices/bsim4v7/b4v7soachk.c | 321 +++++++++++++++--- src/spicelib/devices/bsim4v7/bsim4v7def.h | 27 +- src/spicelib/devices/bsimsoi/b4soi.c | 5 + src/spicelib/devices/bsimsoi/b4soidef.h | 27 +- src/spicelib/devices/bsimsoi/b4soimask.c | 15 + src/spicelib/devices/bsimsoi/b4soimpar.c | 20 ++ src/spicelib/devices/bsimsoi/b4soiset.c | 10 + src/spicelib/devices/bsimsoi/b4soisoachk.c | 321 +++++++++++++++--- src/spicelib/devices/hisim2/hsm2.c | 7 +- src/spicelib/devices/hisim2/hsm2def.h | 15 + src/spicelib/devices/hisim2/hsm2mask.c | 15 + src/spicelib/devices/hisim2/hsm2mpar.c | 20 ++ src/spicelib/devices/hisim2/hsm2set.c | 5 + src/spicelib/devices/hisim2/hsm2soachk.c | 321 +++++++++++++++--- src/spicelib/devices/hisimhv1/hsmhv.c | 7 +- src/spicelib/devices/hisimhv1/hsmhvdef.h | 27 +- src/spicelib/devices/hisimhv1/hsmhvmask.c | 15 + src/spicelib/devices/hisimhv1/hsmhvmpar.c | 20 ++ src/spicelib/devices/hisimhv1/hsmhvset.c | 5 + src/spicelib/devices/hisimhv1/hsmhvsoachk.c | 321 +++++++++++++++--- src/spicelib/devices/hisimhv2/hsmhv2.c | 7 +- src/spicelib/devices/hisimhv2/hsmhv2def.h | 27 +- src/spicelib/devices/hisimhv2/hsmhv2mask.c | 15 + src/spicelib/devices/hisimhv2/hsmhv2mpar.c | 20 ++ src/spicelib/devices/hisimhv2/hsmhv2set.c | 5 + src/spicelib/devices/hisimhv2/hsmhv2soachk.c | 321 +++++++++++++++--- 60 files changed, 3442 insertions(+), 497 deletions(-) diff --git a/src/spicelib/devices/bsim3/b3.c b/src/spicelib/devices/bsim3/b3.c index ac81e5330..85bcb15c6 100644 --- a/src/spicelib/devices/bsim3/b3.c +++ b/src/spicelib/devices/bsim3/b3.c @@ -506,6 +506,11 @@ IOP("vgb_max", BSIM3_MOD_VGB_MAX, IF_REAL, "maximum voltage G-B branch"), IOP("vds_max", BSIM3_MOD_VDS_MAX, IF_REAL, "maximum voltage D-S branch"), IOP("vbs_max", BSIM3_MOD_VBS_MAX, IF_REAL, "maximum voltage B-S branch"), IOP("vbd_max", BSIM3_MOD_VBD_MAX, IF_REAL, "maximum voltage B-D branch"), +IOP("vgsr_max", BSIM3_MOD_VGSR_MAX, IF_REAL, "maximum voltage G-S branch"), +IOP("vgdr_max", BSIM3_MOD_VGDR_MAX, IF_REAL, "maximum voltage G-D branch"), +IOP("vgbr_max", BSIM3_MOD_VGBR_MAX, IF_REAL, "maximum voltage G-B branch"), +IOP("vbsr_max", BSIM3_MOD_VBSR_MAX, IF_REAL, "maximum voltage B-S branch"), +IOP("vbdr_max", BSIM3_MOD_VBDR_MAX, IF_REAL, "maximum voltage B-D branch"), IP( "nmos", BSIM3_MOD_NMOS, IF_FLAG, "Flag to indicate NMOS"), IP( "pmos", BSIM3_MOD_PMOS, IF_FLAG, "Flag to indicate PMOS"), diff --git a/src/spicelib/devices/bsim3/b3mask.c b/src/spicelib/devices/bsim3/b3mask.c index e78e42271..1c53839cd 100644 --- a/src/spicelib/devices/bsim3/b3mask.c +++ b/src/spicelib/devices/bsim3/b3mask.c @@ -1302,6 +1302,21 @@ IFvalue *value) case BSIM3_MOD_VBD_MAX: value->rValue = model->BSIM3vbdMax; return(OK); + case BSIM3_MOD_VGSR_MAX: + value->rValue = model->BSIM3vgsrMax; + return(OK); + case BSIM3_MOD_VGDR_MAX: + value->rValue = model->BSIM3vgdrMax; + return(OK); + case BSIM3_MOD_VGBR_MAX: + value->rValue = model->BSIM3vgbrMax; + return(OK); + case BSIM3_MOD_VBSR_MAX: + value->rValue = model->BSIM3vbsrMax; + return(OK); + case BSIM3_MOD_VBDR_MAX: + value->rValue = model->BSIM3vbdrMax; + return(OK); default: return(E_BADPARM); diff --git a/src/spicelib/devices/bsim3/b3mpar.c b/src/spicelib/devices/bsim3/b3mpar.c index 0cd9d6eec..807dd158f 100644 --- a/src/spicelib/devices/bsim3/b3mpar.c +++ b/src/spicelib/devices/bsim3/b3mpar.c @@ -1744,6 +1744,26 @@ GENmodel *inMod) mod->BSIM3vbdMax = value->rValue; mod->BSIM3vbdMaxGiven = TRUE; break; + case BSIM3_MOD_VGSR_MAX: + mod->BSIM3vgsrMax = value->rValue; + mod->BSIM3vgsrMaxGiven = TRUE; + break; + case BSIM3_MOD_VGDR_MAX: + mod->BSIM3vgdrMax = value->rValue; + mod->BSIM3vgdrMaxGiven = TRUE; + break; + case BSIM3_MOD_VGBR_MAX: + mod->BSIM3vgbrMax = value->rValue; + mod->BSIM3vgbrMaxGiven = TRUE; + break; + case BSIM3_MOD_VBSR_MAX: + mod->BSIM3vbsrMax = value->rValue; + mod->BSIM3vbsrMaxGiven = TRUE; + break; + case BSIM3_MOD_VBDR_MAX: + mod->BSIM3vbdrMax = value->rValue; + mod->BSIM3vbdrMaxGiven = TRUE; + break; case BSIM3_MOD_NMOS : if(value->iValue) { diff --git a/src/spicelib/devices/bsim3/b3set.c b/src/spicelib/devices/bsim3/b3set.c index 33cb88f98..fb15a2574 100644 --- a/src/spicelib/devices/bsim3/b3set.c +++ b/src/spicelib/devices/bsim3/b3set.c @@ -907,6 +907,16 @@ BSIM3instance **InstArray; model->BSIM3vbsMax = 1e99; if (!model->BSIM3vbdMaxGiven) model->BSIM3vbdMax = 1e99; + if (!model->BSIM3vgsrMaxGiven) + model->BSIM3vgsrMax = 1e99; + if (!model->BSIM3vgdrMaxGiven) + model->BSIM3vgdrMax = 1e99; + if (!model->BSIM3vgbrMaxGiven) + model->BSIM3vgbrMax = 1e99; + if (!model->BSIM3vbsrMaxGiven) + model->BSIM3vbsrMax = 1e99; + if (!model->BSIM3vbdrMaxGiven) + model->BSIM3vbdrMax = 1e99; /* loop through all the instances of the model */ for (here = model->BSIM3instances; here != NULL ; diff --git a/src/spicelib/devices/bsim3/b3soachk.c b/src/spicelib/devices/bsim3/b3soachk.c index f002aca88..53d43467e 100644 --- a/src/spicelib/devices/bsim3/b3soachk.c +++ b/src/spicelib/devices/bsim3/b3soachk.c @@ -37,71 +37,302 @@ BSIM3soaCheck(CKTcircuit *ckt, GENmodel *inModel) for (here = model->BSIM3instances; here; here = here->BSIM3nextInstance) { - vgs = fabs(ckt->CKTrhsOld [here->BSIM3gNode] - - ckt->CKTrhsOld [here->BSIM3sNodePrime]); + vgs = ckt->CKTrhsOld [here->BSIM3gNode] - + ckt->CKTrhsOld [here->BSIM3sNodePrime]; - vgd = fabs(ckt->CKTrhsOld [here->BSIM3gNode] - - ckt->CKTrhsOld [here->BSIM3dNodePrime]); + vgd = ckt->CKTrhsOld [here->BSIM3gNode] - + ckt->CKTrhsOld [here->BSIM3dNodePrime]; - vgb = fabs(ckt->CKTrhsOld [here->BSIM3gNode] - - ckt->CKTrhsOld [here->BSIM3bNode]); + vgb = ckt->CKTrhsOld [here->BSIM3gNode] - + ckt->CKTrhsOld [here->BSIM3bNode]; - vds = fabs(ckt->CKTrhsOld [here->BSIM3dNodePrime] - - ckt->CKTrhsOld [here->BSIM3sNodePrime]); + vds = ckt->CKTrhsOld [here->BSIM3dNodePrime] - + ckt->CKTrhsOld [here->BSIM3sNodePrime]; - vbs = fabs(ckt->CKTrhsOld [here->BSIM3bNode] - - ckt->CKTrhsOld [here->BSIM3sNodePrime]); + vbs = ckt->CKTrhsOld [here->BSIM3bNode] - + ckt->CKTrhsOld [here->BSIM3sNodePrime]; - vbd = fabs(ckt->CKTrhsOld [here->BSIM3bNode] - - ckt->CKTrhsOld [here->BSIM3dNodePrime]); - - if (vgs > model->BSIM3vgsMax) - if (warns_vgs < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgs|=%g has exceeded Vgs_max=%g\n", - vgs, model->BSIM3vgsMax); - warns_vgs++; + vbd = ckt->CKTrhsOld [here->BSIM3bNode] - + ckt->CKTrhsOld [here->BSIM3dNodePrime]; + + if (!model->BSIM3vgsrMaxGiven) { + if (fabs(vgs) > model->BSIM3vgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->BSIM3vgsMax); + warns_vgs++; + } + if (!model->BSIM3vgbMaxGiven) { + if (fabs(vgb) > model->BSIM3vgsMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgs_max=%g\n", + vgb, model->BSIM3vgsMax); + warns_vgb++; + } + } else { + if (fabs(vgb) > model->BSIM3vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->BSIM3vgbMax); + warns_vgb++; + } } - - if (vgd > model->BSIM3vgdMax) - if (warns_vgd < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgd|=%g has exceeded Vgd_max=%g\n", - vgd, model->BSIM3vgdMax); - warns_vgd++; + } else { + if (model->BSIM3type > 0) { + if (vgs > model->BSIM3vgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->BSIM3vgsMax); + warns_vgs++; + } + if (-1*vgs > model->BSIM3vgsrMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgsr_max=%g\n", + vgs, model->BSIM3vgsrMax); + warns_vgs++; + } + } else { + if (vgs > model->BSIM3vgsrMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgsr_max=%g\n", + vgs, model->BSIM3vgsrMax); + warns_vgs++; + } + if (-1*vgs > model->BSIM3vgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->BSIM3vgsMax); + warns_vgs++; + } } + } - if (vgb > model->BSIM3vgbMax) - if (warns_vgb < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgb|=%g has exceeded Vgb_max=%g\n", - vgb, model->BSIM3vgbMax); - warns_vgb++; + if (!model->BSIM3vgdrMaxGiven) { + if (fabs(vgd) > model->BSIM3vgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->BSIM3vgdMax); + warns_vgd++; + } + } else { + if (model->BSIM3type > 0) { + if (vgd > model->BSIM3vgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->BSIM3vgdMax); + warns_vgd++; + } + if (-1*vgd > model->BSIM3vgdrMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgdr_max=%g\n", + vgd, model->BSIM3vgdrMax); + warns_vgd++; + } + } else { + if (vgd > model->BSIM3vgdrMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgdr_max=%g\n", + vgd, model->BSIM3vgdrMax); + warns_vgd++; + } + if (-1*vgd > model->BSIM3vgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->BSIM3vgdMax); + warns_vgd++; + } } + } - if (vds > model->BSIM3vdsMax) + if (fabs(vds) > model->BSIM3vdsMax) if (warns_vds < maxwarns) { soa_printf(ckt, (GENinstance*) here, - "|Vds|=%g has exceeded Vds_max=%g\n", + "Vds=%g has exceeded Vds_max=%g\n", vds, model->BSIM3vdsMax); warns_vds++; } - if (vbs > model->BSIM3vbsMax) - if (warns_vbs < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vbs|=%g has exceeded Vbs_max=%g\n", - vbs, model->BSIM3vbsMax); - warns_vbs++; + if (!model->BSIM3vgbrMaxGiven) { + if (fabs(vgb) > model->BSIM3vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->BSIM3vgbMax); + warns_vgb++; + } + } else { + if (model->BSIM3type > 0) { + if (vgb > model->BSIM3vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->BSIM3vgbMax); + warns_vgb++; + } + if (-1*vgb > model->BSIM3vgbrMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgbr_max=%g\n", + vgb, model->BSIM3vgbrMax); + warns_vgb++; + } + } else { + if (vgb > model->BSIM3vgbrMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgbr_max=%g\n", + vgb, model->BSIM3vgbrMax); + warns_vgb++; + } + if (-1*vgb > model->BSIM3vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->BSIM3vgbMax); + warns_vgb++; + } } + } - if (vbd > model->BSIM3vbdMax) - if (warns_vbd < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vbd|=%g has exceeded Vbd_max=%g\n", - vbd, model->BSIM3vbdMax); - warns_vbd++; + if (!model->BSIM3vbsrMaxGiven) { + if (!model->BSIM3vbsMaxGiven) { + if (fabs(vbs) > model->BSIM3vbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->BSIM3vbdMax); + warns_vbs++; + } + } else { + if (fabs(vbs) > model->BSIM3vbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->BSIM3vbsMax); + warns_vbs++; + } + } + } else { + if (!model->BSIM3vbsMaxGiven) { + if (model->BSIM3type > 0) { + if (vbs > model->BSIM3vbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->BSIM3vbdMax); + warns_vbs++; + } + if (-1*vbs > model->BSIM3vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->BSIM3vbsrMax); + warns_vbs++; + } + } else { + if (vbs > model->BSIM3vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->BSIM3vbsrMax); + warns_vbs++; + } + if (-1*vbs > model->BSIM3vbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->BSIM3vbdMax); + warns_vbs++; + } + } + } else { + if (model->BSIM3type > 0) { + if (vbs > model->BSIM3vbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->BSIM3vbsMax); + warns_vbs++; + } + if (-1*vbs > model->BSIM3vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->BSIM3vbsrMax); + warns_vbs++; + } + } else { + if (vbs > model->BSIM3vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->BSIM3vbsrMax); + warns_vbs++; + } + if (-1*vbs > model->BSIM3vbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->BSIM3vbsMax); + warns_vbs++; + } + } + } + } + + if (!model->BSIM3vbdrMaxGiven) { + if (fabs(vbd) > model->BSIM3vbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->BSIM3vbdMax); + warns_vbd++; + } + } else { + if (model->BSIM3type > 0) { + if (vbd > model->BSIM3vbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->BSIM3vbdMax); + warns_vbd++; + } + if (-1*vbd > model->BSIM3vbdrMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbdr_max=%g\n", + vbd, model->BSIM3vbdrMax); + warns_vbd++; + } + } else { + if (vbd > model->BSIM3vbdrMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbdr_max=%g\n", + vbd, model->BSIM3vbdrMax); + warns_vbd++; + } + if (-1*vbd > model->BSIM3vbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->BSIM3vbdMax); + warns_vbd++; + } } + } } } diff --git a/src/spicelib/devices/bsim3/bsim3def.h b/src/spicelib/devices/bsim3/bsim3def.h index 9b1b9503d..1db57b357 100644 --- a/src/spicelib/devices/bsim3/bsim3def.h +++ b/src/spicelib/devices/bsim3/bsim3def.h @@ -870,6 +870,11 @@ typedef struct sBSIM3model double BSIM3vdsMax; double BSIM3vbsMax; double BSIM3vbdMax; + double BSIM3vgsrMax; + double BSIM3vgdrMax; + double BSIM3vgbrMax; + double BSIM3vbsrMax; + double BSIM3vbdrMax; struct bsim3SizeDependParam *pSizeDependParamKnot; @@ -1298,6 +1303,11 @@ typedef struct sBSIM3model unsigned BSIM3vdsMaxGiven :1; unsigned BSIM3vbsMaxGiven :1; unsigned BSIM3vbdMaxGiven :1; + unsigned BSIM3vgsrMaxGiven :1; + unsigned BSIM3vgdrMaxGiven :1; + unsigned BSIM3vgbrMaxGiven :1; + unsigned BSIM3vbsrMaxGiven :1; + unsigned BSIM3vbdrMaxGiven :1; unsigned BSIM3LintGiven :1; unsigned BSIM3LlGiven :1; @@ -1881,12 +1891,17 @@ typedef struct sBSIM3model #define BSIM3_CBDB 792 #define BSIM3_CBSB 793 -#define BSIM3_MOD_VGS_MAX 801 -#define BSIM3_MOD_VGD_MAX 802 -#define BSIM3_MOD_VGB_MAX 803 -#define BSIM3_MOD_VDS_MAX 804 -#define BSIM3_MOD_VBS_MAX 805 -#define BSIM3_MOD_VBD_MAX 806 +#define BSIM3_MOD_VGS_MAX 801 +#define BSIM3_MOD_VGD_MAX 802 +#define BSIM3_MOD_VGB_MAX 803 +#define BSIM3_MOD_VDS_MAX 804 +#define BSIM3_MOD_VBS_MAX 805 +#define BSIM3_MOD_VBD_MAX 806 +#define BSIM3_MOD_VGSR_MAX 807 +#define BSIM3_MOD_VGDR_MAX 808 +#define BSIM3_MOD_VGBR_MAX 809 +#define BSIM3_MOD_VBSR_MAX 810 +#define BSIM3_MOD_VBDR_MAX 811 #include "bsim3ext.h" diff --git a/src/spicelib/devices/bsim3v32/b3v32.c b/src/spicelib/devices/bsim3v32/b3v32.c index a7e037278..8b38ff9b3 100644 --- a/src/spicelib/devices/bsim3v32/b3v32.c +++ b/src/spicelib/devices/bsim3v32/b3v32.c @@ -506,6 +506,11 @@ IOP("vgb_max", BSIM3v32_MOD_VGB_MAX, IF_REAL, "maximum voltage G-B branch"), IOP("vds_max", BSIM3v32_MOD_VDS_MAX, IF_REAL, "maximum voltage D-S branch"), IOP("vbs_max", BSIM3v32_MOD_VBS_MAX, IF_REAL, "maximum voltage B-S branch"), IOP("vbd_max", BSIM3v32_MOD_VBD_MAX, IF_REAL, "maximum voltage B-D branch"), +IOP("vgsr_max", BSIM3v32_MOD_VGSR_MAX, IF_REAL, "maximum voltage G-S branch"), +IOP("vgdr_max", BSIM3v32_MOD_VGDR_MAX, IF_REAL, "maximum voltage G-D branch"), +IOP("vgbr_max", BSIM3v32_MOD_VGBR_MAX, IF_REAL, "maximum voltage G-B branch"), +IOP("vbsr_max", BSIM3v32_MOD_VBSR_MAX, IF_REAL, "maximum voltage B-S branch"), +IOP("vbdr_max", BSIM3v32_MOD_VBDR_MAX, IF_REAL, "maximum voltage B-D branch"), IP( "nmos", BSIM3v32_MOD_NMOS, IF_FLAG, "Flag to indicate NMOS"), IP( "pmos", BSIM3v32_MOD_PMOS, IF_FLAG, "Flag to indicate PMOS"), diff --git a/src/spicelib/devices/bsim3v32/b3v32mask.c b/src/spicelib/devices/bsim3v32/b3v32mask.c index 02cb252ab..15ba67204 100644 --- a/src/spicelib/devices/bsim3v32/b3v32mask.c +++ b/src/spicelib/devices/bsim3v32/b3v32mask.c @@ -1297,6 +1297,21 @@ BSIM3v32mAsk (CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value) case BSIM3v32_MOD_VBD_MAX: value->rValue = model->BSIM3v32vbdMax; return(OK); + case BSIM3v32_MOD_VGSR_MAX: + value->rValue = model->BSIM3v32vgsrMax; + return(OK); + case BSIM3v32_MOD_VGDR_MAX: + value->rValue = model->BSIM3v32vgdrMax; + return(OK); + case BSIM3v32_MOD_VGBR_MAX: + value->rValue = model->BSIM3v32vgbrMax; + return(OK); + case BSIM3v32_MOD_VBSR_MAX: + value->rValue = model->BSIM3v32vbsrMax; + return(OK); + case BSIM3v32_MOD_VBDR_MAX: + value->rValue = model->BSIM3v32vbdrMax; + return(OK); default: return(E_BADPARM); diff --git a/src/spicelib/devices/bsim3v32/b3v32mpar.c b/src/spicelib/devices/bsim3v32/b3v32mpar.c index a0664a8db..c3ec08c2a 100644 --- a/src/spicelib/devices/bsim3v32/b3v32mpar.c +++ b/src/spicelib/devices/bsim3v32/b3v32mpar.c @@ -1740,6 +1740,26 @@ BSIM3v32mParam(int param, IFvalue *value, GENmodel *inMod) mod->BSIM3v32vbdMax = value->rValue; mod->BSIM3v32vbdMaxGiven = TRUE; break; + case BSIM3v32_MOD_VGSR_MAX: + mod->BSIM3v32vgsrMax = value->rValue; + mod->BSIM3v32vgsrMaxGiven = TRUE; + break; + case BSIM3v32_MOD_VGDR_MAX: + mod->BSIM3v32vgdrMax = value->rValue; + mod->BSIM3v32vgdrMaxGiven = TRUE; + break; + case BSIM3v32_MOD_VGBR_MAX: + mod->BSIM3v32vgbrMax = value->rValue; + mod->BSIM3v32vgbrMaxGiven = TRUE; + break; + case BSIM3v32_MOD_VBSR_MAX: + mod->BSIM3v32vbsrMax = value->rValue; + mod->BSIM3v32vbsrMaxGiven = TRUE; + break; + case BSIM3v32_MOD_VBDR_MAX: + mod->BSIM3v32vbdrMax = value->rValue; + mod->BSIM3v32vbdrMaxGiven = TRUE; + break; case BSIM3v32_MOD_NMOS : if(value->iValue) { diff --git a/src/spicelib/devices/bsim3v32/b3v32set.c b/src/spicelib/devices/bsim3v32/b3v32set.c index 991cb01ed..53f787493 100644 --- a/src/spicelib/devices/bsim3v32/b3v32set.c +++ b/src/spicelib/devices/bsim3v32/b3v32set.c @@ -923,6 +923,16 @@ BSIM3v32instance **InstArray; model->BSIM3v32vbsMax = 1e99; if (!model->BSIM3v32vbdMaxGiven) model->BSIM3v32vbdMax = 1e99; + if (!model->BSIM3v32vgsrMaxGiven) + model->BSIM3v32vgsrMax = 1e99; + if (!model->BSIM3v32vgdrMaxGiven) + model->BSIM3v32vgdrMax = 1e99; + if (!model->BSIM3v32vgbrMaxGiven) + model->BSIM3v32vgbrMax = 1e99; + if (!model->BSIM3v32vbsrMaxGiven) + model->BSIM3v32vbsrMax = 1e99; + if (!model->BSIM3v32vbdrMaxGiven) + model->BSIM3v32vbdrMax = 1e99; /* loop through all the instances of the model */ for (here = model->BSIM3v32instances; here != NULL ; diff --git a/src/spicelib/devices/bsim3v32/b3v32soachk.c b/src/spicelib/devices/bsim3v32/b3v32soachk.c index e60ce1bd0..a4bf39a8f 100644 --- a/src/spicelib/devices/bsim3v32/b3v32soachk.c +++ b/src/spicelib/devices/bsim3v32/b3v32soachk.c @@ -37,71 +37,302 @@ BSIM3v32soaCheck(CKTcircuit *ckt, GENmodel *inModel) for (here = model->BSIM3v32instances; here; here = here->BSIM3v32nextInstance) { - vgs = fabs(ckt->CKTrhsOld [here->BSIM3v32gNode] - - ckt->CKTrhsOld [here->BSIM3v32sNodePrime]); + vgs = ckt->CKTrhsOld [here->BSIM3v32gNode] - + ckt->CKTrhsOld [here->BSIM3v32sNodePrime]; - vgd = fabs(ckt->CKTrhsOld [here->BSIM3v32gNode] - - ckt->CKTrhsOld [here->BSIM3v32dNodePrime]); + vgd = ckt->CKTrhsOld [here->BSIM3v32gNode] - + ckt->CKTrhsOld [here->BSIM3v32dNodePrime]; - vgb = fabs(ckt->CKTrhsOld [here->BSIM3v32gNode] - - ckt->CKTrhsOld [here->BSIM3v32bNode]); + vgb = ckt->CKTrhsOld [here->BSIM3v32gNode] - + ckt->CKTrhsOld [here->BSIM3v32bNode]; - vds = fabs(ckt->CKTrhsOld [here->BSIM3v32dNodePrime] - - ckt->CKTrhsOld [here->BSIM3v32sNodePrime]); + vds = ckt->CKTrhsOld [here->BSIM3v32dNodePrime] - + ckt->CKTrhsOld [here->BSIM3v32sNodePrime]; - vbs = fabs(ckt->CKTrhsOld [here->BSIM3v32bNode] - - ckt->CKTrhsOld [here->BSIM3v32sNodePrime]); + vbs = ckt->CKTrhsOld [here->BSIM3v32bNode] - + ckt->CKTrhsOld [here->BSIM3v32sNodePrime]; - vbd = fabs(ckt->CKTrhsOld [here->BSIM3v32bNode] - - ckt->CKTrhsOld [here->BSIM3v32dNodePrime]); - - if (vgs > model->BSIM3v32vgsMax) - if (warns_vgs < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgs|=%g has exceeded Vgs_max=%g\n", - vgs, model->BSIM3v32vgsMax); - warns_vgs++; + vbd = ckt->CKTrhsOld [here->BSIM3v32bNode] - + ckt->CKTrhsOld [here->BSIM3v32dNodePrime]; + + if (!model->BSIM3v32vgsrMaxGiven) { + if (fabs(vgs) > model->BSIM3v32vgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->BSIM3v32vgsMax); + warns_vgs++; + } + if (!model->BSIM3v32vgbMaxGiven) { + if (fabs(vgb) > model->BSIM3v32vgsMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgs_max=%g\n", + vgb, model->BSIM3v32vgsMax); + warns_vgb++; + } + } else { + if (fabs(vgb) > model->BSIM3v32vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->BSIM3v32vgbMax); + warns_vgb++; + } } - - if (vgd > model->BSIM3v32vgdMax) - if (warns_vgd < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgd|=%g has exceeded Vgd_max=%g\n", - vgd, model->BSIM3v32vgdMax); - warns_vgd++; + } else { + if (model->BSIM3v32type > 0) { + if (vgs > model->BSIM3v32vgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->BSIM3v32vgsMax); + warns_vgs++; + } + if (-1*vgs > model->BSIM3v32vgsrMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgsr_max=%g\n", + vgs, model->BSIM3v32vgsrMax); + warns_vgs++; + } + } else { + if (vgs > model->BSIM3v32vgsrMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgsr_max=%g\n", + vgs, model->BSIM3v32vgsrMax); + warns_vgs++; + } + if (-1*vgs > model->BSIM3v32vgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->BSIM3v32vgsMax); + warns_vgs++; + } } + } - if (vgb > model->BSIM3v32vgbMax) - if (warns_vgb < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgb|=%g has exceeded Vgb_max=%g\n", - vgb, model->BSIM3v32vgbMax); - warns_vgb++; + if (!model->BSIM3v32vgdrMaxGiven) { + if (fabs(vgd) > model->BSIM3v32vgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->BSIM3v32vgdMax); + warns_vgd++; + } + } else { + if (model->BSIM3v32type > 0) { + if (vgd > model->BSIM3v32vgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->BSIM3v32vgdMax); + warns_vgd++; + } + if (-1*vgd > model->BSIM3v32vgdrMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgdr_max=%g\n", + vgd, model->BSIM3v32vgdrMax); + warns_vgd++; + } + } else { + if (vgd > model->BSIM3v32vgdrMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgdr_max=%g\n", + vgd, model->BSIM3v32vgdrMax); + warns_vgd++; + } + if (-1*vgd > model->BSIM3v32vgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->BSIM3v32vgdMax); + warns_vgd++; + } } + } - if (vds > model->BSIM3v32vdsMax) + if (fabs(vds) > model->BSIM3v32vdsMax) if (warns_vds < maxwarns) { soa_printf(ckt, (GENinstance*) here, - "|Vds|=%g has exceeded Vds_max=%g\n", + "Vds=%g has exceeded Vds_max=%g\n", vds, model->BSIM3v32vdsMax); warns_vds++; } - if (vbs > model->BSIM3v32vbsMax) - if (warns_vbs < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vbs|=%g has exceeded Vbs_max=%g\n", - vbs, model->BSIM3v32vbsMax); - warns_vbs++; + if (!model->BSIM3v32vgbrMaxGiven) { + if (fabs(vgb) > model->BSIM3v32vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->BSIM3v32vgbMax); + warns_vgb++; + } + } else { + if (model->BSIM3v32type > 0) { + if (vgb > model->BSIM3v32vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->BSIM3v32vgbMax); + warns_vgb++; + } + if (-1*vgb > model->BSIM3v32vgbrMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgbr_max=%g\n", + vgb, model->BSIM3v32vgbrMax); + warns_vgb++; + } + } else { + if (vgb > model->BSIM3v32vgbrMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgbr_max=%g\n", + vgb, model->BSIM3v32vgbrMax); + warns_vgb++; + } + if (-1*vgb > model->BSIM3v32vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->BSIM3v32vgbMax); + warns_vgb++; + } } + } - if (vbd > model->BSIM3v32vbdMax) - if (warns_vbd < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vbd|=%g has exceeded Vbd_max=%g\n", - vbd, model->BSIM3v32vbdMax); - warns_vbd++; + if (!model->BSIM3v32vbsrMaxGiven) { + if (!model->BSIM3v32vbsMaxGiven) { + if (fabs(vbs) > model->BSIM3v32vbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->BSIM3v32vbdMax); + warns_vbs++; + } + } else { + if (fabs(vbs) > model->BSIM3v32vbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->BSIM3v32vbsMax); + warns_vbs++; + } + } + } else { + if (!model->BSIM3v32vbsMaxGiven) { + if (model->BSIM3v32type > 0) { + if (vbs > model->BSIM3v32vbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->BSIM3v32vbdMax); + warns_vbs++; + } + if (-1*vbs > model->BSIM3v32vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->BSIM3v32vbsrMax); + warns_vbs++; + } + } else { + if (vbs > model->BSIM3v32vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->BSIM3v32vbsrMax); + warns_vbs++; + } + if (-1*vbs > model->BSIM3v32vbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->BSIM3v32vbdMax); + warns_vbs++; + } + } + } else { + if (model->BSIM3v32type > 0) { + if (vbs > model->BSIM3v32vbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->BSIM3v32vbsMax); + warns_vbs++; + } + if (-1*vbs > model->BSIM3v32vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->BSIM3v32vbsrMax); + warns_vbs++; + } + } else { + if (vbs > model->BSIM3v32vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->BSIM3v32vbsrMax); + warns_vbs++; + } + if (-1*vbs > model->BSIM3v32vbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->BSIM3v32vbsMax); + warns_vbs++; + } + } + } + } + + if (!model->BSIM3v32vbdrMaxGiven) { + if (fabs(vbd) > model->BSIM3v32vbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->BSIM3v32vbdMax); + warns_vbd++; + } + } else { + if (model->BSIM3v32type > 0) { + if (vbd > model->BSIM3v32vbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->BSIM3v32vbdMax); + warns_vbd++; + } + if (-1*vbd > model->BSIM3v32vbdrMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbdr_max=%g\n", + vbd, model->BSIM3v32vbdrMax); + warns_vbd++; + } + } else { + if (vbd > model->BSIM3v32vbdrMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbdr_max=%g\n", + vbd, model->BSIM3v32vbdrMax); + warns_vbd++; + } + if (-1*vbd > model->BSIM3v32vbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->BSIM3v32vbdMax); + warns_vbd++; + } } + } } } diff --git a/src/spicelib/devices/bsim3v32/bsim3v32def.h b/src/spicelib/devices/bsim3v32/bsim3v32def.h index dd784ae37..6bc0d27e8 100644 --- a/src/spicelib/devices/bsim3v32/bsim3v32def.h +++ b/src/spicelib/devices/bsim3v32/bsim3v32def.h @@ -875,6 +875,11 @@ typedef struct sBSIM3v32model double BSIM3v32vdsMax; double BSIM3v32vbsMax; double BSIM3v32vbdMax; + double BSIM3v32vgsrMax; + double BSIM3v32vgdrMax; + double BSIM3v32vgbrMax; + double BSIM3v32vbsrMax; + double BSIM3v32vbdrMax; struct bsim3v32SizeDependParam *pSizeDependParamKnot; @@ -1326,6 +1331,11 @@ typedef struct sBSIM3v32model unsigned BSIM3v32vdsMaxGiven :1; unsigned BSIM3v32vbsMaxGiven :1; unsigned BSIM3v32vbdMaxGiven :1; + unsigned BSIM3v32vgsrMaxGiven :1; + unsigned BSIM3v32vgdrMaxGiven :1; + unsigned BSIM3v32vgbrMaxGiven :1; + unsigned BSIM3v32vbsrMaxGiven :1; + unsigned BSIM3v32vbdrMaxGiven :1; } BSIM3v32model; @@ -1890,6 +1900,11 @@ typedef struct sBSIM3v32model #define BSIM3v32_MOD_VDS_MAX 804 #define BSIM3v32_MOD_VBS_MAX 805 #define BSIM3v32_MOD_VBD_MAX 806 +#define BSIM3v32_MOD_VGSR_MAX 807 +#define BSIM3v32_MOD_VGDR_MAX 808 +#define BSIM3v32_MOD_VGBR_MAX 809 +#define BSIM3v32_MOD_VBSR_MAX 810 +#define BSIM3v32_MOD_VBDR_MAX 811 #include "bsim3v32ext.h" diff --git a/src/spicelib/devices/bsim4/b4.c b/src/spicelib/devices/bsim4/b4.c index 1127aa81d..d58ff67eb 100644 --- a/src/spicelib/devices/bsim4/b4.c +++ b/src/spicelib/devices/bsim4/b4.c @@ -1076,6 +1076,11 @@ IOP("vgb_max", BSIM4_MOD_VGB_MAX, IF_REAL, "maximum voltage G-B branch"), IOP("vds_max", BSIM4_MOD_VDS_MAX, IF_REAL, "maximum voltage D-S branch"), IOP("vbs_max", BSIM4_MOD_VBS_MAX, IF_REAL, "maximum voltage B-S branch"), IOP("vbd_max", BSIM4_MOD_VBD_MAX, IF_REAL, "maximum voltage B-D branch"), +IOP("vgsr_max", BSIM4_MOD_VGSR_MAX, IF_REAL, "maximum voltage G-S branch"), +IOP("vgdr_max", BSIM4_MOD_VGDR_MAX, IF_REAL, "maximum voltage G-D branch"), +IOP("vgbr_max", BSIM4_MOD_VGBR_MAX, IF_REAL, "maximum voltage G-B branch"), +IOP("vbsr_max", BSIM4_MOD_VBSR_MAX, IF_REAL, "maximum voltage B-S branch"), +IOP("vbdr_max", BSIM4_MOD_VBDR_MAX, IF_REAL, "maximum voltage B-D branch"), IP( "nmos", BSIM4_MOD_NMOS, IF_FLAG, "Flag to indicate NMOS"), IP( "pmos", BSIM4_MOD_PMOS, IF_FLAG, "Flag to indicate PMOS"), diff --git a/src/spicelib/devices/bsim4/b4mask.c b/src/spicelib/devices/bsim4/b4mask.c index a5f434609..8e802cc30 100644 --- a/src/spicelib/devices/bsim4/b4mask.c +++ b/src/spicelib/devices/bsim4/b4mask.c @@ -2751,6 +2751,21 @@ IFvalue *value) case BSIM4_MOD_VBD_MAX: value->rValue = model->BSIM4vbdMax; return(OK); + case BSIM4_MOD_VGSR_MAX: + value->rValue = model->BSIM4vgsrMax; + return(OK); + case BSIM4_MOD_VGDR_MAX: + value->rValue = model->BSIM4vgdrMax; + return(OK); + case BSIM4_MOD_VGBR_MAX: + value->rValue = model->BSIM4vgbrMax; + return(OK); + case BSIM4_MOD_VBSR_MAX: + value->rValue = model->BSIM4vbsrMax; + return(OK); + case BSIM4_MOD_VBDR_MAX: + value->rValue = model->BSIM4vbdrMax; + return(OK); default: return(E_BADPARM); diff --git a/src/spicelib/devices/bsim4/b4mpar.c b/src/spicelib/devices/bsim4/b4mpar.c index 4d1906271..dcc118d40 100644 --- a/src/spicelib/devices/bsim4/b4mpar.c +++ b/src/spicelib/devices/bsim4/b4mpar.c @@ -3664,6 +3664,26 @@ GENmodel *inMod) mod->BSIM4vbdMax = value->rValue; mod->BSIM4vbdMaxGiven = TRUE; break; + case BSIM4_MOD_VGSR_MAX: + mod->BSIM4vgsrMax = value->rValue; + mod->BSIM4vgsrMaxGiven = TRUE; + break; + case BSIM4_MOD_VGDR_MAX: + mod->BSIM4vgdrMax = value->rValue; + mod->BSIM4vgdrMaxGiven = TRUE; + break; + case BSIM4_MOD_VGBR_MAX: + mod->BSIM4vgbrMax = value->rValue; + mod->BSIM4vgbrMaxGiven = TRUE; + break; + case BSIM4_MOD_VBSR_MAX: + mod->BSIM4vbsrMax = value->rValue; + mod->BSIM4vbsrMaxGiven = TRUE; + break; + case BSIM4_MOD_VBDR_MAX: + mod->BSIM4vbdrMax = value->rValue; + mod->BSIM4vbdrMaxGiven = TRUE; + break; case BSIM4_MOD_NMOS : if(value->iValue) { diff --git a/src/spicelib/devices/bsim4/b4set.c b/src/spicelib/devices/bsim4/b4set.c index 255bee971..cc6c04a64 100644 --- a/src/spicelib/devices/bsim4/b4set.c +++ b/src/spicelib/devices/bsim4/b4set.c @@ -2233,6 +2233,16 @@ BSIM4instance **InstArray; model->BSIM4vbsMax = 1e99; if (!model->BSIM4vbdMaxGiven) model->BSIM4vbdMax = 1e99; + if (!model->BSIM4vgsrMaxGiven) + model->BSIM4vgsrMax = 1e99; + if (!model->BSIM4vgdrMaxGiven) + model->BSIM4vgdrMax = 1e99; + if (!model->BSIM4vgbrMaxGiven) + model->BSIM4vgbrMax = 1e99; + if (!model->BSIM4vbsrMaxGiven) + model->BSIM4vbsrMax = 1e99; + if (!model->BSIM4vbdrMaxGiven) + model->BSIM4vbdrMax = 1e99; /* stress effect */ if (!model->BSIM4sarefGiven) diff --git a/src/spicelib/devices/bsim4/b4soachk.c b/src/spicelib/devices/bsim4/b4soachk.c index c8b0d4b2d..6b7639878 100644 --- a/src/spicelib/devices/bsim4/b4soachk.c +++ b/src/spicelib/devices/bsim4/b4soachk.c @@ -37,71 +37,302 @@ BSIM4soaCheck(CKTcircuit *ckt, GENmodel *inModel) for (here = model->BSIM4instances; here; here = here->BSIM4nextInstance) { - vgs = fabs(ckt->CKTrhsOld [here->BSIM4gNodePrime] - - ckt->CKTrhsOld [here->BSIM4sNodePrime]); + vgs = ckt->CKTrhsOld [here->BSIM4gNodePrime] - + ckt->CKTrhsOld [here->BSIM4sNodePrime]; - vgd = fabs(ckt->CKTrhsOld [here->BSIM4gNodePrime] - - ckt->CKTrhsOld [here->BSIM4dNodePrime]); + vgd = ckt->CKTrhsOld [here->BSIM4gNodePrime] - + ckt->CKTrhsOld [here->BSIM4dNodePrime]; - vgb = fabs(ckt->CKTrhsOld [here->BSIM4gNodePrime] - - ckt->CKTrhsOld [here->BSIM4bNodePrime]); + vgb = ckt->CKTrhsOld [here->BSIM4gNodePrime] - + ckt->CKTrhsOld [here->BSIM4bNodePrime]; - vds = fabs(ckt->CKTrhsOld [here->BSIM4dNodePrime] - - ckt->CKTrhsOld [here->BSIM4sNodePrime]); + vds = ckt->CKTrhsOld [here->BSIM4dNodePrime] - + ckt->CKTrhsOld [here->BSIM4sNodePrime]; - vbs = fabs(ckt->CKTrhsOld [here->BSIM4bNodePrime] - - ckt->CKTrhsOld [here->BSIM4sNodePrime]); + vbs = ckt->CKTrhsOld [here->BSIM4bNodePrime] - + ckt->CKTrhsOld [here->BSIM4sNodePrime]; - vbd = fabs(ckt->CKTrhsOld [here->BSIM4bNodePrime] - - ckt->CKTrhsOld [here->BSIM4dNodePrime]); + vbd = ckt->CKTrhsOld [here->BSIM4bNodePrime] - + ckt->CKTrhsOld [here->BSIM4dNodePrime]; - if (vgs > model->BSIM4vgsMax) - if (warns_vgs < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgs|=%g has exceeded Vgs_max=%g\n", - vgs, model->BSIM4vgsMax); - warns_vgs++; + if (!model->BSIM4vgsrMaxGiven) { + if (fabs(vgs) > model->BSIM4vgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->BSIM4vgsMax); + warns_vgs++; + } + if (!model->BSIM4vgbMaxGiven) { + if (fabs(vgb) > model->BSIM4vgsMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgs_max=%g\n", + vgb, model->BSIM4vgsMax); + warns_vgb++; + } + } else { + if (fabs(vgb) > model->BSIM4vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->BSIM4vgbMax); + warns_vgb++; + } } - - if (vgd > model->BSIM4vgdMax) - if (warns_vgd < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgd|=%g has exceeded Vgd_max=%g\n", - vgd, model->BSIM4vgdMax); - warns_vgd++; + } else { + if (model->BSIM4type > 0) { + if (vgs > model->BSIM4vgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->BSIM4vgsMax); + warns_vgs++; + } + if (-1*vgs > model->BSIM4vgsrMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgsr_max=%g\n", + vgs, model->BSIM4vgsrMax); + warns_vgs++; + } + } else { + if (vgs > model->BSIM4vgsrMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgsr_max=%g\n", + vgs, model->BSIM4vgsrMax); + warns_vgs++; + } + if (-1*vgs > model->BSIM4vgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->BSIM4vgsMax); + warns_vgs++; + } } + } - if (vgb > model->BSIM4vgbMax) - if (warns_vgb < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgb|=%g has exceeded Vgb_max=%g\n", - vgb, model->BSIM4vgbMax); - warns_vgb++; + if (!model->BSIM4vgdrMaxGiven) { + if (fabs(vgd) > model->BSIM4vgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->BSIM4vgdMax); + warns_vgd++; + } + } else { + if (model->BSIM4type > 0) { + if (vgd > model->BSIM4vgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->BSIM4vgdMax); + warns_vgd++; + } + if (-1*vgd > model->BSIM4vgdrMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgdr_max=%g\n", + vgd, model->BSIM4vgdrMax); + warns_vgd++; + } + } else { + if (vgd > model->BSIM4vgdrMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgdr_max=%g\n", + vgd, model->BSIM4vgdrMax); + warns_vgd++; + } + if (-1*vgd > model->BSIM4vgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->BSIM4vgdMax); + warns_vgd++; + } } + } - if (vds > model->BSIM4vdsMax) + if (fabs(vds) > model->BSIM4vdsMax) if (warns_vds < maxwarns) { soa_printf(ckt, (GENinstance*) here, - "|Vds|=%g has exceeded Vds_max=%g\n", + "Vds=%g has exceeded Vds_max=%g\n", vds, model->BSIM4vdsMax); warns_vds++; } - if (vbs > model->BSIM4vbsMax) - if (warns_vbs < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vbs|=%g has exceeded Vbs_max=%g\n", - vbs, model->BSIM4vbsMax); - warns_vbs++; + if (!model->BSIM4vgbrMaxGiven) { + if (fabs(vgb) > model->BSIM4vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->BSIM4vgbMax); + warns_vgb++; + } + } else { + if (model->BSIM4type > 0) { + if (vgb > model->BSIM4vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->BSIM4vgbMax); + warns_vgb++; + } + if (-1*vgb > model->BSIM4vgbrMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgbr_max=%g\n", + vgb, model->BSIM4vgbrMax); + warns_vgb++; + } + } else { + if (vgb > model->BSIM4vgbrMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgbr_max=%g\n", + vgb, model->BSIM4vgbrMax); + warns_vgb++; + } + if (-1*vgb > model->BSIM4vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->BSIM4vgbMax); + warns_vgb++; + } } + } - if (vbd > model->BSIM4vbdMax) - if (warns_vbd < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vbd|=%g has exceeded Vbd_max=%g\n", - vbd, model->BSIM4vbdMax); - warns_vbd++; + if (!model->BSIM4vbsrMaxGiven) { + if (!model->BSIM4vbsMaxGiven) { + if (fabs(vbs) > model->BSIM4vbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->BSIM4vbdMax); + warns_vbs++; + } + } else { + if (fabs(vbs) > model->BSIM4vbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->BSIM4vbsMax); + warns_vbs++; + } + } + } else { + if (!model->BSIM4vbsMaxGiven) { + if (model->BSIM4type > 0) { + if (vbs > model->BSIM4vbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->BSIM4vbdMax); + warns_vbs++; + } + if (-1*vbs > model->BSIM4vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->BSIM4vbsrMax); + warns_vbs++; + } + } else { + if (vbs > model->BSIM4vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->BSIM4vbsrMax); + warns_vbs++; + } + if (-1*vbs > model->BSIM4vbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->BSIM4vbdMax); + warns_vbs++; + } + } + } else { + if (model->BSIM4type > 0) { + if (vbs > model->BSIM4vbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->BSIM4vbsMax); + warns_vbs++; + } + if (-1*vbs > model->BSIM4vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->BSIM4vbsrMax); + warns_vbs++; + } + } else { + if (vbs > model->BSIM4vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->BSIM4vbsrMax); + warns_vbs++; + } + if (-1*vbs > model->BSIM4vbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->BSIM4vbsMax); + warns_vbs++; + } + } + } + } + + if (!model->BSIM4vbdrMaxGiven) { + if (fabs(vbd) > model->BSIM4vbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->BSIM4vbdMax); + warns_vbd++; + } + } else { + if (model->BSIM4type > 0) { + if (vbd > model->BSIM4vbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->BSIM4vbdMax); + warns_vbd++; + } + if (-1*vbd > model->BSIM4vbdrMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbdr_max=%g\n", + vbd, model->BSIM4vbdrMax); + warns_vbd++; + } + } else { + if (vbd > model->BSIM4vbdrMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbdr_max=%g\n", + vbd, model->BSIM4vbdrMax); + warns_vbd++; + } + if (-1*vbd > model->BSIM4vbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->BSIM4vbdMax); + warns_vbd++; + } } + } } } diff --git a/src/spicelib/devices/bsim4/bsim4def.h b/src/spicelib/devices/bsim4/bsim4def.h index 44a0e04fc..c85683654 100644 --- a/src/spicelib/devices/bsim4/bsim4def.h +++ b/src/spicelib/devices/bsim4/bsim4def.h @@ -1819,6 +1819,11 @@ typedef struct sBSIM4model double BSIM4vdsMax; double BSIM4vbsMax; double BSIM4vbdMax; + double BSIM4vgsrMax; + double BSIM4vgdrMax; + double BSIM4vgbrMax; + double BSIM4vbsrMax; + double BSIM4vbdrMax; struct bsim4SizeDependParam *pSizeDependParamKnot; @@ -2682,6 +2687,11 @@ typedef struct sBSIM4model unsigned BSIM4vdsMaxGiven :1; unsigned BSIM4vbsMaxGiven :1; unsigned BSIM4vbdMaxGiven :1; + unsigned BSIM4vgsrMaxGiven :1; + unsigned BSIM4vgdrMaxGiven :1; + unsigned BSIM4vgbrMaxGiven :1; + unsigned BSIM4vbsrMaxGiven :1; + unsigned BSIM4vbdrMaxGiven :1; unsigned BSIM4LintGiven :1; unsigned BSIM4LlGiven :1; @@ -3799,12 +3809,17 @@ typedef struct sBSIM4model #define BSIM4_MOD_TNOIC 1272 #define BSIM4_MOD_RNOIC 1273 -#define BSIM4_MOD_VGS_MAX 1301 -#define BSIM4_MOD_VGD_MAX 1302 -#define BSIM4_MOD_VGB_MAX 1303 -#define BSIM4_MOD_VDS_MAX 1304 -#define BSIM4_MOD_VBS_MAX 1305 -#define BSIM4_MOD_VBD_MAX 1306 +#define BSIM4_MOD_VGS_MAX 1301 +#define BSIM4_MOD_VGD_MAX 1302 +#define BSIM4_MOD_VGB_MAX 1303 +#define BSIM4_MOD_VDS_MAX 1304 +#define BSIM4_MOD_VBS_MAX 1305 +#define BSIM4_MOD_VBD_MAX 1306 +#define BSIM4_MOD_VGSR_MAX 1307 +#define BSIM4_MOD_VGDR_MAX 1308 +#define BSIM4_MOD_VGBR_MAX 1309 +#define BSIM4_MOD_VBSR_MAX 1310 +#define BSIM4_MOD_VBDR_MAX 1311 #include "bsim4ext.h" diff --git a/src/spicelib/devices/bsim4v5/b4v5.c b/src/spicelib/devices/bsim4v5/b4v5.c index 99ff77a58..686b0f1e8 100644 --- a/src/spicelib/devices/bsim4v5/b4v5.c +++ b/src/spicelib/devices/bsim4v5/b4v5.c @@ -897,6 +897,11 @@ IOP("vgb_max", BSIM4v5_MOD_VGB_MAX, IF_REAL, "maximum voltage G-B branch"), IOP("vds_max", BSIM4v5_MOD_VDS_MAX, IF_REAL, "maximum voltage D-S branch"), IOP("vbs_max", BSIM4v5_MOD_VBS_MAX, IF_REAL, "maximum voltage B-S branch"), IOP("vbd_max", BSIM4v5_MOD_VBD_MAX, IF_REAL, "maximum voltage B-D branch"), +IOP("vgsr_max", BSIM4v5_MOD_VGSR_MAX, IF_REAL, "maximum voltage G-S branch"), +IOP("vgdr_max", BSIM4v5_MOD_VGDR_MAX, IF_REAL, "maximum voltage G-D branch"), +IOP("vgbr_max", BSIM4v5_MOD_VGBR_MAX, IF_REAL, "maximum voltage G-B branch"), +IOP("vbsr_max", BSIM4v5_MOD_VBSR_MAX, IF_REAL, "maximum voltage B-S branch"), +IOP("vbdr_max", BSIM4v5_MOD_VBDR_MAX, IF_REAL, "maximum voltage B-D branch"), IP( "nmos", BSIM4v5_MOD_NMOS, IF_FLAG, "Flag to indicate NMOS"), IP( "pmos", BSIM4v5_MOD_PMOS, IF_FLAG, "Flag to indicate PMOS"), diff --git a/src/spicelib/devices/bsim4v5/b4v5mask.c b/src/spicelib/devices/bsim4v5/b4v5mask.c index 8fc0273ec..421bee27a 100644 --- a/src/spicelib/devices/bsim4v5/b4v5mask.c +++ b/src/spicelib/devices/bsim4v5/b4v5mask.c @@ -2272,6 +2272,21 @@ IFvalue *value) case BSIM4v5_MOD_VBD_MAX: value->rValue = model->BSIM4v5vbdMax; return(OK); + case BSIM4v5_MOD_VGSR_MAX: + value->rValue = model->BSIM4v5vgsrMax; + return(OK); + case BSIM4v5_MOD_VGDR_MAX: + value->rValue = model->BSIM4v5vgdrMax; + return(OK); + case BSIM4v5_MOD_VGBR_MAX: + value->rValue = model->BSIM4v5vgbrMax; + return(OK); + case BSIM4v5_MOD_VBSR_MAX: + value->rValue = model->BSIM4v5vbsrMax; + return(OK); + case BSIM4v5_MOD_VBDR_MAX: + value->rValue = model->BSIM4v5vbdrMax; + return(OK); default: return(E_BADPARM); diff --git a/src/spicelib/devices/bsim4v5/b4v5mpar.c b/src/spicelib/devices/bsim4v5/b4v5mpar.c index eb31e0f94..17f9ec4a6 100644 --- a/src/spicelib/devices/bsim4v5/b4v5mpar.c +++ b/src/spicelib/devices/bsim4v5/b4v5mpar.c @@ -3085,6 +3085,26 @@ GENmodel *inMod) mod->BSIM4v5vbdMax = value->rValue; mod->BSIM4v5vbdMaxGiven = TRUE; break; + case BSIM4v5_MOD_VGSR_MAX: + mod->BSIM4v5vgsrMax = value->rValue; + mod->BSIM4v5vgsrMaxGiven = TRUE; + break; + case BSIM4v5_MOD_VGDR_MAX: + mod->BSIM4v5vgdrMax = value->rValue; + mod->BSIM4v5vgdrMaxGiven = TRUE; + break; + case BSIM4v5_MOD_VGBR_MAX: + mod->BSIM4v5vgbrMax = value->rValue; + mod->BSIM4v5vgbrMaxGiven = TRUE; + break; + case BSIM4v5_MOD_VBSR_MAX: + mod->BSIM4v5vbsrMax = value->rValue; + mod->BSIM4v5vbsrMaxGiven = TRUE; + break; + case BSIM4v5_MOD_VBDR_MAX: + mod->BSIM4v5vbdrMax = value->rValue; + mod->BSIM4v5vbdrMaxGiven = TRUE; + break; case BSIM4v5_MOD_NMOS : if(value->iValue) { diff --git a/src/spicelib/devices/bsim4v5/b4v5set.c b/src/spicelib/devices/bsim4v5/b4v5set.c index a803aa278..ef891b506 100644 --- a/src/spicelib/devices/bsim4v5/b4v5set.c +++ b/src/spicelib/devices/bsim4v5/b4v5set.c @@ -1588,6 +1588,16 @@ BSIM4v5instance **InstArray; model->BSIM4v5vbsMax = 1e99; if (!model->BSIM4v5vbdMaxGiven) model->BSIM4v5vbdMax = 1e99; + if (!model->BSIM4v5vgsrMaxGiven) + model->BSIM4v5vgsrMax = 1e99; + if (!model->BSIM4v5vgdrMaxGiven) + model->BSIM4v5vgdrMax = 1e99; + if (!model->BSIM4v5vgbrMaxGiven) + model->BSIM4v5vgbrMax = 1e99; + if (!model->BSIM4v5vbsrMaxGiven) + model->BSIM4v5vbsrMax = 1e99; + if (!model->BSIM4v5vbdrMaxGiven) + model->BSIM4v5vbdrMax = 1e99; /* stress effect */ if (!model->BSIM4v5sarefGiven) diff --git a/src/spicelib/devices/bsim4v5/b4v5soachk.c b/src/spicelib/devices/bsim4v5/b4v5soachk.c index 0fdda87fd..a9cba44f7 100644 --- a/src/spicelib/devices/bsim4v5/b4v5soachk.c +++ b/src/spicelib/devices/bsim4v5/b4v5soachk.c @@ -37,71 +37,302 @@ BSIM4v5soaCheck(CKTcircuit *ckt, GENmodel *inModel) for (here = model->BSIM4v5instances; here; here = here->BSIM4v5nextInstance) { - vgs = fabs(ckt->CKTrhsOld [here->BSIM4v5gNodePrime] - - ckt->CKTrhsOld [here->BSIM4v5sNodePrime]); + vgs = ckt->CKTrhsOld [here->BSIM4v5gNodePrime] - + ckt->CKTrhsOld [here->BSIM4v5sNodePrime]; - vgd = fabs(ckt->CKTrhsOld [here->BSIM4v5gNodePrime] - - ckt->CKTrhsOld [here->BSIM4v5dNodePrime]); + vgd = ckt->CKTrhsOld [here->BSIM4v5gNodePrime] - + ckt->CKTrhsOld [here->BSIM4v5dNodePrime]; - vgb = fabs(ckt->CKTrhsOld [here->BSIM4v5gNodePrime] - - ckt->CKTrhsOld [here->BSIM4v5bNodePrime]); + vgb = ckt->CKTrhsOld [here->BSIM4v5gNodePrime] - + ckt->CKTrhsOld [here->BSIM4v5bNodePrime]; - vds = fabs(ckt->CKTrhsOld [here->BSIM4v5dNodePrime] - - ckt->CKTrhsOld [here->BSIM4v5sNodePrime]); + vds = ckt->CKTrhsOld [here->BSIM4v5dNodePrime] - + ckt->CKTrhsOld [here->BSIM4v5sNodePrime]; - vbs = fabs(ckt->CKTrhsOld [here->BSIM4v5bNodePrime] - - ckt->CKTrhsOld [here->BSIM4v5sNodePrime]); + vbs = ckt->CKTrhsOld [here->BSIM4v5bNodePrime] - + ckt->CKTrhsOld [here->BSIM4v5sNodePrime]; - vbd = fabs(ckt->CKTrhsOld [here->BSIM4v5bNodePrime] - - ckt->CKTrhsOld [here->BSIM4v5dNodePrime]); + vbd = ckt->CKTrhsOld [here->BSIM4v5bNodePrime] - + ckt->CKTrhsOld [here->BSIM4v5dNodePrime]; - if (vgs > model->BSIM4v5vgsMax) - if (warns_vgs < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgs|=%g has exceeded Vgs_max=%g\n", - vgs, model->BSIM4v5vgsMax); - warns_vgs++; + if (!model->BSIM4v5vgsrMaxGiven) { + if (fabs(vgs) > model->BSIM4v5vgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->BSIM4v5vgsMax); + warns_vgs++; + } + if (!model->BSIM4v5vgbMaxGiven) { + if (fabs(vgb) > model->BSIM4v5vgsMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgs_max=%g\n", + vgb, model->BSIM4v5vgsMax); + warns_vgb++; + } + } else { + if (fabs(vgb) > model->BSIM4v5vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->BSIM4v5vgbMax); + warns_vgb++; + } } - - if (vgd > model->BSIM4v5vgdMax) - if (warns_vgd < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgd|=%g has exceeded Vgd_max=%g\n", - vgd, model->BSIM4v5vgdMax); - warns_vgd++; + } else { + if (model->BSIM4v5type > 0) { + if (vgs > model->BSIM4v5vgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->BSIM4v5vgsMax); + warns_vgs++; + } + if (-1*vgs > model->BSIM4v5vgsrMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgsr_max=%g\n", + vgs, model->BSIM4v5vgsrMax); + warns_vgs++; + } + } else { + if (vgs > model->BSIM4v5vgsrMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgsr_max=%g\n", + vgs, model->BSIM4v5vgsrMax); + warns_vgs++; + } + if (-1*vgs > model->BSIM4v5vgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->BSIM4v5vgsMax); + warns_vgs++; + } } + } - if (vgb > model->BSIM4v5vgbMax) - if (warns_vgb < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgb|=%g has exceeded Vgb_max=%g\n", - vgb, model->BSIM4v5vgbMax); - warns_vgb++; + if (!model->BSIM4v5vgdrMaxGiven) { + if (fabs(vgd) > model->BSIM4v5vgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->BSIM4v5vgdMax); + warns_vgd++; + } + } else { + if (model->BSIM4v5type > 0) { + if (vgd > model->BSIM4v5vgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->BSIM4v5vgdMax); + warns_vgd++; + } + if (-1*vgd > model->BSIM4v5vgdrMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgdr_max=%g\n", + vgd, model->BSIM4v5vgdrMax); + warns_vgd++; + } + } else { + if (vgd > model->BSIM4v5vgdrMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgdr_max=%g\n", + vgd, model->BSIM4v5vgdrMax); + warns_vgd++; + } + if (-1*vgd > model->BSIM4v5vgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->BSIM4v5vgdMax); + warns_vgd++; + } } + } - if (vds > model->BSIM4v5vdsMax) + if (fabs(vds) > model->BSIM4v5vdsMax) if (warns_vds < maxwarns) { soa_printf(ckt, (GENinstance*) here, - "|Vds|=%g has exceeded Vds_max=%g\n", + "Vds=%g has exceeded Vds_max=%g\n", vds, model->BSIM4v5vdsMax); warns_vds++; } - if (vbs > model->BSIM4v5vbsMax) - if (warns_vbs < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vbs|=%g has exceeded Vbs_max=%g\n", - vbs, model->BSIM4v5vbsMax); - warns_vbs++; + if (!model->BSIM4v5vgbrMaxGiven) { + if (fabs(vgb) > model->BSIM4v5vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->BSIM4v5vgbMax); + warns_vgb++; + } + } else { + if (model->BSIM4v5type > 0) { + if (vgb > model->BSIM4v5vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->BSIM4v5vgbMax); + warns_vgb++; + } + if (-1*vgb > model->BSIM4v5vgbrMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgbr_max=%g\n", + vgb, model->BSIM4v5vgbrMax); + warns_vgb++; + } + } else { + if (vgb > model->BSIM4v5vgbrMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgbr_max=%g\n", + vgb, model->BSIM4v5vgbrMax); + warns_vgb++; + } + if (-1*vgb > model->BSIM4v5vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->BSIM4v5vgbMax); + warns_vgb++; + } } + } - if (vbd > model->BSIM4v5vbdMax) - if (warns_vbd < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vbd|=%g has exceeded Vbd_max=%g\n", - vbd, model->BSIM4v5vbdMax); - warns_vbd++; + if (!model->BSIM4v5vbsrMaxGiven) { + if (!model->BSIM4v5vbsMaxGiven) { + if (fabs(vbs) > model->BSIM4v5vbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->BSIM4v5vbdMax); + warns_vbs++; + } + } else { + if (fabs(vbs) > model->BSIM4v5vbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->BSIM4v5vbsMax); + warns_vbs++; + } + } + } else { + if (!model->BSIM4v5vbsMaxGiven) { + if (model->BSIM4v5type > 0) { + if (vbs > model->BSIM4v5vbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->BSIM4v5vbdMax); + warns_vbs++; + } + if (-1*vbs > model->BSIM4v5vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->BSIM4v5vbsrMax); + warns_vbs++; + } + } else { + if (vbs > model->BSIM4v5vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->BSIM4v5vbsrMax); + warns_vbs++; + } + if (-1*vbs > model->BSIM4v5vbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->BSIM4v5vbdMax); + warns_vbs++; + } + } + } else { + if (model->BSIM4v5type > 0) { + if (vbs > model->BSIM4v5vbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->BSIM4v5vbsMax); + warns_vbs++; + } + if (-1*vbs > model->BSIM4v5vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->BSIM4v5vbsrMax); + warns_vbs++; + } + } else { + if (vbs > model->BSIM4v5vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->BSIM4v5vbsrMax); + warns_vbs++; + } + if (-1*vbs > model->BSIM4v5vbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->BSIM4v5vbsMax); + warns_vbs++; + } + } + } + } + + if (!model->BSIM4v5vbdrMaxGiven) { + if (fabs(vbd) > model->BSIM4v5vbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->BSIM4v5vbdMax); + warns_vbd++; + } + } else { + if (model->BSIM4v5type > 0) { + if (vbd > model->BSIM4v5vbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->BSIM4v5vbdMax); + warns_vbd++; + } + if (-1*vbd > model->BSIM4v5vbdrMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbdr_max=%g\n", + vbd, model->BSIM4v5vbdrMax); + warns_vbd++; + } + } else { + if (vbd > model->BSIM4v5vbdrMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbdr_max=%g\n", + vbd, model->BSIM4v5vbdrMax); + warns_vbd++; + } + if (-1*vbd > model->BSIM4v5vbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->BSIM4v5vbdMax); + warns_vbd++; + } } + } } } diff --git a/src/spicelib/devices/bsim4v5/bsim4v5def.h b/src/spicelib/devices/bsim4v5/bsim4v5def.h index b860ef18d..c40d70ba2 100644 --- a/src/spicelib/devices/bsim4v5/bsim4v5def.h +++ b/src/spicelib/devices/bsim4v5/bsim4v5def.h @@ -1598,6 +1598,11 @@ typedef struct sBSIM4v5model double BSIM4v5vdsMax; double BSIM4v5vbsMax; double BSIM4v5vbdMax; + double BSIM4v5vgsrMax; + double BSIM4v5vgdrMax; + double BSIM4v5vgbrMax; + double BSIM4v5vbsrMax; + double BSIM4v5vbdrMax; struct bsim4v5SizeDependParam *pSizeDependParamKnot; @@ -2332,6 +2337,11 @@ typedef struct sBSIM4v5model unsigned BSIM4v5vdsMaxGiven :1; unsigned BSIM4v5vbsMaxGiven :1; unsigned BSIM4v5vbdMaxGiven :1; + unsigned BSIM4v5vgsrMaxGiven :1; + unsigned BSIM4v5vgdrMaxGiven :1; + unsigned BSIM4v5vgbrMaxGiven :1; + unsigned BSIM4v5vbsrMaxGiven :1; + unsigned BSIM4v5vbdrMaxGiven :1; unsigned BSIM4v5LintGiven :1; unsigned BSIM4v5LlGiven :1; @@ -3305,12 +3315,17 @@ typedef struct sBSIM4v5model #define BSIM4v5_MOD_RBSDBYW 1125 #define BSIM4v5_MOD_RBSDBYNF 1126 -#define BSIM4v5_MOD_VGS_MAX 1201 -#define BSIM4v5_MOD_VGD_MAX 1202 -#define BSIM4v5_MOD_VGB_MAX 1203 -#define BSIM4v5_MOD_VDS_MAX 1204 -#define BSIM4v5_MOD_VBS_MAX 1205 -#define BSIM4v5_MOD_VBD_MAX 1206 +#define BSIM4v5_MOD_VGS_MAX 1201 +#define BSIM4v5_MOD_VGD_MAX 1202 +#define BSIM4v5_MOD_VGB_MAX 1203 +#define BSIM4v5_MOD_VDS_MAX 1204 +#define BSIM4v5_MOD_VBS_MAX 1205 +#define BSIM4v5_MOD_VBD_MAX 1206 +#define BSIM4v5_MOD_VGSR_MAX 1207 +#define BSIM4v5_MOD_VGDR_MAX 1208 +#define BSIM4v5_MOD_VGBR_MAX 1209 +#define BSIM4v5_MOD_VBSR_MAX 1210 +#define BSIM4v5_MOD_VBDR_MAX 1211 #include "bsim4v5ext.h" diff --git a/src/spicelib/devices/bsim4v6/b4v6.c b/src/spicelib/devices/bsim4v6/b4v6.c index 3860bc60a..87c6b2928 100644 --- a/src/spicelib/devices/bsim4v6/b4v6.c +++ b/src/spicelib/devices/bsim4v6/b4v6.c @@ -981,6 +981,11 @@ IOP("vgb_max", BSIM4v6_MOD_VGB_MAX, IF_REAL, "maximum voltage G-B branch"), IOP("vds_max", BSIM4v6_MOD_VDS_MAX, IF_REAL, "maximum voltage D-S branch"), IOP("vbs_max", BSIM4v6_MOD_VBS_MAX, IF_REAL, "maximum voltage B-S branch"), IOP("vbd_max", BSIM4v6_MOD_VBD_MAX, IF_REAL, "maximum voltage B-D branch"), +IOP("vgsr_max", BSIM4v6_MOD_VGSR_MAX, IF_REAL, "maximum voltage G-S branch"), +IOP("vgdr_max", BSIM4v6_MOD_VGDR_MAX, IF_REAL, "maximum voltage G-D branch"), +IOP("vgbr_max", BSIM4v6_MOD_VGBR_MAX, IF_REAL, "maximum voltage G-B branch"), +IOP("vbsr_max", BSIM4v6_MOD_VBSR_MAX, IF_REAL, "maximum voltage B-S branch"), +IOP("vbdr_max", BSIM4v6_MOD_VBDR_MAX, IF_REAL, "maximum voltage B-D branch"), IP( "nmos", BSIM4v6_MOD_NMOS, IF_FLAG, "Flag to indicate NMOS"), IP( "pmos", BSIM4v6_MOD_PMOS, IF_FLAG, "Flag to indicate PMOS"), diff --git a/src/spicelib/devices/bsim4v6/b4v6mask.c b/src/spicelib/devices/bsim4v6/b4v6mask.c index 72175e747..73568c658 100644 --- a/src/spicelib/devices/bsim4v6/b4v6mask.c +++ b/src/spicelib/devices/bsim4v6/b4v6mask.c @@ -2508,6 +2508,21 @@ IFvalue *value) case BSIM4v6_MOD_VBD_MAX: value->rValue = model->BSIM4v6vbdMax; return(OK); + case BSIM4v6_MOD_VGSR_MAX: + value->rValue = model->BSIM4v6vgsrMax; + return(OK); + case BSIM4v6_MOD_VGDR_MAX: + value->rValue = model->BSIM4v6vgdrMax; + return(OK); + case BSIM4v6_MOD_VGBR_MAX: + value->rValue = model->BSIM4v6vgbrMax; + return(OK); + case BSIM4v6_MOD_VBSR_MAX: + value->rValue = model->BSIM4v6vbsrMax; + return(OK); + case BSIM4v6_MOD_VBDR_MAX: + value->rValue = model->BSIM4v6vbdrMax; + return(OK); default: return(E_BADPARM); diff --git a/src/spicelib/devices/bsim4v6/b4v6mpar.c b/src/spicelib/devices/bsim4v6/b4v6mpar.c index 25faa22d8..b1babc1f4 100644 --- a/src/spicelib/devices/bsim4v6/b4v6mpar.c +++ b/src/spicelib/devices/bsim4v6/b4v6mpar.c @@ -3401,6 +3401,26 @@ GENmodel *inMod) mod->BSIM4v6vbdMax = value->rValue; mod->BSIM4v6vbdMaxGiven = TRUE; break; + case BSIM4v6_MOD_VGSR_MAX: + mod->BSIM4v6vgsrMax = value->rValue; + mod->BSIM4v6vgsrMaxGiven = TRUE; + break; + case BSIM4v6_MOD_VGDR_MAX: + mod->BSIM4v6vgdrMax = value->rValue; + mod->BSIM4v6vgdrMaxGiven = TRUE; + break; + case BSIM4v6_MOD_VGBR_MAX: + mod->BSIM4v6vgbrMax = value->rValue; + mod->BSIM4v6vgbrMaxGiven = TRUE; + break; + case BSIM4v6_MOD_VBSR_MAX: + mod->BSIM4v6vbsrMax = value->rValue; + mod->BSIM4v6vbsrMaxGiven = TRUE; + break; + case BSIM4v6_MOD_VBDR_MAX: + mod->BSIM4v6vbdrMax = value->rValue; + mod->BSIM4v6vbdrMaxGiven = TRUE; + break; case BSIM4v6_MOD_NMOS : if(value->iValue) { diff --git a/src/spicelib/devices/bsim4v6/b4v6set.c b/src/spicelib/devices/bsim4v6/b4v6set.c index f009e7c91..33b6460f2 100644 --- a/src/spicelib/devices/bsim4v6/b4v6set.c +++ b/src/spicelib/devices/bsim4v6/b4v6set.c @@ -1949,6 +1949,16 @@ BSIM4v6instance **InstArray; model->BSIM4v6vbsMax = 1e99; if (!model->BSIM4v6vbdMaxGiven) model->BSIM4v6vbdMax = 1e99; + if (!model->BSIM4v6vgsrMaxGiven) + model->BSIM4v6vgsrMax = 1e99; + if (!model->BSIM4v6vgdrMaxGiven) + model->BSIM4v6vgdrMax = 1e99; + if (!model->BSIM4v6vgbrMaxGiven) + model->BSIM4v6vgbrMax = 1e99; + if (!model->BSIM4v6vbsrMaxGiven) + model->BSIM4v6vbsrMax = 1e99; + if (!model->BSIM4v6vbdrMaxGiven) + model->BSIM4v6vbdrMax = 1e99; /* stress effect */ if (!model->BSIM4v6sarefGiven) diff --git a/src/spicelib/devices/bsim4v6/b4v6soachk.c b/src/spicelib/devices/bsim4v6/b4v6soachk.c index 69dc14a07..9b71b2705 100644 --- a/src/spicelib/devices/bsim4v6/b4v6soachk.c +++ b/src/spicelib/devices/bsim4v6/b4v6soachk.c @@ -37,71 +37,302 @@ BSIM4v6soaCheck(CKTcircuit *ckt, GENmodel *inModel) for (here = model->BSIM4v6instances; here; here = here->BSIM4v6nextInstance) { - vgs = fabs(ckt->CKTrhsOld [here->BSIM4v6gNodePrime] - - ckt->CKTrhsOld [here->BSIM4v6sNodePrime]); + vgs = ckt->CKTrhsOld [here->BSIM4v6gNodePrime] - + ckt->CKTrhsOld [here->BSIM4v6sNodePrime]; - vgd = fabs(ckt->CKTrhsOld [here->BSIM4v6gNodePrime] - - ckt->CKTrhsOld [here->BSIM4v6dNodePrime]); + vgd = ckt->CKTrhsOld [here->BSIM4v6gNodePrime] - + ckt->CKTrhsOld [here->BSIM4v6dNodePrime]; - vgb = fabs(ckt->CKTrhsOld [here->BSIM4v6gNodePrime] - - ckt->CKTrhsOld [here->BSIM4v6bNodePrime]); + vgb = ckt->CKTrhsOld [here->BSIM4v6gNodePrime] - + ckt->CKTrhsOld [here->BSIM4v6bNodePrime]; - vds = fabs(ckt->CKTrhsOld [here->BSIM4v6dNodePrime] - - ckt->CKTrhsOld [here->BSIM4v6sNodePrime]); + vds = ckt->CKTrhsOld [here->BSIM4v6dNodePrime] - + ckt->CKTrhsOld [here->BSIM4v6sNodePrime]; - vbs = fabs(ckt->CKTrhsOld [here->BSIM4v6bNodePrime] - - ckt->CKTrhsOld [here->BSIM4v6sNodePrime]); + vbs = ckt->CKTrhsOld [here->BSIM4v6bNodePrime] - + ckt->CKTrhsOld [here->BSIM4v6sNodePrime]; - vbd = fabs(ckt->CKTrhsOld [here->BSIM4v6bNodePrime] - - ckt->CKTrhsOld [here->BSIM4v6dNodePrime]); + vbd = ckt->CKTrhsOld [here->BSIM4v6bNodePrime] - + ckt->CKTrhsOld [here->BSIM4v6dNodePrime]; - if (vgs > model->BSIM4v6vgsMax) - if (warns_vgs < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgs|=%g has exceeded Vgs_max=%g\n", - vgs, model->BSIM4v6vgsMax); - warns_vgs++; + if (!model->BSIM4v6vgsrMaxGiven) { + if (fabs(vgs) > model->BSIM4v6vgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->BSIM4v6vgsMax); + warns_vgs++; + } + if (!model->BSIM4v6vgbMaxGiven) { + if (fabs(vgb) > model->BSIM4v6vgsMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgs_max=%g\n", + vgb, model->BSIM4v6vgsMax); + warns_vgb++; + } + } else { + if (fabs(vgb) > model->BSIM4v6vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->BSIM4v6vgbMax); + warns_vgb++; + } } - - if (vgd > model->BSIM4v6vgdMax) - if (warns_vgd < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgd|=%g has exceeded Vgd_max=%g\n", - vgd, model->BSIM4v6vgdMax); - warns_vgd++; + } else { + if (model->BSIM4v6type > 0) { + if (vgs > model->BSIM4v6vgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->BSIM4v6vgsMax); + warns_vgs++; + } + if (-1*vgs > model->BSIM4v6vgsrMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgsr_max=%g\n", + vgs, model->BSIM4v6vgsrMax); + warns_vgs++; + } + } else { + if (vgs > model->BSIM4v6vgsrMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgsr_max=%g\n", + vgs, model->BSIM4v6vgsrMax); + warns_vgs++; + } + if (-1*vgs > model->BSIM4v6vgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->BSIM4v6vgsMax); + warns_vgs++; + } } + } - if (vgb > model->BSIM4v6vgbMax) - if (warns_vgb < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgb|=%g has exceeded Vgb_max=%g\n", - vgb, model->BSIM4v6vgbMax); - warns_vgb++; + if (!model->BSIM4v6vgdrMaxGiven) { + if (fabs(vgd) > model->BSIM4v6vgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->BSIM4v6vgdMax); + warns_vgd++; + } + } else { + if (model->BSIM4v6type > 0) { + if (vgd > model->BSIM4v6vgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->BSIM4v6vgdMax); + warns_vgd++; + } + if (-1*vgd > model->BSIM4v6vgdrMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgdr_max=%g\n", + vgd, model->BSIM4v6vgdrMax); + warns_vgd++; + } + } else { + if (vgd > model->BSIM4v6vgdrMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgdr_max=%g\n", + vgd, model->BSIM4v6vgdrMax); + warns_vgd++; + } + if (-1*vgd > model->BSIM4v6vgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->BSIM4v6vgdMax); + warns_vgd++; + } } + } - if (vds > model->BSIM4v6vdsMax) + if (fabs(vds) > model->BSIM4v6vdsMax) if (warns_vds < maxwarns) { soa_printf(ckt, (GENinstance*) here, - "|Vds|=%g has exceeded Vds_max=%g\n", + "Vds=%g has exceeded Vds_max=%g\n", vds, model->BSIM4v6vdsMax); warns_vds++; } - if (vbs > model->BSIM4v6vbsMax) - if (warns_vbs < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vbs|=%g has exceeded Vbs_max=%g\n", - vbs, model->BSIM4v6vbsMax); - warns_vbs++; + if (!model->BSIM4v6vgbrMaxGiven) { + if (fabs(vgb) > model->BSIM4v6vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->BSIM4v6vgbMax); + warns_vgb++; + } + } else { + if (model->BSIM4v6type > 0) { + if (vgb > model->BSIM4v6vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->BSIM4v6vgbMax); + warns_vgb++; + } + if (-1*vgb > model->BSIM4v6vgbrMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgbr_max=%g\n", + vgb, model->BSIM4v6vgbrMax); + warns_vgb++; + } + } else { + if (vgb > model->BSIM4v6vgbrMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgbr_max=%g\n", + vgb, model->BSIM4v6vgbrMax); + warns_vgb++; + } + if (-1*vgb > model->BSIM4v6vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->BSIM4v6vgbMax); + warns_vgb++; + } } + } - if (vbd > model->BSIM4v6vbdMax) - if (warns_vbd < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vbd|=%g has exceeded Vbd_max=%g\n", - vbd, model->BSIM4v6vbdMax); - warns_vbd++; + if (!model->BSIM4v6vbsrMaxGiven) { + if (!model->BSIM4v6vbsMaxGiven) { + if (fabs(vbs) > model->BSIM4v6vbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->BSIM4v6vbdMax); + warns_vbs++; + } + } else { + if (fabs(vbs) > model->BSIM4v6vbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->BSIM4v6vbsMax); + warns_vbs++; + } + } + } else { + if (!model->BSIM4v6vbsMaxGiven) { + if (model->BSIM4v6type > 0) { + if (vbs > model->BSIM4v6vbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->BSIM4v6vbdMax); + warns_vbs++; + } + if (-1*vbs > model->BSIM4v6vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->BSIM4v6vbsrMax); + warns_vbs++; + } + } else { + if (vbs > model->BSIM4v6vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->BSIM4v6vbsrMax); + warns_vbs++; + } + if (-1*vbs > model->BSIM4v6vbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->BSIM4v6vbdMax); + warns_vbs++; + } + } + } else { + if (model->BSIM4v6type > 0) { + if (vbs > model->BSIM4v6vbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->BSIM4v6vbsMax); + warns_vbs++; + } + if (-1*vbs > model->BSIM4v6vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->BSIM4v6vbsrMax); + warns_vbs++; + } + } else { + if (vbs > model->BSIM4v6vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->BSIM4v6vbsrMax); + warns_vbs++; + } + if (-1*vbs > model->BSIM4v6vbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->BSIM4v6vbsMax); + warns_vbs++; + } + } + } + } + + if (!model->BSIM4v6vbdrMaxGiven) { + if (fabs(vbd) > model->BSIM4v6vbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->BSIM4v6vbdMax); + warns_vbd++; + } + } else { + if (model->BSIM4v6type > 0) { + if (vbd > model->BSIM4v6vbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->BSIM4v6vbdMax); + warns_vbd++; + } + if (-1*vbd > model->BSIM4v6vbdrMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbdr_max=%g\n", + vbd, model->BSIM4v6vbdrMax); + warns_vbd++; + } + } else { + if (vbd > model->BSIM4v6vbdrMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbdr_max=%g\n", + vbd, model->BSIM4v6vbdrMax); + warns_vbd++; + } + if (-1*vbd > model->BSIM4v6vbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->BSIM4v6vbdMax); + warns_vbd++; + } } + } } } diff --git a/src/spicelib/devices/bsim4v6/bsim4v6def.h b/src/spicelib/devices/bsim4v6/bsim4v6def.h index 04a5b776b..a3348f07a 100644 --- a/src/spicelib/devices/bsim4v6/bsim4v6def.h +++ b/src/spicelib/devices/bsim4v6/bsim4v6def.h @@ -1701,6 +1701,11 @@ typedef struct sBSIM4v6model double BSIM4v6vdsMax; double BSIM4v6vbsMax; double BSIM4v6vbdMax; + double BSIM4v6vgsrMax; + double BSIM4v6vgdrMax; + double BSIM4v6vgbrMax; + double BSIM4v6vbsrMax; + double BSIM4v6vbdrMax; struct bsim4v6SizeDependParam *pSizeDependParamKnot; @@ -2509,6 +2514,11 @@ typedef struct sBSIM4v6model unsigned BSIM4v6vdsMaxGiven :1; unsigned BSIM4v6vbsMaxGiven :1; unsigned BSIM4v6vbdMaxGiven :1; + unsigned BSIM4v6vgsrMaxGiven :1; + unsigned BSIM4v6vgdrMaxGiven :1; + unsigned BSIM4v6vgbrMaxGiven :1; + unsigned BSIM4v6vbsrMaxGiven :1; + unsigned BSIM4v6vbdrMaxGiven :1; unsigned BSIM4v6LintGiven :1; unsigned BSIM4v6LlGiven :1; @@ -3569,6 +3579,11 @@ typedef struct sBSIM4v6model #define BSIM4v6_MOD_VDS_MAX 1304 #define BSIM4v6_MOD_VBS_MAX 1305 #define BSIM4v6_MOD_VBD_MAX 1306 +#define BSIM4v6_MOD_VGSR_MAX 1307 +#define BSIM4v6_MOD_VGDR_MAX 1308 +#define BSIM4v6_MOD_VGBR_MAX 1309 +#define BSIM4v6_MOD_VBSR_MAX 1310 +#define BSIM4v6_MOD_VBDR_MAX 1311 #include "bsim4v6ext.h" diff --git a/src/spicelib/devices/bsim4v7/b4v7.c b/src/spicelib/devices/bsim4v7/b4v7.c index 7210dea0b..4e175ca02 100644 --- a/src/spicelib/devices/bsim4v7/b4v7.c +++ b/src/spicelib/devices/bsim4v7/b4v7.c @@ -1039,6 +1039,11 @@ IOP("vgb_max", BSIM4v7_MOD_VGB_MAX, IF_REAL, "maximum voltage G-B branch"), IOP("vds_max", BSIM4v7_MOD_VDS_MAX, IF_REAL, "maximum voltage D-S branch"), IOP("vbs_max", BSIM4v7_MOD_VBS_MAX, IF_REAL, "maximum voltage B-S branch"), IOP("vbd_max", BSIM4v7_MOD_VBD_MAX, IF_REAL, "maximum voltage B-D branch"), +IOP("vgsr_max", BSIM4v7_MOD_VGSR_MAX, IF_REAL, "maximum voltage G-S branch"), +IOP("vgdr_max", BSIM4v7_MOD_VGDR_MAX, IF_REAL, "maximum voltage G-D branch"), +IOP("vgbr_max", BSIM4v7_MOD_VGBR_MAX, IF_REAL, "maximum voltage G-B branch"), +IOP("vbsr_max", BSIM4v7_MOD_VBSR_MAX, IF_REAL, "maximum voltage B-S branch"), +IOP("vbdr_max", BSIM4v7_MOD_VBDR_MAX, IF_REAL, "maximum voltage B-D branch"), IP( "nmos", BSIM4v7_MOD_NMOS, IF_FLAG, "Flag to indicate NMOS"), IP( "pmos", BSIM4v7_MOD_PMOS, IF_FLAG, "Flag to indicate PMOS"), diff --git a/src/spicelib/devices/bsim4v7/b4v7mask.c b/src/spicelib/devices/bsim4v7/b4v7mask.c index 0acdaf4cc..77e160ded 100644 --- a/src/spicelib/devices/bsim4v7/b4v7mask.c +++ b/src/spicelib/devices/bsim4v7/b4v7mask.c @@ -2712,6 +2712,21 @@ IFvalue *value) case BSIM4v7_MOD_VBD_MAX: value->rValue = model->BSIM4v7vbdMax; return(OK); + case BSIM4v7_MOD_VGSR_MAX: + value->rValue = model->BSIM4v7vgsrMax; + return(OK); + case BSIM4v7_MOD_VGDR_MAX: + value->rValue = model->BSIM4v7vgdrMax; + return(OK); + case BSIM4v7_MOD_VGBR_MAX: + value->rValue = model->BSIM4v7vgbrMax; + return(OK); + case BSIM4v7_MOD_VBSR_MAX: + value->rValue = model->BSIM4v7vbsrMax; + return(OK); + case BSIM4v7_MOD_VBDR_MAX: + value->rValue = model->BSIM4v7vbdrMax; + return(OK); default: return(E_BADPARM); diff --git a/src/spicelib/devices/bsim4v7/b4v7mpar.c b/src/spicelib/devices/bsim4v7/b4v7mpar.c index bd9724b22..9d02f775d 100644 --- a/src/spicelib/devices/bsim4v7/b4v7mpar.c +++ b/src/spicelib/devices/bsim4v7/b4v7mpar.c @@ -3627,6 +3627,26 @@ GENmodel *inMod) mod->BSIM4v7vbdMax = value->rValue; mod->BSIM4v7vbdMaxGiven = TRUE; break; + case BSIM4v7_MOD_VGSR_MAX: + mod->BSIM4v7vgsrMax = value->rValue; + mod->BSIM4v7vgsrMaxGiven = TRUE; + break; + case BSIM4v7_MOD_VGDR_MAX: + mod->BSIM4v7vgdrMax = value->rValue; + mod->BSIM4v7vgdrMaxGiven = TRUE; + break; + case BSIM4v7_MOD_VGBR_MAX: + mod->BSIM4v7vgbrMax = value->rValue; + mod->BSIM4v7vgbrMaxGiven = TRUE; + break; + case BSIM4v7_MOD_VBSR_MAX: + mod->BSIM4v7vbsrMax = value->rValue; + mod->BSIM4v7vbsrMaxGiven = TRUE; + break; + case BSIM4v7_MOD_VBDR_MAX: + mod->BSIM4v7vbdrMax = value->rValue; + mod->BSIM4v7vbdrMaxGiven = TRUE; + break; case BSIM4v7_MOD_NMOS : if(value->iValue) { diff --git a/src/spicelib/devices/bsim4v7/b4v7set.c b/src/spicelib/devices/bsim4v7/b4v7set.c index 00d0ea20d..9c2f560f4 100644 --- a/src/spicelib/devices/bsim4v7/b4v7set.c +++ b/src/spicelib/devices/bsim4v7/b4v7set.c @@ -2100,6 +2100,16 @@ BSIM4v7instance **InstArray; model->BSIM4v7vbsMax = 1e99; if (!model->BSIM4v7vbdMaxGiven) model->BSIM4v7vbdMax = 1e99; + if (!model->BSIM4v7vgsrMaxGiven) + model->BSIM4v7vgsrMax = 1e99; + if (!model->BSIM4v7vgdrMaxGiven) + model->BSIM4v7vgdrMax = 1e99; + if (!model->BSIM4v7vgbrMaxGiven) + model->BSIM4v7vgbrMax = 1e99; + if (!model->BSIM4v7vbsrMaxGiven) + model->BSIM4v7vbsrMax = 1e99; + if (!model->BSIM4v7vbdrMaxGiven) + model->BSIM4v7vbdrMax = 1e99; /* stress effect */ if (!model->BSIM4v7sarefGiven) diff --git a/src/spicelib/devices/bsim4v7/b4v7soachk.c b/src/spicelib/devices/bsim4v7/b4v7soachk.c index 9cae237e5..0c327e295 100644 --- a/src/spicelib/devices/bsim4v7/b4v7soachk.c +++ b/src/spicelib/devices/bsim4v7/b4v7soachk.c @@ -37,71 +37,302 @@ BSIM4v7soaCheck(CKTcircuit *ckt, GENmodel *inModel) for (here = model->BSIM4v7instances; here; here = here->BSIM4v7nextInstance) { - vgs = fabs(ckt->CKTrhsOld [here->BSIM4v7gNodePrime] - - ckt->CKTrhsOld [here->BSIM4v7sNodePrime]); + vgs = ckt->CKTrhsOld [here->BSIM4v7gNodePrime] - + ckt->CKTrhsOld [here->BSIM4v7sNodePrime]; - vgd = fabs(ckt->CKTrhsOld [here->BSIM4v7gNodePrime] - - ckt->CKTrhsOld [here->BSIM4v7dNodePrime]); + vgd = ckt->CKTrhsOld [here->BSIM4v7gNodePrime] - + ckt->CKTrhsOld [here->BSIM4v7dNodePrime]; - vgb = fabs(ckt->CKTrhsOld [here->BSIM4v7gNodePrime] - - ckt->CKTrhsOld [here->BSIM4v7bNodePrime]); + vgb = ckt->CKTrhsOld [here->BSIM4v7gNodePrime] - + ckt->CKTrhsOld [here->BSIM4v7bNodePrime]; - vds = fabs(ckt->CKTrhsOld [here->BSIM4v7dNodePrime] - - ckt->CKTrhsOld [here->BSIM4v7sNodePrime]); + vds = ckt->CKTrhsOld [here->BSIM4v7dNodePrime] - + ckt->CKTrhsOld [here->BSIM4v7sNodePrime]; - vbs = fabs(ckt->CKTrhsOld [here->BSIM4v7bNodePrime] - - ckt->CKTrhsOld [here->BSIM4v7sNodePrime]); + vbs = ckt->CKTrhsOld [here->BSIM4v7bNodePrime] - + ckt->CKTrhsOld [here->BSIM4v7sNodePrime]; - vbd = fabs(ckt->CKTrhsOld [here->BSIM4v7bNodePrime] - - ckt->CKTrhsOld [here->BSIM4v7dNodePrime]); + vbd = ckt->CKTrhsOld [here->BSIM4v7bNodePrime] - + ckt->CKTrhsOld [here->BSIM4v7dNodePrime]; - if (vgs > model->BSIM4v7vgsMax) - if (warns_vgs < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgs|=%g has exceeded Vgs_max=%g\n", - vgs, model->BSIM4v7vgsMax); - warns_vgs++; + if (!model->BSIM4v7vgsrMaxGiven) { + if (fabs(vgs) > model->BSIM4v7vgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->BSIM4v7vgsMax); + warns_vgs++; + } + if (!model->BSIM4v7vgbMaxGiven) { + if (fabs(vgb) > model->BSIM4v7vgsMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgs_max=%g\n", + vgb, model->BSIM4v7vgsMax); + warns_vgb++; + } + } else { + if (fabs(vgb) > model->BSIM4v7vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->BSIM4v7vgbMax); + warns_vgb++; + } } - - if (vgd > model->BSIM4v7vgdMax) - if (warns_vgd < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgd|=%g has exceeded Vgd_max=%g\n", - vgd, model->BSIM4v7vgdMax); - warns_vgd++; + } else { + if (model->BSIM4v7type > 0) { + if (vgs > model->BSIM4v7vgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->BSIM4v7vgsMax); + warns_vgs++; + } + if (-1*vgs > model->BSIM4v7vgsrMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgsr_max=%g\n", + vgs, model->BSIM4v7vgsrMax); + warns_vgs++; + } + } else { + if (vgs > model->BSIM4v7vgsrMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgsr_max=%g\n", + vgs, model->BSIM4v7vgsrMax); + warns_vgs++; + } + if (-1*vgs > model->BSIM4v7vgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->BSIM4v7vgsMax); + warns_vgs++; + } } + } - if (vgb > model->BSIM4v7vgbMax) - if (warns_vgb < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgb|=%g has exceeded Vgb_max=%g\n", - vgb, model->BSIM4v7vgbMax); - warns_vgb++; + if (!model->BSIM4v7vgdrMaxGiven) { + if (fabs(vgd) > model->BSIM4v7vgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->BSIM4v7vgdMax); + warns_vgd++; + } + } else { + if (model->BSIM4v7type > 0) { + if (vgd > model->BSIM4v7vgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->BSIM4v7vgdMax); + warns_vgd++; + } + if (-1*vgd > model->BSIM4v7vgdrMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgdr_max=%g\n", + vgd, model->BSIM4v7vgdrMax); + warns_vgd++; + } + } else { + if (vgd > model->BSIM4v7vgdrMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgdr_max=%g\n", + vgd, model->BSIM4v7vgdrMax); + warns_vgd++; + } + if (-1*vgd > model->BSIM4v7vgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->BSIM4v7vgdMax); + warns_vgd++; + } } + } - if (vds > model->BSIM4v7vdsMax) + if (fabs(vds) > model->BSIM4v7vdsMax) if (warns_vds < maxwarns) { soa_printf(ckt, (GENinstance*) here, - "|Vds|=%g has exceeded Vds_max=%g\n", + "Vds=%g has exceeded Vds_max=%g\n", vds, model->BSIM4v7vdsMax); warns_vds++; } - if (vbs > model->BSIM4v7vbsMax) - if (warns_vbs < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vbs|=%g has exceeded Vbs_max=%g\n", - vbs, model->BSIM4v7vbsMax); - warns_vbs++; + if (!model->BSIM4v7vgbrMaxGiven) { + if (fabs(vgb) > model->BSIM4v7vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->BSIM4v7vgbMax); + warns_vgb++; + } + } else { + if (model->BSIM4v7type > 0) { + if (vgb > model->BSIM4v7vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->BSIM4v7vgbMax); + warns_vgb++; + } + if (-1*vgb > model->BSIM4v7vgbrMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgbr_max=%g\n", + vgb, model->BSIM4v7vgbrMax); + warns_vgb++; + } + } else { + if (vgb > model->BSIM4v7vgbrMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgbr_max=%g\n", + vgb, model->BSIM4v7vgbrMax); + warns_vgb++; + } + if (-1*vgb > model->BSIM4v7vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->BSIM4v7vgbMax); + warns_vgb++; + } } + } - if (vbd > model->BSIM4v7vbdMax) - if (warns_vbd < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vbd|=%g has exceeded Vbd_max=%g\n", - vbd, model->BSIM4v7vbdMax); - warns_vbd++; + if (!model->BSIM4v7vbsrMaxGiven) { + if (!model->BSIM4v7vbsMaxGiven) { + if (fabs(vbs) > model->BSIM4v7vbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->BSIM4v7vbdMax); + warns_vbs++; + } + } else { + if (fabs(vbs) > model->BSIM4v7vbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->BSIM4v7vbsMax); + warns_vbs++; + } + } + } else { + if (!model->BSIM4v7vbsMaxGiven) { + if (model->BSIM4v7type > 0) { + if (vbs > model->BSIM4v7vbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->BSIM4v7vbdMax); + warns_vbs++; + } + if (-1*vbs > model->BSIM4v7vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->BSIM4v7vbsrMax); + warns_vbs++; + } + } else { + if (vbs > model->BSIM4v7vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->BSIM4v7vbsrMax); + warns_vbs++; + } + if (-1*vbs > model->BSIM4v7vbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->BSIM4v7vbdMax); + warns_vbs++; + } + } + } else { + if (model->BSIM4v7type > 0) { + if (vbs > model->BSIM4v7vbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->BSIM4v7vbsMax); + warns_vbs++; + } + if (-1*vbs > model->BSIM4v7vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->BSIM4v7vbsrMax); + warns_vbs++; + } + } else { + if (vbs > model->BSIM4v7vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->BSIM4v7vbsrMax); + warns_vbs++; + } + if (-1*vbs > model->BSIM4v7vbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->BSIM4v7vbsMax); + warns_vbs++; + } + } + } + } + + if (!model->BSIM4v7vbdrMaxGiven) { + if (fabs(vbd) > model->BSIM4v7vbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->BSIM4v7vbdMax); + warns_vbd++; + } + } else { + if (model->BSIM4v7type > 0) { + if (vbd > model->BSIM4v7vbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->BSIM4v7vbdMax); + warns_vbd++; + } + if (-1*vbd > model->BSIM4v7vbdrMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbdr_max=%g\n", + vbd, model->BSIM4v7vbdrMax); + warns_vbd++; + } + } else { + if (vbd > model->BSIM4v7vbdrMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbdr_max=%g\n", + vbd, model->BSIM4v7vbdrMax); + warns_vbd++; + } + if (-1*vbd > model->BSIM4v7vbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->BSIM4v7vbdMax); + warns_vbd++; + } } + } } } diff --git a/src/spicelib/devices/bsim4v7/bsim4v7def.h b/src/spicelib/devices/bsim4v7/bsim4v7def.h index 8ca3d86a4..469172445 100644 --- a/src/spicelib/devices/bsim4v7/bsim4v7def.h +++ b/src/spicelib/devices/bsim4v7/bsim4v7def.h @@ -1775,6 +1775,11 @@ typedef struct sBSIM4v7model double BSIM4v7vdsMax; double BSIM4v7vbsMax; double BSIM4v7vbdMax; + double BSIM4v7vgsrMax; + double BSIM4v7vgdrMax; + double BSIM4v7vgbrMax; + double BSIM4v7vbsrMax; + double BSIM4v7vbdrMax; struct bsim4SizeDependParam *pSizeDependParamKnot; @@ -2638,6 +2643,11 @@ typedef struct sBSIM4v7model unsigned BSIM4v7vdsMaxGiven :1; unsigned BSIM4v7vbsMaxGiven :1; unsigned BSIM4v7vbdMaxGiven :1; + unsigned BSIM4v7vgsrMaxGiven :1; + unsigned BSIM4v7vgdrMaxGiven :1; + unsigned BSIM4v7vgbrMaxGiven :1; + unsigned BSIM4v7vbsrMaxGiven :1; + unsigned BSIM4v7vbdrMaxGiven :1; unsigned BSIM4v7LintGiven :1; unsigned BSIM4v7LlGiven :1; @@ -3755,12 +3765,17 @@ typedef struct sBSIM4v7model #define BSIM4v7_MOD_TNOIC 1272 #define BSIM4v7_MOD_RNOIC 1273 -#define BSIM4v7_MOD_VGS_MAX 1301 -#define BSIM4v7_MOD_VGD_MAX 1302 -#define BSIM4v7_MOD_VGB_MAX 1303 -#define BSIM4v7_MOD_VDS_MAX 1304 -#define BSIM4v7_MOD_VBS_MAX 1305 -#define BSIM4v7_MOD_VBD_MAX 1306 +#define BSIM4v7_MOD_VGS_MAX 1301 +#define BSIM4v7_MOD_VGD_MAX 1302 +#define BSIM4v7_MOD_VGB_MAX 1303 +#define BSIM4v7_MOD_VDS_MAX 1304 +#define BSIM4v7_MOD_VBS_MAX 1305 +#define BSIM4v7_MOD_VBD_MAX 1306 +#define BSIM4v7_MOD_VGSR_MAX 1307 +#define BSIM4v7_MOD_VGDR_MAX 1308 +#define BSIM4v7_MOD_VGBR_MAX 1309 +#define BSIM4v7_MOD_VBSR_MAX 1310 +#define BSIM4v7_MOD_VBDR_MAX 1311 #include "bsim4v7ext.h" diff --git a/src/spicelib/devices/bsimsoi/b4soi.c b/src/spicelib/devices/bsimsoi/b4soi.c index e131b50b9..d2e5c64fb 100644 --- a/src/spicelib/devices/bsimsoi/b4soi.c +++ b/src/spicelib/devices/bsimsoi/b4soi.c @@ -1109,6 +1109,11 @@ IOP("vgb_max", B4SOI_MOD_VGB_MAX, IF_REAL, "maximum voltage G-B branch"), IOP("vds_max", B4SOI_MOD_VDS_MAX, IF_REAL, "maximum voltage D-S branch"), IOP("vbs_max", B4SOI_MOD_VBS_MAX, IF_REAL, "maximum voltage B-S branch"), IOP("vbd_max", B4SOI_MOD_VBD_MAX, IF_REAL, "maximum voltage B-D branch"), +IOP("vgsr_max", B4SOI_MOD_VGSR_MAX, IF_REAL, "maximum voltage G-S branch"), +IOP("vgdr_max", B4SOI_MOD_VGDR_MAX, IF_REAL, "maximum voltage G-D branch"), +IOP("vgbr_max", B4SOI_MOD_VGBR_MAX, IF_REAL, "maximum voltage G-B branch"), +IOP("vbsr_max", B4SOI_MOD_VBSR_MAX, IF_REAL, "maximum voltage B-S branch"), +IOP("vbdr_max", B4SOI_MOD_VBDR_MAX, IF_REAL, "maximum voltage B-D branch"), IP( "nmos", B4SOI_MOD_NMOS, IF_FLAG, "Flag to indicate NMOS"), IP( "pmos", B4SOI_MOD_PMOS, IF_FLAG, "Flag to indicate PMOS"), diff --git a/src/spicelib/devices/bsimsoi/b4soidef.h b/src/spicelib/devices/bsimsoi/b4soidef.h index 8ebb90ada..2c0be8af5 100644 --- a/src/spicelib/devices/bsimsoi/b4soidef.h +++ b/src/spicelib/devices/bsimsoi/b4soidef.h @@ -2116,12 +2116,22 @@ typedef struct sB4SOImodel double B4SOIvdsMax; double B4SOIvbsMax; double B4SOIvbdMax; + double B4SOIvgsrMax; + double B4SOIvgdrMax; + double B4SOIvgbrMax; + double B4SOIvbsrMax; + double B4SOIvbdrMax; unsigned B4SOIvgsMaxGiven :1; unsigned B4SOIvgdMaxGiven :1; unsigned B4SOIvgbMaxGiven :1; unsigned B4SOIvdsMaxGiven :1; unsigned B4SOIvbsMaxGiven :1; unsigned B4SOIvbdMaxGiven :1; + unsigned B4SOIvgsrMaxGiven :1; + unsigned B4SOIvgdrMaxGiven :1; + unsigned B4SOIvgbrMaxGiven :1; + unsigned B4SOIvbsrMaxGiven :1; + unsigned B4SOIvbdrMaxGiven :1; struct b4soiSizeDependParam *pSizeDependParamKnot; @@ -4258,12 +4268,17 @@ typedef struct sB4SOImodel #define B4SOI_MOD_WNLX 2106 #define B4SOI_MOD_PNLX 2107 -#define B4SOI_MOD_VGS_MAX 2201 -#define B4SOI_MOD_VGD_MAX 2202 -#define B4SOI_MOD_VGB_MAX 2203 -#define B4SOI_MOD_VDS_MAX 2204 -#define B4SOI_MOD_VBS_MAX 2205 -#define B4SOI_MOD_VBD_MAX 2206 +#define B4SOI_MOD_VGS_MAX 2201 +#define B4SOI_MOD_VGD_MAX 2202 +#define B4SOI_MOD_VGB_MAX 2203 +#define B4SOI_MOD_VDS_MAX 2204 +#define B4SOI_MOD_VBS_MAX 2205 +#define B4SOI_MOD_VBD_MAX 2206 +#define B4SOI_MOD_VGSR_MAX 2207 +#define B4SOI_MOD_VGDR_MAX 2208 +#define B4SOI_MOD_VGBR_MAX 2209 +#define B4SOI_MOD_VBSR_MAX 2210 +#define B4SOI_MOD_VBDR_MAX 2211 #include "b4soiext.h" diff --git a/src/spicelib/devices/bsimsoi/b4soimask.c b/src/spicelib/devices/bsimsoi/b4soimask.c index fcbdf3d3f..f20989c57 100644 --- a/src/spicelib/devices/bsimsoi/b4soimask.c +++ b/src/spicelib/devices/bsimsoi/b4soimask.c @@ -2818,6 +2818,21 @@ IFvalue *value) case B4SOI_MOD_VBD_MAX: value->rValue = model->B4SOIvbdMax; return(OK); + case B4SOI_MOD_VGSR_MAX: + value->rValue = model->B4SOIvgsrMax; + return(OK); + case B4SOI_MOD_VGDR_MAX: + value->rValue = model->B4SOIvgdrMax; + return(OK); + case B4SOI_MOD_VGBR_MAX: + value->rValue = model->B4SOIvgbrMax; + return(OK); + case B4SOI_MOD_VBSR_MAX: + value->rValue = model->B4SOIvbsrMax; + return(OK); + case B4SOI_MOD_VBDR_MAX: + value->rValue = model->B4SOIvbdrMax; + return(OK); default: return(E_BADPARM); diff --git a/src/spicelib/devices/bsimsoi/b4soimpar.c b/src/spicelib/devices/bsimsoi/b4soimpar.c index bc4294f71..a3adb8309 100644 --- a/src/spicelib/devices/bsimsoi/b4soimpar.c +++ b/src/spicelib/devices/bsimsoi/b4soimpar.c @@ -3783,6 +3783,26 @@ case B4SOI_MOD_UD: mod->B4SOIvbdMax = value->rValue; mod->B4SOIvbdMaxGiven = TRUE; break; + case B4SOI_MOD_VGSR_MAX: + mod->B4SOIvgsrMax = value->rValue; + mod->B4SOIvgsrMaxGiven = TRUE; + break; + case B4SOI_MOD_VGDR_MAX: + mod->B4SOIvgdrMax = value->rValue; + mod->B4SOIvgdrMaxGiven = TRUE; + break; + case B4SOI_MOD_VGBR_MAX: + mod->B4SOIvgbrMax = value->rValue; + mod->B4SOIvgbrMaxGiven = TRUE; + break; + case B4SOI_MOD_VBSR_MAX: + mod->B4SOIvbsrMax = value->rValue; + mod->B4SOIvbsrMaxGiven = TRUE; + break; + case B4SOI_MOD_VBDR_MAX: + mod->B4SOIvbdrMax = value->rValue; + mod->B4SOIvbdrMaxGiven = TRUE; + break; case B4SOI_MOD_NMOS : if(value->iValue) { diff --git a/src/spicelib/devices/bsimsoi/b4soiset.c b/src/spicelib/devices/bsimsoi/b4soiset.c index e13d33960..3cd7e5e9e 100644 --- a/src/spicelib/devices/bsimsoi/b4soiset.c +++ b/src/spicelib/devices/bsimsoi/b4soiset.c @@ -2066,6 +2066,16 @@ B4SOIinstance **InstArray; model->B4SOIvbsMax = 1e99; if (!model->B4SOIvbdMaxGiven) model->B4SOIvbdMax = 1e99; + if (!model->B4SOIvgsrMaxGiven) + model->B4SOIvgsrMax = 1e99; + if (!model->B4SOIvgdrMaxGiven) + model->B4SOIvgdrMax = 1e99; + if (!model->B4SOIvgbrMaxGiven) + model->B4SOIvgbrMax = 1e99; + if (!model->B4SOIvbsrMaxGiven) + model->B4SOIvbsrMax = 1e99; + if (!model->B4SOIvbdrMaxGiven) + model->B4SOIvbdrMax = 1e99; if (!model->B4SOIfdModGiven) model->B4SOIfdMod = 0; diff --git a/src/spicelib/devices/bsimsoi/b4soisoachk.c b/src/spicelib/devices/bsimsoi/b4soisoachk.c index dc85fa06e..998afbed0 100644 --- a/src/spicelib/devices/bsimsoi/b4soisoachk.c +++ b/src/spicelib/devices/bsimsoi/b4soisoachk.c @@ -37,71 +37,302 @@ B4SOIsoaCheck(CKTcircuit *ckt, GENmodel *inModel) for (here = model->B4SOIinstances; here; here = here->B4SOInextInstance) { - vgs = fabs(ckt->CKTrhsOld [here->B4SOIgNode] - - ckt->CKTrhsOld [here->B4SOIsNodePrime]); + vgs = ckt->CKTrhsOld [here->B4SOIgNode] - + ckt->CKTrhsOld [here->B4SOIsNodePrime]; - vgd = fabs(ckt->CKTrhsOld [here->B4SOIgNode] - - ckt->CKTrhsOld [here->B4SOIdNodePrime]); + vgd = ckt->CKTrhsOld [here->B4SOIgNode] - + ckt->CKTrhsOld [here->B4SOIdNodePrime]; - vgb = fabs(ckt->CKTrhsOld [here->B4SOIgNode] - - ckt->CKTrhsOld [here->B4SOIbNode]); + vgb = ckt->CKTrhsOld [here->B4SOIgNode] - + ckt->CKTrhsOld [here->B4SOIbNode]; - vds = fabs(ckt->CKTrhsOld [here->B4SOIdNodePrime] - - ckt->CKTrhsOld [here->B4SOIsNodePrime]); + vds = ckt->CKTrhsOld [here->B4SOIdNodePrime] - + ckt->CKTrhsOld [here->B4SOIsNodePrime]; - vbs = fabs(ckt->CKTrhsOld [here->B4SOIbNode] - - ckt->CKTrhsOld [here->B4SOIsNodePrime]); + vbs = ckt->CKTrhsOld [here->B4SOIbNode] - + ckt->CKTrhsOld [here->B4SOIsNodePrime]; - vbd = fabs(ckt->CKTrhsOld [here->B4SOIbNode] - - ckt->CKTrhsOld [here->B4SOIdNodePrime]); + vbd = ckt->CKTrhsOld [here->B4SOIbNode] - + ckt->CKTrhsOld [here->B4SOIdNodePrime]; - if (vgs > model->B4SOIvgsMax) - if (warns_vgs < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgs|=%g has exceeded Vgs_max=%g\n", - vgs, model->B4SOIvgsMax); - warns_vgs++; + if (!model->B4SOIvgsrMaxGiven) { + if (fabs(vgs) > model->B4SOIvgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->B4SOIvgsMax); + warns_vgs++; + } + if (!model->B4SOIvgbMaxGiven) { + if (fabs(vgb) > model->B4SOIvgsMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgs_max=%g\n", + vgb, model->B4SOIvgsMax); + warns_vgb++; + } + } else { + if (fabs(vgb) > model->B4SOIvgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->B4SOIvgbMax); + warns_vgb++; + } } - - if (vgd > model->B4SOIvgdMax) - if (warns_vgd < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgd|=%g has exceeded Vgd_max=%g\n", - vgd, model->B4SOIvgdMax); - warns_vgd++; + } else { + if (model->B4SOItype > 0) { + if (vgs > model->B4SOIvgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->B4SOIvgsMax); + warns_vgs++; + } + if (-1*vgs > model->B4SOIvgsrMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgsr_max=%g\n", + vgs, model->B4SOIvgsrMax); + warns_vgs++; + } + } else { + if (vgs > model->B4SOIvgsrMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgsr_max=%g\n", + vgs, model->B4SOIvgsrMax); + warns_vgs++; + } + if (-1*vgs > model->B4SOIvgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->B4SOIvgsMax); + warns_vgs++; + } } + } - if (vgb > model->B4SOIvgbMax) - if (warns_vgb < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgb|=%g has exceeded Vgb_max=%g\n", - vgb, model->B4SOIvgbMax); - warns_vgb++; + if (!model->B4SOIvgdrMaxGiven) { + if (fabs(vgd) > model->B4SOIvgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->B4SOIvgdMax); + warns_vgd++; + } + } else { + if (model->B4SOItype > 0) { + if (vgd > model->B4SOIvgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->B4SOIvgdMax); + warns_vgd++; + } + if (-1*vgd > model->B4SOIvgdrMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgdr_max=%g\n", + vgd, model->B4SOIvgdrMax); + warns_vgd++; + } + } else { + if (vgd > model->B4SOIvgdrMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgdr_max=%g\n", + vgd, model->B4SOIvgdrMax); + warns_vgd++; + } + if (-1*vgd > model->B4SOIvgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->B4SOIvgdMax); + warns_vgd++; + } } + } - if (vds > model->B4SOIvdsMax) + if (fabs(vds) > model->B4SOIvdsMax) if (warns_vds < maxwarns) { soa_printf(ckt, (GENinstance*) here, - "|Vds|=%g has exceeded Vds_max=%g\n", + "Vds=%g has exceeded Vds_max=%g\n", vds, model->B4SOIvdsMax); warns_vds++; } - if (vbs > model->B4SOIvbsMax) - if (warns_vbs < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vbs|=%g has exceeded Vbs_max=%g\n", - vbs, model->B4SOIvbsMax); - warns_vbs++; + if (!model->B4SOIvgbrMaxGiven) { + if (fabs(vgb) > model->B4SOIvgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->B4SOIvgbMax); + warns_vgb++; + } + } else { + if (model->B4SOItype > 0) { + if (vgb > model->B4SOIvgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->B4SOIvgbMax); + warns_vgb++; + } + if (-1*vgb > model->B4SOIvgbrMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgbr_max=%g\n", + vgb, model->B4SOIvgbrMax); + warns_vgb++; + } + } else { + if (vgb > model->B4SOIvgbrMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgbr_max=%g\n", + vgb, model->B4SOIvgbrMax); + warns_vgb++; + } + if (-1*vgb > model->B4SOIvgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->B4SOIvgbMax); + warns_vgb++; + } } + } - if (vbd > model->B4SOIvbdMax) - if (warns_vbd < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vbd|=%g has exceeded Vbd_max=%g\n", - vbd, model->B4SOIvbdMax); - warns_vbd++; + if (!model->B4SOIvbsrMaxGiven) { + if (!model->B4SOIvbsMaxGiven) { + if (fabs(vbs) > model->B4SOIvbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->B4SOIvbdMax); + warns_vbs++; + } + } else { + if (fabs(vbs) > model->B4SOIvbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->B4SOIvbsMax); + warns_vbs++; + } + } + } else { + if (!model->B4SOIvbsMaxGiven) { + if (model->B4SOItype > 0) { + if (vbs > model->B4SOIvbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->B4SOIvbdMax); + warns_vbs++; + } + if (-1*vbs > model->B4SOIvbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->B4SOIvbsrMax); + warns_vbs++; + } + } else { + if (vbs > model->B4SOIvbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->B4SOIvbsrMax); + warns_vbs++; + } + if (-1*vbs > model->B4SOIvbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->B4SOIvbdMax); + warns_vbs++; + } + } + } else { + if (model->B4SOItype > 0) { + if (vbs > model->B4SOIvbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->B4SOIvbsMax); + warns_vbs++; + } + if (-1*vbs > model->B4SOIvbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->B4SOIvbsrMax); + warns_vbs++; + } + } else { + if (vbs > model->B4SOIvbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->B4SOIvbsrMax); + warns_vbs++; + } + if (-1*vbs > model->B4SOIvbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->B4SOIvbsMax); + warns_vbs++; + } + } + } + } + + if (!model->B4SOIvbdrMaxGiven) { + if (fabs(vbd) > model->B4SOIvbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->B4SOIvbdMax); + warns_vbd++; + } + } else { + if (model->B4SOItype > 0) { + if (vbd > model->B4SOIvbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->B4SOIvbdMax); + warns_vbd++; + } + if (-1*vbd > model->B4SOIvbdrMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbdr_max=%g\n", + vbd, model->B4SOIvbdrMax); + warns_vbd++; + } + } else { + if (vbd > model->B4SOIvbdrMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbdr_max=%g\n", + vbd, model->B4SOIvbdrMax); + warns_vbd++; + } + if (-1*vbd > model->B4SOIvbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->B4SOIvbdMax); + warns_vbd++; + } } + } } } diff --git a/src/spicelib/devices/hisim2/hsm2.c b/src/spicelib/devices/hisim2/hsm2.c index dcb0b679d..59b8b5aa2 100644 --- a/src/spicelib/devices/hisim2/hsm2.c +++ b/src/spicelib/devices/hisim2/hsm2.c @@ -703,7 +703,12 @@ IFparm HSM2mPTable[] = { /* model parameters */ IOP("vgb_max", HSM2_MOD_VGB_MAX, IF_REAL, "maximum voltage G-B branch"), IOP("vds_max", HSM2_MOD_VDS_MAX, IF_REAL, "maximum voltage D-S branch"), IOP("vbs_max", HSM2_MOD_VBS_MAX, IF_REAL, "maximum voltage B-S branch"), - IOP("vbd_max", HSM2_MOD_VBD_MAX, IF_REAL, "maximum voltage B-D branch") + IOP("vbd_max", HSM2_MOD_VBD_MAX, IF_REAL, "maximum voltage B-D branch"), + IOP("vgsr_max", HSM2_MOD_VGSR_MAX, IF_REAL, "maximum voltage G-S branch"), + IOP("vgdr_max", HSM2_MOD_VGDR_MAX, IF_REAL, "maximum voltage G-D branch"), + IOP("vgbr_max", HSM2_MOD_VGBR_MAX, IF_REAL, "maximum voltage G-B branch"), + IOP("vbsr_max", HSM2_MOD_VBSR_MAX, IF_REAL, "maximum voltage B-S branch"), + IOP("vbdr_max", HSM2_MOD_VBDR_MAX, IF_REAL, "maximum voltage B-D branch") }; diff --git a/src/spicelib/devices/hisim2/hsm2def.h b/src/spicelib/devices/hisim2/hsm2def.h index 3a941aaf2..e37320f17 100644 --- a/src/spicelib/devices/hisim2/hsm2def.h +++ b/src/spicelib/devices/hisim2/hsm2def.h @@ -1266,6 +1266,11 @@ typedef struct sHSM2model { /* model structure for a resistor */ double HSM2vdsMax; double HSM2vbsMax; double HSM2vbdMax; + double HSM2vgsrMax; + double HSM2vgdrMax; + double HSM2vgbrMax; + double HSM2vbsrMax; + double HSM2vbdrMax; HSM2modelMKSParam modelMKS ; /* unit-converted parameters */ @@ -1839,6 +1844,11 @@ typedef struct sHSM2model { /* model structure for a resistor */ unsigned HSM2vdsMaxGiven :1; unsigned HSM2vbsMaxGiven :1; unsigned HSM2vbdMaxGiven :1; + unsigned HSM2vgsrMaxGiven :1; + unsigned HSM2vgdrMaxGiven :1; + unsigned HSM2vgbrMaxGiven :1; + unsigned HSM2vbsrMaxGiven :1; + unsigned HSM2vbdrMaxGiven :1; } HSM2model; @@ -2521,6 +2531,11 @@ typedef struct sHSM2model { /* model structure for a resistor */ #define HSM2_MOD_VDS_MAX 4004 #define HSM2_MOD_VBS_MAX 4005 #define HSM2_MOD_VBD_MAX 4006 +#define HSM2_MOD_VGSR_MAX 4007 +#define HSM2_MOD_VGDR_MAX 4008 +#define HSM2_MOD_VGBR_MAX 4009 +#define HSM2_MOD_VBSR_MAX 4010 +#define HSM2_MOD_VBDR_MAX 4011 #include "hsm2ext.h" diff --git a/src/spicelib/devices/hisim2/hsm2mask.c b/src/spicelib/devices/hisim2/hsm2mask.c index c4b45a72c..832747b54 100644 --- a/src/spicelib/devices/hisim2/hsm2mask.c +++ b/src/spicelib/devices/hisim2/hsm2mask.c @@ -1736,6 +1736,21 @@ int HSM2mAsk( case HSM2_MOD_VBD_MAX: value->rValue = model->HSM2vbdMax; return(OK); + case HSM2_MOD_VGSR_MAX: + value->rValue = model->HSM2vgsrMax; + return(OK); + case HSM2_MOD_VGDR_MAX: + value->rValue = model->HSM2vgdrMax; + return(OK); + case HSM2_MOD_VGBR_MAX: + value->rValue = model->HSM2vgbrMax; + return(OK); + case HSM2_MOD_VBSR_MAX: + value->rValue = model->HSM2vbsrMax; + return(OK); + case HSM2_MOD_VBDR_MAX: + value->rValue = model->HSM2vbdrMax; + return(OK); default: return(E_BADPARM); diff --git a/src/spicelib/devices/hisim2/hsm2mpar.c b/src/spicelib/devices/hisim2/hsm2mpar.c index 4657811f2..699ceb13e 100644 --- a/src/spicelib/devices/hisim2/hsm2mpar.c +++ b/src/spicelib/devices/hisim2/hsm2mpar.c @@ -2284,6 +2284,26 @@ int HSM2mParam( mod->HSM2vbdMax = value->rValue; mod->HSM2vbdMaxGiven = TRUE; break; + case HSM2_MOD_VGSR_MAX: + mod->HSM2vgsrMax = value->rValue; + mod->HSM2vgsrMaxGiven = TRUE; + break; + case HSM2_MOD_VGDR_MAX: + mod->HSM2vgdrMax = value->rValue; + mod->HSM2vgdrMaxGiven = TRUE; + break; + case HSM2_MOD_VGBR_MAX: + mod->HSM2vgbrMax = value->rValue; + mod->HSM2vgbrMaxGiven = TRUE; + break; + case HSM2_MOD_VBSR_MAX: + mod->HSM2vbsrMax = value->rValue; + mod->HSM2vbsrMaxGiven = TRUE; + break; + case HSM2_MOD_VBDR_MAX: + mod->HSM2vbdrMax = value->rValue; + mod->HSM2vbdrMaxGiven = TRUE; + break; default: return(E_BADPARM); diff --git a/src/spicelib/devices/hisim2/hsm2set.c b/src/spicelib/devices/hisim2/hsm2set.c index 5f5a2abbd..5aa33bfb7 100644 --- a/src/spicelib/devices/hisim2/hsm2set.c +++ b/src/spicelib/devices/hisim2/hsm2set.c @@ -765,6 +765,11 @@ int HSM2setup( if (!model->HSM2vdsMaxGiven) model->HSM2vdsMax = 1e99; if (!model->HSM2vbsMaxGiven) model->HSM2vbsMax = 1e99; if (!model->HSM2vbdMaxGiven) model->HSM2vbdMax = 1e99; + if (!model->HSM2vgsrMaxGiven) model->HSM2vgsrMax = 1e99; + if (!model->HSM2vgdrMaxGiven) model->HSM2vgdrMax = 1e99; + if (!model->HSM2vgbrMaxGiven) model->HSM2vgbrMax = 1e99; + if (!model->HSM2vbsrMaxGiven) model->HSM2vbsrMax = 1e99; + if (!model->HSM2vbdrMaxGiven) model->HSM2vbdrMax = 1e99; if ( model->HSM2_codep ) { RANGERESET(model->HSM2_ndepm, 5e15, 2e17, "NDEPM" ) ; diff --git a/src/spicelib/devices/hisim2/hsm2soachk.c b/src/spicelib/devices/hisim2/hsm2soachk.c index 9a0d33d38..a7652d810 100644 --- a/src/spicelib/devices/hisim2/hsm2soachk.c +++ b/src/spicelib/devices/hisim2/hsm2soachk.c @@ -37,71 +37,302 @@ HSM2soaCheck(CKTcircuit *ckt, GENmodel *inModel) for (here = model->HSM2instances; here; here = here->HSM2nextInstance) { - vgs = fabs(ckt->CKTrhsOld [here->HSM2gNode] - - ckt->CKTrhsOld [here->HSM2sNodePrime]); + vgs = ckt->CKTrhsOld [here->HSM2gNode] - + ckt->CKTrhsOld [here->HSM2sNodePrime]; - vgd = fabs(ckt->CKTrhsOld [here->HSM2gNode] - - ckt->CKTrhsOld [here->HSM2dNodePrime]); + vgd = ckt->CKTrhsOld [here->HSM2gNode] - + ckt->CKTrhsOld [here->HSM2dNodePrime]; - vgb = fabs(ckt->CKTrhsOld [here->HSM2gNode] - - ckt->CKTrhsOld [here->HSM2bNode]); + vgb = ckt->CKTrhsOld [here->HSM2gNode] - + ckt->CKTrhsOld [here->HSM2bNodePrime]; - vds = fabs(ckt->CKTrhsOld [here->HSM2dNodePrime] - - ckt->CKTrhsOld [here->HSM2sNodePrime]); + vds = ckt->CKTrhsOld [here->HSM2dNode] - + ckt->CKTrhsOld [here->HSM2sNodePrime]; - vbs = fabs(ckt->CKTrhsOld [here->HSM2bNode] - - ckt->CKTrhsOld [here->HSM2sNodePrime]); + vbs = ckt->CKTrhsOld [here->HSM2bNode] - + ckt->CKTrhsOld [here->HSM2sNodePrime]; - vbd = fabs(ckt->CKTrhsOld [here->HSM2bNode] - - ckt->CKTrhsOld [here->HSM2dNodePrime]); + vbd = ckt->CKTrhsOld [here->HSM2bNode] - + ckt->CKTrhsOld [here->HSM2dNodePrime]; - if (vgs > model->HSM2vgsMax) - if (warns_vgs < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgs|=%g has exceeded Vgs_max=%g\n", - vgs, model->HSM2vgsMax); - warns_vgs++; + if (!model->HSM2vgsrMaxGiven) { + if (fabs(vgs) > model->HSM2vgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->HSM2vgsMax); + warns_vgs++; + } + if (!model->HSM2vgbMaxGiven) { + if (fabs(vgb) > model->HSM2vgsMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgs_max=%g\n", + vgb, model->HSM2vgsMax); + warns_vgb++; + } + } else { + if (fabs(vgb) > model->HSM2vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->HSM2vgbMax); + warns_vgb++; + } } - - if (vgd > model->HSM2vgdMax) - if (warns_vgd < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgd|=%g has exceeded Vgd_max=%g\n", - vgd, model->HSM2vgdMax); - warns_vgd++; + } else { + if (model->HSM2_type > 0) { + if (vgs > model->HSM2vgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->HSM2vgsMax); + warns_vgs++; + } + if (-1*vgs > model->HSM2vgsrMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgsr_max=%g\n", + vgs, model->HSM2vgsrMax); + warns_vgs++; + } + } else { + if (vgs > model->HSM2vgsrMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgsr_max=%g\n", + vgs, model->HSM2vgsrMax); + warns_vgs++; + } + if (-1*vgs > model->HSM2vgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->HSM2vgsMax); + warns_vgs++; + } } + } - if (vgb > model->HSM2vgbMax) - if (warns_vgb < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgb|=%g has exceeded Vgb_max=%g\n", - vgb, model->HSM2vgbMax); - warns_vgb++; + if (!model->HSM2vgdrMaxGiven) { + if (fabs(vgd) > model->HSM2vgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->HSM2vgdMax); + warns_vgd++; + } + } else { + if (model->HSM2_type > 0) { + if (vgd > model->HSM2vgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->HSM2vgdMax); + warns_vgd++; + } + if (-1*vgd > model->HSM2vgdrMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgdr_max=%g\n", + vgd, model->HSM2vgdrMax); + warns_vgd++; + } + } else { + if (vgd > model->HSM2vgdrMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgdr_max=%g\n", + vgd, model->HSM2vgdrMax); + warns_vgd++; + } + if (-1*vgd > model->HSM2vgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->HSM2vgdMax); + warns_vgd++; + } } + } - if (vds > model->HSM2vdsMax) + if (fabs(vds) > model->HSM2vdsMax) if (warns_vds < maxwarns) { soa_printf(ckt, (GENinstance*) here, - "|Vds|=%g has exceeded Vds_max=%g\n", + "Vds=%g has exceeded Vds_max=%g\n", vds, model->HSM2vdsMax); warns_vds++; } - if (vbs > model->HSM2vbsMax) - if (warns_vbs < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vbs|=%g has exceeded Vbs_max=%g\n", - vbs, model->HSM2vbsMax); - warns_vbs++; + if (!model->HSM2vgbrMaxGiven) { + if (fabs(vgb) > model->HSM2vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->HSM2vgbMax); + warns_vgb++; + } + } else { + if (model->HSM2_type > 0) { + if (vgb > model->HSM2vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->HSM2vgbMax); + warns_vgb++; + } + if (-1*vgb > model->HSM2vgbrMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgbr_max=%g\n", + vgb, model->HSM2vgbrMax); + warns_vgb++; + } + } else { + if (vgb > model->HSM2vgbrMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgbr_max=%g\n", + vgb, model->HSM2vgbrMax); + warns_vgb++; + } + if (-1*vgb > model->HSM2vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->HSM2vgbMax); + warns_vgb++; + } } + } - if (vbd > model->HSM2vbdMax) - if (warns_vbd < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vbd|=%g has exceeded Vbd_max=%g\n", - vbd, model->HSM2vbdMax); - warns_vbd++; + if (!model->HSM2vbsrMaxGiven) { + if (!model->HSM2vbsMaxGiven) { + if (fabs(vbs) > model->HSM2vbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->HSM2vbdMax); + warns_vbs++; + } + } else { + if (fabs(vbs) > model->HSM2vbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->HSM2vbsMax); + warns_vbs++; + } + } + } else { + if (!model->HSM2vbsMaxGiven) { + if (model->HSM2_type > 0) { + if (vbs > model->HSM2vbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->HSM2vbdMax); + warns_vbs++; + } + if (-1*vbs > model->HSM2vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->HSM2vbsrMax); + warns_vbs++; + } + } else { + if (vbs > model->HSM2vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->HSM2vbsrMax); + warns_vbs++; + } + if (-1*vbs > model->HSM2vbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->HSM2vbdMax); + warns_vbs++; + } + } + } else { + if (model->HSM2_type > 0) { + if (vbs > model->HSM2vbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->HSM2vbsMax); + warns_vbs++; + } + if (-1*vbs > model->HSM2vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->HSM2vbsrMax); + warns_vbs++; + } + } else { + if (vbs > model->HSM2vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->HSM2vbsrMax); + warns_vbs++; + } + if (-1*vbs > model->HSM2vbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->HSM2vbsMax); + warns_vbs++; + } + } + } + } + + if (!model->HSM2vbdrMaxGiven) { + if (fabs(vbd) > model->HSM2vbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->HSM2vbdMax); + warns_vbd++; + } + } else { + if (model->HSM2_type > 0) { + if (vbd > model->HSM2vbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->HSM2vbdMax); + warns_vbd++; + } + if (-1*vbd > model->HSM2vbdrMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbdr_max=%g\n", + vbd, model->HSM2vbdrMax); + warns_vbd++; + } + } else { + if (vbd > model->HSM2vbdrMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbdr_max=%g\n", + vbd, model->HSM2vbdrMax); + warns_vbd++; + } + if (-1*vbd > model->HSM2vbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->HSM2vbdMax); + warns_vbd++; + } } + } } } diff --git a/src/spicelib/devices/hisimhv1/hsmhv.c b/src/spicelib/devices/hisimhv1/hsmhv.c index f94803ab8..898159919 100644 --- a/src/spicelib/devices/hisimhv1/hsmhv.c +++ b/src/spicelib/devices/hisimhv1/hsmhv.c @@ -725,7 +725,12 @@ IFparm HSMHVmPTable[] = { /* model parameters */ IOP("vgb_max", HSMHV_MOD_VGB_MAX, IF_REAL, "maximum voltage G-B branch"), IOP("vds_max", HSMHV_MOD_VDS_MAX, IF_REAL, "maximum voltage D-S branch"), IOP("vbs_max", HSMHV_MOD_VBS_MAX, IF_REAL, "maximum voltage B-S branch"), - IOP("vbd_max", HSMHV_MOD_VBD_MAX, IF_REAL, "maximum voltage B-D branch") + IOP("vbd_max", HSMHV_MOD_VBD_MAX, IF_REAL, "maximum voltage B-D branch"), + IOP("vgsr_max", HSMHV_MOD_VGSR_MAX, IF_REAL, "maximum voltage G-S branch"), + IOP("vgdr_max", HSMHV_MOD_VGDR_MAX, IF_REAL, "maximum voltage G-D branch"), + IOP("vgbr_max", HSMHV_MOD_VGBR_MAX, IF_REAL, "maximum voltage G-B branch"), + IOP("vbsr_max", HSMHV_MOD_VBSR_MAX, IF_REAL, "maximum voltage B-S branch"), + IOP("vbdr_max", HSMHV_MOD_VBDR_MAX, IF_REAL, "maximum voltage B-D branch") }; diff --git a/src/spicelib/devices/hisimhv1/hsmhvdef.h b/src/spicelib/devices/hisimhv1/hsmhvdef.h index 8ddfe40a2..7651f7537 100644 --- a/src/spicelib/devices/hisimhv1/hsmhvdef.h +++ b/src/spicelib/devices/hisimhv1/hsmhvdef.h @@ -1558,6 +1558,11 @@ typedef struct sHSMHVmodel { /* model structure for a resistor */ double HSMHVvdsMax; double HSMHVvbsMax; double HSMHVvbdMax; + double HSMHVvgsrMax; + double HSMHVvgdrMax; + double HSMHVvgbrMax; + double HSMHVvbsrMax; + double HSMHVvbdrMax; HSMHVmodelMKSParam modelMKS ; /* unit-converted parameters */ @@ -2191,6 +2196,11 @@ typedef struct sHSMHVmodel { /* model structure for a resistor */ unsigned HSMHVvdsMaxGiven :1; unsigned HSMHVvbsMaxGiven :1; unsigned HSMHVvbdMaxGiven :1; + unsigned HSMHVvgsrMaxGiven :1; + unsigned HSMHVvgdrMaxGiven :1; + unsigned HSMHVvgbrMaxGiven :1; + unsigned HSMHVvbsrMaxGiven :1; + unsigned HSMHVvbdrMaxGiven :1; } HSMHVmodel; @@ -2943,12 +2953,17 @@ typedef struct sHSMHVmodel { /* model structure for a resistor */ #define HSMHV_MOD_TCJBDSWG 96 #define HSMHV_MOD_TCJBSSWG 97 -#define HSMHV_MOD_VGS_MAX 4001 -#define HSMHV_MOD_VGD_MAX 4002 -#define HSMHV_MOD_VGB_MAX 4003 -#define HSMHV_MOD_VDS_MAX 4004 -#define HSMHV_MOD_VBS_MAX 4005 -#define HSMHV_MOD_VBD_MAX 4006 +#define HSMHV_MOD_VGS_MAX 4001 +#define HSMHV_MOD_VGD_MAX 4002 +#define HSMHV_MOD_VGB_MAX 4003 +#define HSMHV_MOD_VDS_MAX 4004 +#define HSMHV_MOD_VBS_MAX 4005 +#define HSMHV_MOD_VBD_MAX 4006 +#define HSMHV_MOD_VGSR_MAX 4007 +#define HSMHV_MOD_VGDR_MAX 4008 +#define HSMHV_MOD_VGBR_MAX 4009 +#define HSMHV_MOD_VBSR_MAX 4010 +#define HSMHV_MOD_VBDR_MAX 4011 #include "hsmhvext.h" diff --git a/src/spicelib/devices/hisimhv1/hsmhvmask.c b/src/spicelib/devices/hisimhv1/hsmhvmask.c index e959c9222..e601a5e7a 100644 --- a/src/spicelib/devices/hisimhv1/hsmhvmask.c +++ b/src/spicelib/devices/hisimhv1/hsmhvmask.c @@ -1868,6 +1868,21 @@ int HSMHVmAsk( case HSMHV_MOD_VBD_MAX: value->rValue = model->HSMHVvbdMax; return(OK); + case HSMHV_MOD_VGSR_MAX: + value->rValue = model->HSMHVvgsrMax; + return(OK); + case HSMHV_MOD_VGDR_MAX: + value->rValue = model->HSMHVvgdrMax; + return(OK); + case HSMHV_MOD_VGBR_MAX: + value->rValue = model->HSMHVvgbrMax; + return(OK); + case HSMHV_MOD_VBSR_MAX: + value->rValue = model->HSMHVvbsrMax; + return(OK); + case HSMHV_MOD_VBDR_MAX: + value->rValue = model->HSMHVvbdrMax; + return(OK); default: return(E_BADPARM); diff --git a/src/spicelib/devices/hisimhv1/hsmhvmpar.c b/src/spicelib/devices/hisimhv1/hsmhvmpar.c index 3258c7ab2..1bd06bc7e 100644 --- a/src/spicelib/devices/hisimhv1/hsmhvmpar.c +++ b/src/spicelib/devices/hisimhv1/hsmhvmpar.c @@ -2470,6 +2470,26 @@ int HSMHVmParam( mod->HSMHVvbdMax = value->rValue; mod->HSMHVvbdMaxGiven = TRUE; break; + case HSMHV_MOD_VGSR_MAX: + mod->HSMHVvgsrMax = value->rValue; + mod->HSMHVvgsrMaxGiven = TRUE; + break; + case HSMHV_MOD_VGDR_MAX: + mod->HSMHVvgdrMax = value->rValue; + mod->HSMHVvgdrMaxGiven = TRUE; + break; + case HSMHV_MOD_VGBR_MAX: + mod->HSMHVvgbrMax = value->rValue; + mod->HSMHVvgbrMaxGiven = TRUE; + break; + case HSMHV_MOD_VBSR_MAX: + mod->HSMHVvbsrMax = value->rValue; + mod->HSMHVvbsrMaxGiven = TRUE; + break; + case HSMHV_MOD_VBDR_MAX: + mod->HSMHVvbdrMax = value->rValue; + mod->HSMHVvbdrMaxGiven = TRUE; + break; default: return(E_BADPARM); diff --git a/src/spicelib/devices/hisimhv1/hsmhvset.c b/src/spicelib/devices/hisimhv1/hsmhvset.c index e598aff14..80d84c77c 100644 --- a/src/spicelib/devices/hisimhv1/hsmhvset.c +++ b/src/spicelib/devices/hisimhv1/hsmhvset.c @@ -744,6 +744,11 @@ int HSMHVsetup( if (!model->HSMHVvdsMaxGiven) model->HSMHVvdsMax = 1e99; if (!model->HSMHVvbsMaxGiven) model->HSMHVvbsMax = 1e99; if (!model->HSMHVvbdMaxGiven) model->HSMHVvbdMax = 1e99; + if (!model->HSMHVvgsrMaxGiven) model->HSMHVvgsrMax = 1e99; + if (!model->HSMHVvgdrMaxGiven) model->HSMHVvgdrMax = 1e99; + if (!model->HSMHVvgbrMaxGiven) model->HSMHVvgbrMax = 1e99; + if (!model->HSMHVvbsrMaxGiven) model->HSMHVvbsrMax = 1e99; + if (!model->HSMHVvbdrMaxGiven) model->HSMHVvbdrMax = 1e99; /* For Symmetrical Device */ if ( model->HSMHV_cosym ) { diff --git a/src/spicelib/devices/hisimhv1/hsmhvsoachk.c b/src/spicelib/devices/hisimhv1/hsmhvsoachk.c index a3362c6a2..5509d3aa8 100644 --- a/src/spicelib/devices/hisimhv1/hsmhvsoachk.c +++ b/src/spicelib/devices/hisimhv1/hsmhvsoachk.c @@ -37,71 +37,302 @@ HSMHVsoaCheck(CKTcircuit *ckt, GENmodel *inModel) for (here = model->HSMHVinstances; here; here = here->HSMHVnextInstance) { - vgs = fabs(ckt->CKTrhsOld [here->HSMHVgNode] - - ckt->CKTrhsOld [here->HSMHVsNodePrime]); + vgs = ckt->CKTrhsOld [here->HSMHVgNode] - + ckt->CKTrhsOld [here->HSMHVsNodePrime]; - vgd = fabs(ckt->CKTrhsOld [here->HSMHVgNode] - - ckt->CKTrhsOld [here->HSMHVdNodePrime]); + vgd = ckt->CKTrhsOld [here->HSMHVgNode] - + ckt->CKTrhsOld [here->HSMHVdNodePrime]; - vgb = fabs(ckt->CKTrhsOld [here->HSMHVgNode] - - ckt->CKTrhsOld [here->HSMHVbNode]); + vgb = ckt->CKTrhsOld [here->HSMHVgNode] - + ckt->CKTrhsOld [here->HSMHVbNodePrime]; - vds = fabs(ckt->CKTrhsOld [here->HSMHVdNodePrime] - - ckt->CKTrhsOld [here->HSMHVsNodePrime]); + vds = ckt->CKTrhsOld [here->HSMHVdNode] - + ckt->CKTrhsOld [here->HSMHVsNodePrime]; - vbs = fabs(ckt->CKTrhsOld [here->HSMHVbNode] - - ckt->CKTrhsOld [here->HSMHVsNodePrime]); + vbs = ckt->CKTrhsOld [here->HSMHVbNode] - + ckt->CKTrhsOld [here->HSMHVsNodePrime]; - vbd = fabs(ckt->CKTrhsOld [here->HSMHVbNode] - - ckt->CKTrhsOld [here->HSMHVdNodePrime]); + vbd = ckt->CKTrhsOld [here->HSMHVbNode] - + ckt->CKTrhsOld [here->HSMHVdNodePrime]; - if (vgs > model->HSMHVvgsMax) - if (warns_vgs < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgs|=%g has exceeded Vgs_max=%g\n", - vgs, model->HSMHVvgsMax); - warns_vgs++; + if (!model->HSMHVvgsrMaxGiven) { + if (fabs(vgs) > model->HSMHVvgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->HSMHVvgsMax); + warns_vgs++; + } + if (!model->HSMHVvgbMaxGiven) { + if (fabs(vgb) > model->HSMHVvgsMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgs_max=%g\n", + vgb, model->HSMHVvgsMax); + warns_vgb++; + } + } else { + if (fabs(vgb) > model->HSMHVvgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->HSMHVvgbMax); + warns_vgb++; + } } - - if (vgd > model->HSMHVvgdMax) - if (warns_vgd < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgd|=%g has exceeded Vgd_max=%g\n", - vgd, model->HSMHVvgdMax); - warns_vgd++; + } else { + if (model->HSMHV_type > 0) { + if (vgs > model->HSMHVvgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->HSMHVvgsMax); + warns_vgs++; + } + if (-1*vgs > model->HSMHVvgsrMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgsr_max=%g\n", + vgs, model->HSMHVvgsrMax); + warns_vgs++; + } + } else { + if (vgs > model->HSMHVvgsrMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgsr_max=%g\n", + vgs, model->HSMHVvgsrMax); + warns_vgs++; + } + if (-1*vgs > model->HSMHVvgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->HSMHVvgsMax); + warns_vgs++; + } } + } - if (vgb > model->HSMHVvgbMax) - if (warns_vgb < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgb|=%g has exceeded Vgb_max=%g\n", - vgb, model->HSMHVvgbMax); - warns_vgb++; + if (!model->HSMHVvgdrMaxGiven) { + if (fabs(vgd) > model->HSMHVvgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->HSMHVvgdMax); + warns_vgd++; + } + } else { + if (model->HSMHV_type > 0) { + if (vgd > model->HSMHVvgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->HSMHVvgdMax); + warns_vgd++; + } + if (-1*vgd > model->HSMHVvgdrMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgdr_max=%g\n", + vgd, model->HSMHVvgdrMax); + warns_vgd++; + } + } else { + if (vgd > model->HSMHVvgdrMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgdr_max=%g\n", + vgd, model->HSMHVvgdrMax); + warns_vgd++; + } + if (-1*vgd > model->HSMHVvgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->HSMHVvgdMax); + warns_vgd++; + } } + } - if (vds > model->HSMHVvdsMax) + if (fabs(vds) > model->HSMHVvdsMax) if (warns_vds < maxwarns) { soa_printf(ckt, (GENinstance*) here, - "|Vds|=%g has exceeded Vds_max=%g\n", + "Vds=%g has exceeded Vds_max=%g\n", vds, model->HSMHVvdsMax); warns_vds++; } - if (vbs > model->HSMHVvbsMax) - if (warns_vbs < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vbs|=%g has exceeded Vbs_max=%g\n", - vbs, model->HSMHVvbsMax); - warns_vbs++; + if (!model->HSMHVvgbrMaxGiven) { + if (fabs(vgb) > model->HSMHVvgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->HSMHVvgbMax); + warns_vgb++; + } + } else { + if (model->HSMHV_type > 0) { + if (vgb > model->HSMHVvgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->HSMHVvgbMax); + warns_vgb++; + } + if (-1*vgb > model->HSMHVvgbrMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgbr_max=%g\n", + vgb, model->HSMHVvgbrMax); + warns_vgb++; + } + } else { + if (vgb > model->HSMHVvgbrMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgbr_max=%g\n", + vgb, model->HSMHVvgbrMax); + warns_vgb++; + } + if (-1*vgb > model->HSMHVvgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->HSMHVvgbMax); + warns_vgb++; + } } + } - if (vbd > model->HSMHVvbdMax) - if (warns_vbd < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vbd|=%g has exceeded Vbd_max=%g\n", - vbd, model->HSMHVvbdMax); - warns_vbd++; + if (!model->HSMHVvbsrMaxGiven) { + if (!model->HSMHVvbsMaxGiven) { + if (fabs(vbs) > model->HSMHVvbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->HSMHVvbdMax); + warns_vbs++; + } + } else { + if (fabs(vbs) > model->HSMHVvbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->HSMHVvbsMax); + warns_vbs++; + } + } + } else { + if (!model->HSMHVvbsMaxGiven) { + if (model->HSMHV_type > 0) { + if (vbs > model->HSMHVvbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->HSMHVvbdMax); + warns_vbs++; + } + if (-1*vbs > model->HSMHVvbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->HSMHVvbsrMax); + warns_vbs++; + } + } else { + if (vbs > model->HSMHVvbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->HSMHVvbsrMax); + warns_vbs++; + } + if (-1*vbs > model->HSMHVvbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->HSMHVvbdMax); + warns_vbs++; + } + } + } else { + if (model->HSMHV_type > 0) { + if (vbs > model->HSMHVvbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->HSMHVvbsMax); + warns_vbs++; + } + if (-1*vbs > model->HSMHVvbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->HSMHVvbsrMax); + warns_vbs++; + } + } else { + if (vbs > model->HSMHVvbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->HSMHVvbsrMax); + warns_vbs++; + } + if (-1*vbs > model->HSMHVvbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->HSMHVvbsMax); + warns_vbs++; + } + } + } + } + + if (!model->HSMHVvbdrMaxGiven) { + if (fabs(vbd) > model->HSMHVvbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->HSMHVvbdMax); + warns_vbd++; + } + } else { + if (model->HSMHV_type > 0) { + if (vbd > model->HSMHVvbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->HSMHVvbdMax); + warns_vbd++; + } + if (-1*vbd > model->HSMHVvbdrMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbdr_max=%g\n", + vbd, model->HSMHVvbdrMax); + warns_vbd++; + } + } else { + if (vbd > model->HSMHVvbdrMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbdr_max=%g\n", + vbd, model->HSMHVvbdrMax); + warns_vbd++; + } + if (-1*vbd > model->HSMHVvbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->HSMHVvbdMax); + warns_vbd++; + } } + } } } diff --git a/src/spicelib/devices/hisimhv2/hsmhv2.c b/src/spicelib/devices/hisimhv2/hsmhv2.c index 465207142..68d0272d3 100644 --- a/src/spicelib/devices/hisimhv2/hsmhv2.c +++ b/src/spicelib/devices/hisimhv2/hsmhv2.c @@ -908,7 +908,12 @@ IFparm HSMHV2mPTable[] = { /* model parameters */ IOP("vgb_max", HSMHV2_MOD_VGB_MAX, IF_REAL, "maximum voltage G-B branch"), IOP("vds_max", HSMHV2_MOD_VDS_MAX, IF_REAL, "maximum voltage D-S branch"), IOP("vbs_max", HSMHV2_MOD_VBS_MAX, IF_REAL, "maximum voltage B-S branch"), - IOP("vbd_max", HSMHV2_MOD_VBD_MAX, IF_REAL, "maximum voltage B-D branch") + IOP("vbd_max", HSMHV2_MOD_VBD_MAX, IF_REAL, "maximum voltage B-D branch"), + IOP("vgsr_max", HSMHV2_MOD_VGSR_MAX, IF_REAL, "maximum voltage G-S branch"), + IOP("vgdr_max", HSMHV2_MOD_VGDR_MAX, IF_REAL, "maximum voltage G-D branch"), + IOP("vgbr_max", HSMHV2_MOD_VGBR_MAX, IF_REAL, "maximum voltage G-B branch"), + IOP("vbsr_max", HSMHV2_MOD_VBSR_MAX, IF_REAL, "maximum voltage B-S branch"), + IOP("vbdr_max", HSMHV2_MOD_VBDR_MAX, IF_REAL, "maximum voltage B-D branch") }; diff --git a/src/spicelib/devices/hisimhv2/hsmhv2def.h b/src/spicelib/devices/hisimhv2/hsmhv2def.h index 4f4c4abbf..32db4015e 100644 --- a/src/spicelib/devices/hisimhv2/hsmhv2def.h +++ b/src/spicelib/devices/hisimhv2/hsmhv2def.h @@ -1803,6 +1803,11 @@ typedef struct sHSMHV2model { /* model structure for a resistor */ double HSMHV2vdsMax; double HSMHV2vbsMax; double HSMHV2vbdMax; + double HSMHV2vgsrMax; + double HSMHV2vgdrMax; + double HSMHV2vgbrMax; + double HSMHV2vbsrMax; + double HSMHV2vbdrMax; HSMHV2modelMKSParam modelMKS ; /* unit-converted parameters */ @@ -2570,6 +2575,11 @@ typedef struct sHSMHV2model { /* model structure for a resistor */ unsigned HSMHV2vdsMaxGiven :1; unsigned HSMHV2vbsMaxGiven :1; unsigned HSMHV2vbdMaxGiven :1; + unsigned HSMHV2vgsrMaxGiven :1; + unsigned HSMHV2vgdrMaxGiven :1; + unsigned HSMHV2vgbrMaxGiven :1; + unsigned HSMHV2vbsrMaxGiven :1; + unsigned HSMHV2vbdrMaxGiven :1; } HSMHV2model; @@ -3463,12 +3473,17 @@ typedef struct sHSMHV2model { /* model structure for a resistor */ #define HSMHV2_MOD_TCJBDSWG 96 #define HSMHV2_MOD_TCJBSSWG 97 -#define HSMHV2_MOD_VGS_MAX 4001 -#define HSMHV2_MOD_VGD_MAX 4002 -#define HSMHV2_MOD_VGB_MAX 4003 -#define HSMHV2_MOD_VDS_MAX 4004 -#define HSMHV2_MOD_VBS_MAX 4005 -#define HSMHV2_MOD_VBD_MAX 4006 +#define HSMHV2_MOD_VGS_MAX 4001 +#define HSMHV2_MOD_VGD_MAX 4002 +#define HSMHV2_MOD_VGB_MAX 4003 +#define HSMHV2_MOD_VDS_MAX 4004 +#define HSMHV2_MOD_VBS_MAX 4005 +#define HSMHV2_MOD_VBD_MAX 4006 +#define HSMHV2_MOD_VGSR_MAX 4007 +#define HSMHV2_MOD_VGDR_MAX 4008 +#define HSMHV2_MOD_VGBR_MAX 4009 +#define HSMHV2_MOD_VBSR_MAX 4010 +#define HSMHV2_MOD_VBDR_MAX 4011 #include "hsmhv2ext.h" diff --git a/src/spicelib/devices/hisimhv2/hsmhv2mask.c b/src/spicelib/devices/hisimhv2/hsmhv2mask.c index e58dbc457..3a7f233e6 100644 --- a/src/spicelib/devices/hisimhv2/hsmhv2mask.c +++ b/src/spicelib/devices/hisimhv2/hsmhv2mask.c @@ -2282,6 +2282,21 @@ int HSMHV2mAsk( case HSMHV2_MOD_VBD_MAX: value->rValue = model->HSMHV2vbdMax; return(OK); + case HSMHV2_MOD_VGSR_MAX: + value->rValue = model->HSMHV2vgsrMax; + return(OK); + case HSMHV2_MOD_VGDR_MAX: + value->rValue = model->HSMHV2vgdrMax; + return(OK); + case HSMHV2_MOD_VGBR_MAX: + value->rValue = model->HSMHV2vgbrMax; + return(OK); + case HSMHV2_MOD_VBSR_MAX: + value->rValue = model->HSMHV2vbsrMax; + return(OK); + case HSMHV2_MOD_VBDR_MAX: + value->rValue = model->HSMHV2vbdrMax; + return(OK); default: return(E_BADPARM); diff --git a/src/spicelib/devices/hisimhv2/hsmhv2mpar.c b/src/spicelib/devices/hisimhv2/hsmhv2mpar.c index c74c0b92f..bf9afdcd3 100644 --- a/src/spicelib/devices/hisimhv2/hsmhv2mpar.c +++ b/src/spicelib/devices/hisimhv2/hsmhv2mpar.c @@ -2995,6 +2995,26 @@ int HSMHV2mParam( mod->HSMHV2vbdMax = value->rValue; mod->HSMHV2vbdMaxGiven = TRUE; break; + case HSMHV2_MOD_VGSR_MAX: + mod->HSMHV2vgsrMax = value->rValue; + mod->HSMHV2vgsrMaxGiven = TRUE; + break; + case HSMHV2_MOD_VGDR_MAX: + mod->HSMHV2vgdrMax = value->rValue; + mod->HSMHV2vgdrMaxGiven = TRUE; + break; + case HSMHV2_MOD_VGBR_MAX: + mod->HSMHV2vgbrMax = value->rValue; + mod->HSMHV2vgbrMaxGiven = TRUE; + break; + case HSMHV2_MOD_VBSR_MAX: + mod->HSMHV2vbsrMax = value->rValue; + mod->HSMHV2vbsrMaxGiven = TRUE; + break; + case HSMHV2_MOD_VBDR_MAX: + mod->HSMHV2vbdrMax = value->rValue; + mod->HSMHV2vbdrMaxGiven = TRUE; + break; default: return(E_BADPARM); diff --git a/src/spicelib/devices/hisimhv2/hsmhv2set.c b/src/spicelib/devices/hisimhv2/hsmhv2set.c index 6f4256fb5..aae6cc8b9 100644 --- a/src/spicelib/devices/hisimhv2/hsmhv2set.c +++ b/src/spicelib/devices/hisimhv2/hsmhv2set.c @@ -961,6 +961,11 @@ int HSMHV2setup( if (!model->HSMHV2vdsMaxGiven) model->HSMHV2vdsMax = 1e99; if (!model->HSMHV2vbsMaxGiven) model->HSMHV2vbsMax = 1e99; if (!model->HSMHV2vbdMaxGiven) model->HSMHV2vbdMax = 1e99; + if (!model->HSMHV2vgsrMaxGiven) model->HSMHV2vgsrMax = 1e99; + if (!model->HSMHV2vgdrMaxGiven) model->HSMHV2vgdrMax = 1e99; + if (!model->HSMHV2vgbrMaxGiven) model->HSMHV2vgbrMax = 1e99; + if (!model->HSMHV2vbsrMaxGiven) model->HSMHV2vbsrMax = 1e99; + if (!model->HSMHV2vbdrMaxGiven) model->HSMHV2vbdrMax = 1e99; /* For Symmetrical Device */ if ( model->HSMHV2_cosym ) { diff --git a/src/spicelib/devices/hisimhv2/hsmhv2soachk.c b/src/spicelib/devices/hisimhv2/hsmhv2soachk.c index c50e9cf74..de7f5d5d9 100644 --- a/src/spicelib/devices/hisimhv2/hsmhv2soachk.c +++ b/src/spicelib/devices/hisimhv2/hsmhv2soachk.c @@ -37,71 +37,302 @@ HSMHV2soaCheck(CKTcircuit *ckt, GENmodel *inModel) for (here = model->HSMHV2instances; here; here = here->HSMHV2nextInstance) { - vgs = fabs(ckt->CKTrhsOld [here->HSMHV2gNode] - - ckt->CKTrhsOld [here->HSMHV2sNodePrime]); + vgs = ckt->CKTrhsOld [here->HSMHV2gNode] - + ckt->CKTrhsOld [here->HSMHV2sNodePrime]; - vgd = fabs(ckt->CKTrhsOld [here->HSMHV2gNode] - - ckt->CKTrhsOld [here->HSMHV2dNodePrime]); + vgd = ckt->CKTrhsOld [here->HSMHV2gNode] - + ckt->CKTrhsOld [here->HSMHV2dNodePrime]; - vgb = fabs(ckt->CKTrhsOld [here->HSMHV2gNode] - - ckt->CKTrhsOld [here->HSMHV2bNode]); + vgb = ckt->CKTrhsOld [here->HSMHV2gNode] - + ckt->CKTrhsOld [here->HSMHV2bNodePrime]; - vds = fabs(ckt->CKTrhsOld [here->HSMHV2dNodePrime] - - ckt->CKTrhsOld [here->HSMHV2sNodePrime]); + vds = ckt->CKTrhsOld [here->HSMHV2dNode] - + ckt->CKTrhsOld [here->HSMHV2sNodePrime]; - vbs = fabs(ckt->CKTrhsOld [here->HSMHV2bNode] - - ckt->CKTrhsOld [here->HSMHV2sNodePrime]); + vbs = ckt->CKTrhsOld [here->HSMHV2bNode] - + ckt->CKTrhsOld [here->HSMHV2sNodePrime]; - vbd = fabs(ckt->CKTrhsOld [here->HSMHV2bNode] - - ckt->CKTrhsOld [here->HSMHV2dNodePrime]); + vbd = ckt->CKTrhsOld [here->HSMHV2bNode] - + ckt->CKTrhsOld [here->HSMHV2dNodePrime]; - if (vgs > model->HSMHV2vgsMax) - if (warns_vgs < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgs|=%g has exceeded Vgs_max=%g\n", - vgs, model->HSMHV2vgsMax); - warns_vgs++; + if (!model->HSMHV2vgsrMaxGiven) { + if (fabs(vgs) > model->HSMHV2vgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->HSMHV2vgsMax); + warns_vgs++; + } + if (!model->HSMHV2vgbMaxGiven) { + if (fabs(vgb) > model->HSMHV2vgsMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgs_max=%g\n", + vgb, model->HSMHV2vgsMax); + warns_vgb++; + } + } else { + if (fabs(vgb) > model->HSMHV2vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->HSMHV2vgbMax); + warns_vgb++; + } } - - if (vgd > model->HSMHV2vgdMax) - if (warns_vgd < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgd|=%g has exceeded Vgd_max=%g\n", - vgd, model->HSMHV2vgdMax); - warns_vgd++; + } else { + if (model->HSMHV2_type > 0) { + if (vgs > model->HSMHV2vgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->HSMHV2vgsMax); + warns_vgs++; + } + if (-1*vgs > model->HSMHV2vgsrMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgsr_max=%g\n", + vgs, model->HSMHV2vgsrMax); + warns_vgs++; + } + } else { + if (vgs > model->HSMHV2vgsrMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgsr_max=%g\n", + vgs, model->HSMHV2vgsrMax); + warns_vgs++; + } + if (-1*vgs > model->HSMHV2vgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgs=%g has exceeded Vgs_max=%g\n", + vgs, model->HSMHV2vgsMax); + warns_vgs++; + } } + } - if (vgb > model->HSMHV2vgbMax) - if (warns_vgb < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vgb|=%g has exceeded Vgb_max=%g\n", - vgb, model->HSMHV2vgbMax); - warns_vgb++; + if (!model->HSMHV2vgdrMaxGiven) { + if (fabs(vgd) > model->HSMHV2vgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->HSMHV2vgdMax); + warns_vgd++; + } + } else { + if (model->HSMHV2_type > 0) { + if (vgd > model->HSMHV2vgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->HSMHV2vgdMax); + warns_vgd++; + } + if (-1*vgd > model->HSMHV2vgdrMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgdr_max=%g\n", + vgd, model->HSMHV2vgdrMax); + warns_vgd++; + } + } else { + if (vgd > model->HSMHV2vgdrMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgdr_max=%g\n", + vgd, model->HSMHV2vgdrMax); + warns_vgd++; + } + if (-1*vgd > model->HSMHV2vgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgd=%g has exceeded Vgd_max=%g\n", + vgd, model->HSMHV2vgdMax); + warns_vgd++; + } } + } - if (vds > model->HSMHV2vdsMax) + if (fabs(vds) > model->HSMHV2vdsMax) if (warns_vds < maxwarns) { soa_printf(ckt, (GENinstance*) here, - "|Vds|=%g has exceeded Vds_max=%g\n", + "Vds=%g has exceeded Vds_max=%g\n", vds, model->HSMHV2vdsMax); warns_vds++; } - if (vbs > model->HSMHV2vbsMax) - if (warns_vbs < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vbs|=%g has exceeded Vbs_max=%g\n", - vbs, model->HSMHV2vbsMax); - warns_vbs++; + if (!model->HSMHV2vgbrMaxGiven) { + if (fabs(vgb) > model->HSMHV2vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->HSMHV2vgbMax); + warns_vgb++; + } + } else { + if (model->HSMHV2_type > 0) { + if (vgb > model->HSMHV2vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->HSMHV2vgbMax); + warns_vgb++; + } + if (-1*vgb > model->HSMHV2vgbrMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgbr_max=%g\n", + vgb, model->HSMHV2vgbrMax); + warns_vgb++; + } + } else { + if (vgb > model->HSMHV2vgbrMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgbr_max=%g\n", + vgb, model->HSMHV2vgbrMax); + warns_vgb++; + } + if (-1*vgb > model->HSMHV2vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vgb=%g has exceeded Vgb_max=%g\n", + vgb, model->HSMHV2vgbMax); + warns_vgb++; + } } + } - if (vbd > model->HSMHV2vbdMax) - if (warns_vbd < maxwarns) { - soa_printf(ckt, (GENinstance*) here, - "|Vbd|=%g has exceeded Vbd_max=%g\n", - vbd, model->HSMHV2vbdMax); - warns_vbd++; + if (!model->HSMHV2vbsrMaxGiven) { + if (!model->HSMHV2vbsMaxGiven) { + if (fabs(vbs) > model->HSMHV2vbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->HSMHV2vbdMax); + warns_vbs++; + } + } else { + if (fabs(vbs) > model->HSMHV2vbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->HSMHV2vbsMax); + warns_vbs++; + } + } + } else { + if (!model->HSMHV2vbsMaxGiven) { + if (model->HSMHV2_type > 0) { + if (vbs > model->HSMHV2vbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->HSMHV2vbdMax); + warns_vbs++; + } + if (-1*vbs > model->HSMHV2vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->HSMHV2vbsrMax); + warns_vbs++; + } + } else { + if (vbs > model->HSMHV2vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->HSMHV2vbsrMax); + warns_vbs++; + } + if (-1*vbs > model->HSMHV2vbdMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbd_max=%g\n", + vbs, model->HSMHV2vbdMax); + warns_vbs++; + } + } + } else { + if (model->HSMHV2_type > 0) { + if (vbs > model->HSMHV2vbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->HSMHV2vbsMax); + warns_vbs++; + } + if (-1*vbs > model->HSMHV2vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->HSMHV2vbsrMax); + warns_vbs++; + } + } else { + if (vbs > model->HSMHV2vbsrMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbsr_max=%g\n", + vbs, model->HSMHV2vbsrMax); + warns_vbs++; + } + if (-1*vbs > model->HSMHV2vbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbs=%g has exceeded Vbs_max=%g\n", + vbs, model->HSMHV2vbsMax); + warns_vbs++; + } + } + } + } + + if (!model->HSMHV2vbdrMaxGiven) { + if (fabs(vbd) > model->HSMHV2vbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->HSMHV2vbdMax); + warns_vbd++; + } + } else { + if (model->HSMHV2_type > 0) { + if (vbd > model->HSMHV2vbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->HSMHV2vbdMax); + warns_vbd++; + } + if (-1*vbd > model->HSMHV2vbdrMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbdr_max=%g\n", + vbd, model->HSMHV2vbdrMax); + warns_vbd++; + } + } else { + if (vbd > model->HSMHV2vbdrMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbdr_max=%g\n", + vbd, model->HSMHV2vbdrMax); + warns_vbd++; + } + if (-1*vbd > model->HSMHV2vbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vbd=%g has exceeded Vbd_max=%g\n", + vbd, model->HSMHV2vbdMax); + warns_vbd++; + } } + } } }