devices/hisim2, implement HSM2soaCheck()
This commit is contained in:
parent
f6c6fa85a0
commit
2875ac632f
|
|
@ -27,6 +27,7 @@ libhisim2_la_SOURCES = hisim2.h \
|
||||||
hsm2par.c \
|
hsm2par.c \
|
||||||
hsm2pzld.c \
|
hsm2pzld.c \
|
||||||
hsm2set.c \
|
hsm2set.c \
|
||||||
|
hsm2soachk.c \
|
||||||
hsm2temp.c \
|
hsm2temp.c \
|
||||||
hsm2trunc.c
|
hsm2trunc.c
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -619,7 +619,14 @@ IFparm HSM2mPTable[] = { /* model parameters */
|
||||||
IOP("pnfalp", HSM2_MOD_PNFALP, IF_REAL, "Cross-term dependence of nfalp"),
|
IOP("pnfalp", HSM2_MOD_PNFALP, IF_REAL, "Cross-term dependence of nfalp"),
|
||||||
IOP("pvdiffj", HSM2_MOD_PVDIFFJ, IF_REAL, "Cross-term dependence of vdiffj"),
|
IOP("pvdiffj", HSM2_MOD_PVDIFFJ, IF_REAL, "Cross-term dependence of vdiffj"),
|
||||||
IOP("pibpc1", HSM2_MOD_PIBPC1, IF_REAL, "Cross-term dependence of ibpc1"),
|
IOP("pibpc1", HSM2_MOD_PIBPC1, IF_REAL, "Cross-term dependence of ibpc1"),
|
||||||
IOP("pibpc2", HSM2_MOD_PIBPC2, IF_REAL, "Cross-term dependence of ibpc2")
|
IOP("pibpc2", HSM2_MOD_PIBPC2, IF_REAL, "Cross-term dependence of ibpc2"),
|
||||||
|
|
||||||
|
IOP("vgs_max", HSM2_MOD_VGS_MAX, IF_REAL, "maximum voltage G-S branch"),
|
||||||
|
IOP("vgd_max", HSM2_MOD_VGD_MAX, IF_REAL, "maximum voltage G-D branch"),
|
||||||
|
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")
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1126,6 +1126,13 @@ typedef struct sHSM2model { /* model structure for a resistor */
|
||||||
double HSM2_ktnom ;
|
double HSM2_ktnom ;
|
||||||
int HSM2_bypass_enable ;
|
int HSM2_bypass_enable ;
|
||||||
|
|
||||||
|
double HSM2vgsMax;
|
||||||
|
double HSM2vgdMax;
|
||||||
|
double HSM2vgbMax;
|
||||||
|
double HSM2vdsMax;
|
||||||
|
double HSM2vbsMax;
|
||||||
|
double HSM2vbdMax;
|
||||||
|
|
||||||
HSM2modelMKSParam modelMKS ; /* unit-converted parameters */
|
HSM2modelMKSParam modelMKS ; /* unit-converted parameters */
|
||||||
/* flag for model */
|
/* flag for model */
|
||||||
unsigned HSM2_type_Given :1;
|
unsigned HSM2_type_Given :1;
|
||||||
|
|
@ -1647,6 +1654,13 @@ typedef struct sHSM2model { /* model structure for a resistor */
|
||||||
unsigned HSM2_pibpc1_Given :1;
|
unsigned HSM2_pibpc1_Given :1;
|
||||||
unsigned HSM2_pibpc2_Given :1;
|
unsigned HSM2_pibpc2_Given :1;
|
||||||
|
|
||||||
|
unsigned HSM2vgsMaxGiven :1;
|
||||||
|
unsigned HSM2vgdMaxGiven :1;
|
||||||
|
unsigned HSM2vgbMaxGiven :1;
|
||||||
|
unsigned HSM2vdsMaxGiven :1;
|
||||||
|
unsigned HSM2vbsMaxGiven :1;
|
||||||
|
unsigned HSM2vbdMaxGiven :1;
|
||||||
|
|
||||||
} HSM2model;
|
} HSM2model;
|
||||||
|
|
||||||
#ifndef NMOS
|
#ifndef NMOS
|
||||||
|
|
@ -2282,6 +2296,13 @@ typedef struct sHSM2model { /* model structure for a resistor */
|
||||||
#define HSM2_MOD_TCJBDSWG 96
|
#define HSM2_MOD_TCJBDSWG 96
|
||||||
#define HSM2_MOD_TCJBSSWG 97
|
#define HSM2_MOD_TCJBSSWG 97
|
||||||
|
|
||||||
|
#define HSM2_MOD_VGS_MAX 4001
|
||||||
|
#define HSM2_MOD_VGD_MAX 4002
|
||||||
|
#define HSM2_MOD_VGB_MAX 4003
|
||||||
|
#define HSM2_MOD_VDS_MAX 4004
|
||||||
|
#define HSM2_MOD_VBS_MAX 4005
|
||||||
|
#define HSM2_MOD_VBD_MAX 4006
|
||||||
|
|
||||||
#include "hsm2ext.h"
|
#include "hsm2ext.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -37,3 +37,4 @@ extern int HSM2unsetup(GENmodel*,CKTcircuit*);
|
||||||
extern int HSM2temp(GENmodel*,CKTcircuit*);
|
extern int HSM2temp(GENmodel*,CKTcircuit*);
|
||||||
extern int HSM2trunc(GENmodel*,CKTcircuit*,double*);
|
extern int HSM2trunc(GENmodel*,CKTcircuit*,double*);
|
||||||
extern int HSM2noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
|
extern int HSM2noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
|
||||||
|
extern int HSM2soaCheck(CKTcircuit *, GENmodel *);
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ SPICEdev HSM2info = {
|
||||||
/* DEVsenTrunc */ NULL,
|
/* DEVsenTrunc */ NULL,
|
||||||
/* DEVdisto */ NULL,
|
/* DEVdisto */ NULL,
|
||||||
/* DEVnoise */ HSM2noise,
|
/* DEVnoise */ HSM2noise,
|
||||||
/* DEVsoaCheck */ NULL,
|
/* DEVsoaCheck */ HSM2soaCheck,
|
||||||
#ifdef CIDER
|
#ifdef CIDER
|
||||||
/* DEVdump */ NULL,
|
/* DEVdump */ NULL,
|
||||||
/* DEVacct */ NULL,
|
/* DEVacct */ NULL,
|
||||||
|
|
|
||||||
|
|
@ -1567,6 +1567,25 @@ int HSM2mAsk(
|
||||||
value->rValue = model->HSM2_pibpc2;
|
value->rValue = model->HSM2_pibpc2;
|
||||||
return(OK);
|
return(OK);
|
||||||
|
|
||||||
|
case HSM2_MOD_VGS_MAX:
|
||||||
|
value->rValue = model->HSM2vgsMax;
|
||||||
|
return(OK);
|
||||||
|
case HSM2_MOD_VGD_MAX:
|
||||||
|
value->rValue = model->HSM2vgdMax;
|
||||||
|
return(OK);
|
||||||
|
case HSM2_MOD_VGB_MAX:
|
||||||
|
value->rValue = model->HSM2vgbMax;
|
||||||
|
return(OK);
|
||||||
|
case HSM2_MOD_VDS_MAX:
|
||||||
|
value->rValue = model->HSM2vdsMax;
|
||||||
|
return(OK);
|
||||||
|
case HSM2_MOD_VBS_MAX:
|
||||||
|
value->rValue = model->HSM2vbsMax;
|
||||||
|
return(OK);
|
||||||
|
case HSM2_MOD_VBD_MAX:
|
||||||
|
value->rValue = model->HSM2vbdMax;
|
||||||
|
return(OK);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return(E_BADPARM);
|
return(E_BADPARM);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2071,6 +2071,31 @@ int HSM2mParam(
|
||||||
mod->HSM2_pibpc2_Given = TRUE;
|
mod->HSM2_pibpc2_Given = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case HSM2_MOD_VGS_MAX:
|
||||||
|
mod->HSM2vgsMax = value->rValue;
|
||||||
|
mod->HSM2vgsMaxGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case HSM2_MOD_VGD_MAX:
|
||||||
|
mod->HSM2vgdMax = value->rValue;
|
||||||
|
mod->HSM2vgdMaxGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case HSM2_MOD_VGB_MAX:
|
||||||
|
mod->HSM2vgbMax = value->rValue;
|
||||||
|
mod->HSM2vgbMaxGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case HSM2_MOD_VDS_MAX:
|
||||||
|
mod->HSM2vdsMax = value->rValue;
|
||||||
|
mod->HSM2vdsMaxGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case HSM2_MOD_VBS_MAX:
|
||||||
|
mod->HSM2vbsMax = value->rValue;
|
||||||
|
mod->HSM2vbsMaxGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case HSM2_MOD_VBD_MAX:
|
||||||
|
mod->HSM2vbdMax = value->rValue;
|
||||||
|
mod->HSM2vbdMaxGiven = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return(E_BADPARM);
|
return(E_BADPARM);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -641,6 +641,12 @@ int HSM2setup(
|
||||||
if ( !model->HSM2_pibpc1_Given ) model->HSM2_pibpc1 = 0.0 ;
|
if ( !model->HSM2_pibpc1_Given ) model->HSM2_pibpc1 = 0.0 ;
|
||||||
if ( !model->HSM2_pibpc2_Given ) model->HSM2_pibpc2 = 0.0 ;
|
if ( !model->HSM2_pibpc2_Given ) model->HSM2_pibpc2 = 0.0 ;
|
||||||
|
|
||||||
|
if (!model->HSM2vgsMaxGiven) model->HSM2vgsMax = 1e99;
|
||||||
|
if (!model->HSM2vgdMaxGiven) model->HSM2vgdMax = 1e99;
|
||||||
|
if (!model->HSM2vgbMaxGiven) model->HSM2vgbMax = 1e99;
|
||||||
|
if (!model->HSM2vdsMaxGiven) model->HSM2vdsMax = 1e99;
|
||||||
|
if (!model->HSM2vbsMaxGiven) model->HSM2vbsMax = 1e99;
|
||||||
|
if (!model->HSM2vbdMaxGiven) model->HSM2vbdMax = 1e99;
|
||||||
|
|
||||||
if ( model->HSM2_corecip == 1 ){
|
if ( model->HSM2_corecip == 1 ){
|
||||||
model->HSM2_sc2 = 0.0 ; model->HSM2_lsc2 = 0.0 ; model->HSM2_wsc2 = 0.0 ; model->HSM2_psc2 = 0.0 ;
|
model->HSM2_sc2 = 0.0 ; model->HSM2_lsc2 = 0.0 ; model->HSM2_wsc2 = 0.0 ; model->HSM2_psc2 = 0.0 ;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,110 @@
|
||||||
|
/**********
|
||||||
|
Copyright 2013 Dietmar Warning. All rights reserved.
|
||||||
|
Author: 2013 Dietmar Warning
|
||||||
|
**********/
|
||||||
|
|
||||||
|
#include "ngspice/ngspice.h"
|
||||||
|
#include "ngspice/cktdefs.h"
|
||||||
|
#include "hsm2def.h"
|
||||||
|
#include "ngspice/trandefs.h"
|
||||||
|
#include "ngspice/sperror.h"
|
||||||
|
#include "ngspice/suffix.h"
|
||||||
|
#include "ngspice/cpdefs.h"
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
HSM2soaCheck(CKTcircuit *ckt, GENmodel *inModel)
|
||||||
|
{
|
||||||
|
HSM2model *model = (HSM2model *) inModel;
|
||||||
|
HSM2instance *here;
|
||||||
|
double vgs, vgd, vgb, vds, vbs, vbd; /* actual mos voltages */
|
||||||
|
int maxwarns;
|
||||||
|
static int warns_vgs = 0, warns_vgd = 0, warns_vgb = 0, warns_vds = 0, warns_vbs = 0, warns_vbd = 0;
|
||||||
|
|
||||||
|
if (!ckt) {
|
||||||
|
warns_vgs = 0;
|
||||||
|
warns_vgd = 0;
|
||||||
|
warns_vgb = 0;
|
||||||
|
warns_vds = 0;
|
||||||
|
warns_vbs = 0;
|
||||||
|
warns_vbd = 0;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
maxwarns = ckt->CKTsoaMaxWarns;
|
||||||
|
|
||||||
|
for (; model; model = model->HSM2nextModel) {
|
||||||
|
|
||||||
|
for (here = model->HSM2instances; here; here = here->HSM2nextInstance) {
|
||||||
|
|
||||||
|
vgs = fabs(ckt->CKTrhsOld [here->HSM2gNode] -
|
||||||
|
ckt->CKTrhsOld [here->HSM2sNodePrime]);
|
||||||
|
|
||||||
|
vgd = fabs(ckt->CKTrhsOld [here->HSM2gNode] -
|
||||||
|
ckt->CKTrhsOld [here->HSM2dNodePrime]);
|
||||||
|
|
||||||
|
vgb = fabs(ckt->CKTrhsOld [here->HSM2gNode] -
|
||||||
|
ckt->CKTrhsOld [here->HSM2bNode]);
|
||||||
|
|
||||||
|
vds = fabs(ckt->CKTrhsOld [here->HSM2dNodePrime] -
|
||||||
|
ckt->CKTrhsOld [here->HSM2sNodePrime]);
|
||||||
|
|
||||||
|
vbs = fabs(ckt->CKTrhsOld [here->HSM2bNode] -
|
||||||
|
ckt->CKTrhsOld [here->HSM2sNodePrime]);
|
||||||
|
|
||||||
|
vbd = fabs(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 (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 (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 (vds > model->HSM2vdsMax)
|
||||||
|
if (warns_vds < maxwarns) {
|
||||||
|
soa_printf(ckt, (GENinstance*) here,
|
||||||
|
"|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 (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++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
@ -5860,6 +5860,10 @@
|
||||||
RelativePath="..\src\spicelib\devices\hisim2\hsm2set.c"
|
RelativePath="..\src\spicelib\devices\hisim2\hsm2set.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\spicelib\devices\hisim2\hsm2soachk.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\src\spicelib\devices\hisim2\hsm2temp.c"
|
RelativePath="..\src\spicelib\devices\hisim2\hsm2temp.c"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue