new scalable diode model including tunnel component
This commit is contained in:
parent
cc44d34f70
commit
dcc22ada60
|
|
@ -1,7 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified by Dietmar Warning 2003 and Paolo Nenzi 2003
|
||||
Modified by Paolo Nenzi 2003 and Dietmar Warning 2012
|
||||
**********/
|
||||
|
||||
#include "ngspice/ngspice.h"
|
||||
|
|
@ -10,13 +10,15 @@ Modified by Dietmar Warning 2003 and Paolo Nenzi 2003
|
|||
#include "ngspice/suffix.h"
|
||||
|
||||
IFparm DIOpTable[] = { /* parameters */
|
||||
IOPU("off", DIO_OFF, IF_FLAG, "Initially off"),
|
||||
IOPU("temp", DIO_TEMP, IF_REAL, "Instance temperature"),
|
||||
IOPU("dtemp", DIO_DTEMP, IF_REAL, "Instance delta temperature"),
|
||||
IOPAU("ic", DIO_IC, IF_REAL, "Initial device voltage"),
|
||||
IOPU("area", DIO_AREA, IF_REAL, "Area factor"),
|
||||
IOPU("pj", DIO_PJ, IF_REAL, "Perimeter factor"),
|
||||
IOPU("m", DIO_M, IF_REAL, "Multiplier"),
|
||||
IOPU("off", DIO_OFF, IF_FLAG, "Initially off"),
|
||||
IOPU("temp", DIO_TEMP, IF_REAL, "Instance temperature"),
|
||||
IOPU("dtemp", DIO_DTEMP, IF_REAL, "Instance delta temperature"),
|
||||
IOPAU("ic", DIO_IC, IF_REAL, "Initial device voltage"),
|
||||
IOPU("area", DIO_AREA, IF_REAL, "Area factor"),
|
||||
IOPU("pj", DIO_PJ, IF_REAL, "Perimeter factor"),
|
||||
IOPU("w", DIO_W, IF_REAL, "Diode width"),
|
||||
IOPU("l", DIO_L, IF_REAL, "Diode length"),
|
||||
IOPU("m", DIO_M, IF_REAL, "Multiplier"),
|
||||
|
||||
IP("sens_area",DIO_AREA_SENS,IF_FLAG,"flag to request sensitivity WRT area"),
|
||||
OP("vd", DIO_VOLTAGE,IF_REAL, "Diode voltage"),
|
||||
|
|
@ -37,6 +39,7 @@ IFparm DIOpTable[] = { /* parameters */
|
|||
};
|
||||
|
||||
IFparm DIOmPTable[] = { /* model parameters */
|
||||
IOP( "level", DIO_MOD_LEVEL, IF_INTEGER, "Diode level selector"),
|
||||
IOP( "is", DIO_MOD_IS, IF_REAL, "Saturation current"),
|
||||
IOPR( "js", DIO_MOD_IS, IF_REAL, "Saturation current"),
|
||||
IOP( "jsw", DIO_MOD_JSW, IF_REAL, "Sidewall Saturation current"),
|
||||
|
|
@ -48,6 +51,7 @@ IFparm DIOmPTable[] = { /* model parameters */
|
|||
IOPR( "trs1", DIO_MOD_TRS, IF_REAL, "Ohmic resistance 1st order temp. coeff."),
|
||||
IOP( "trs2", DIO_MOD_TRS2, IF_REAL, "Ohmic resistance 2nd order temp. coeff."),
|
||||
IOP( "n", DIO_MOD_N, IF_REAL, "Emission Coefficient"),
|
||||
IOP( "ns", DIO_MOD_NS, IF_REAL, "Sidewall emission Coefficient"),
|
||||
IOPA( "tt", DIO_MOD_TT, IF_REAL, "Transit Time"),
|
||||
IOPA( "ttt1", DIO_MOD_TTT1, IF_REAL, "Transit Time 1st order temp. coeff."),
|
||||
IOPA( "ttt2", DIO_MOD_TTT2, IF_REAL, "Transit Time 2nd order temp. coeff."),
|
||||
|
|
@ -63,10 +67,13 @@ IFparm DIOmPTable[] = { /* model parameters */
|
|||
IOP( "cjp", DIO_MOD_CJSW, IF_REAL, "Sidewall junction capacitance"),
|
||||
IOPR( "cjsw", DIO_MOD_CJSW, IF_REAL, "Sidewall junction capacitance"),
|
||||
IOP( "php", DIO_MOD_VJSW, IF_REAL, "Sidewall junction potential"),
|
||||
IOP( "mjsw", DIO_MOD_MJSW, IF_REAL, "Sidewall Grading coefficient"),
|
||||
IOP( "ikf", DIO_MOD_IKF, IF_REAL, "Forward Knee current"),
|
||||
IOPR( "ik", DIO_MOD_IKF, IF_REAL, "Forward Knee current"),
|
||||
IOP( "ikr", DIO_MOD_IKR, IF_REAL, "Reverse Knee current"),
|
||||
IOP( "mjsw", DIO_MOD_MJSW, IF_REAL, "Sidewall Grading coefficient"),
|
||||
IOP( "ikf", DIO_MOD_IKF, IF_REAL, "Forward Knee current"),
|
||||
IOPR( "ik", DIO_MOD_IKF, IF_REAL, "Forward Knee current"),
|
||||
IOP( "ikr", DIO_MOD_IKR, IF_REAL, "Reverse Knee current"),
|
||||
IOP( "nbv", DIO_MOD_NBV, IF_REAL, "Breakdown Emission Coefficient"),
|
||||
IOP("area", DIO_MOD_AREA, IF_REAL, "Area factor"),
|
||||
IOP( "pj", DIO_MOD_PJ, IF_REAL, "Perimeter factor"),
|
||||
|
||||
IOP( "tlev", DIO_MOD_TLEV, IF_INTEGER, "Diode temperature equation selector"),
|
||||
IOP( "tlevc", DIO_MOD_TLEVC, IF_INTEGER, "Diode temperature equation selector"),
|
||||
|
|
@ -76,16 +83,25 @@ IFparm DIOmPTable[] = { /* model parameters */
|
|||
IOPR( "ctc", DIO_MOD_CTA, IF_REAL, "Area junction capacitance temperature coefficient"),
|
||||
IOP( "ctp", DIO_MOD_CTP, IF_REAL, "Perimeter junction capacitance temperature coefficient"),
|
||||
|
||||
IOP( "ctp", DIO_MOD_CTP, IF_REAL, "Perimeter junction capacitance temperature coefficient"),
|
||||
|
||||
IOP( "tpb", DIO_MOD_TPB, IF_REAL, "Area junction potential temperature coefficient"),
|
||||
IOPR( "tvj", DIO_MOD_TPB, IF_REAL, "Area junction potential temperature coefficient"),
|
||||
IOP( "tphp", DIO_MOD_TPHP, IF_REAL, "Perimeter junction potential temperature coefficient"),
|
||||
|
||||
IOP( "jtun", DIO_MOD_JTUN, IF_REAL, "Tunneling saturation current"),
|
||||
IOP( "jtunsw", DIO_MOD_JTUNSW, IF_REAL, "Tunneling sidewall saturation current"),
|
||||
IOP( "ntun", DIO_MOD_NTUN, IF_REAL, "Tunneling emission coefficient"),
|
||||
IOP( "xtitun", DIO_MOD_XTITUN, IF_REAL, "Tunneling saturation current exponential"),
|
||||
IOP( "keg", DIO_MOD_KEG, IF_REAL, "EG correction factor for tunneling"),
|
||||
|
||||
IOP( "kf", DIO_MOD_KF, IF_REAL, "flicker noise coefficient"),
|
||||
IOP( "af", DIO_MOD_AF, IF_REAL, "flicker noise exponent"),
|
||||
IOP( "fc", DIO_MOD_FC, IF_REAL, "Forward bias junction fit parameter"),
|
||||
IOP( "fcs", DIO_MOD_FCS, IF_REAL, "Forward bias sidewall junction fit parameter"),
|
||||
IOP( "bv", DIO_MOD_BV, IF_REAL, "Reverse breakdown voltage"),
|
||||
IOP( "ibv", DIO_MOD_IBV, IF_REAL, "Current at reverse breakdown voltage"),
|
||||
IOPR( "ib", DIO_MOD_IBV, IF_REAL, "Current at reverse breakdown voltage"),
|
||||
IOP( "tcv", DIO_MOD_TCV, IF_REAL, "Reverse breakdown voltage temperature coefficient"),
|
||||
OPU( "cond", DIO_MOD_COND,IF_REAL, "Ohmic conductance"),
|
||||
IP( "d", DIO_MOD_D, IF_FLAG, "Diode model")
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ DIOacLoad(GENmodel *inModel, CKTcircuit *ckt)
|
|||
/* loop through all the instances of the model */
|
||||
for (here = model->DIOinstances; here != NULL ;
|
||||
here=here->DIOnextInstance) {
|
||||
if (here->DIOowner != ARCHme) continue;
|
||||
gspr=here->DIOtConductance*here->DIOarea*here->DIOm;
|
||||
if (here->DIOowner != ARCHme) continue;
|
||||
gspr=here->DIOtConductance*here->DIOarea;
|
||||
geq= *(ckt->CKTstate0 + here->DIOconduct);
|
||||
xceq= *(ckt->CKTstate0 + here->DIOcapCurrent) * ckt->CKTomega;
|
||||
*(here->DIOposPosPtr ) += gspr;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified by Dietmar Warning 2003 and Paolo Nenzi 2003
|
||||
Modified by Paolo Nenzi 2003 and Dietmar Warning 2012
|
||||
**********/
|
||||
|
||||
#include "ngspice/ngspice.h"
|
||||
|
|
@ -39,6 +39,12 @@ DIOask (CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value,
|
|||
case DIO_PJ:
|
||||
value->rValue = here->DIOpj;
|
||||
return(OK);
|
||||
case DIO_W:
|
||||
value->rValue = here->DIOw;
|
||||
return(OK);
|
||||
case DIO_L:
|
||||
value->rValue = here->DIOl;
|
||||
return(OK);
|
||||
case DIO_M:
|
||||
value->rValue = here->DIOm;
|
||||
return(OK);
|
||||
|
|
@ -46,7 +52,7 @@ DIOask (CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value,
|
|||
case DIO_TEMP:
|
||||
value->rValue = here->DIOtemp-CONSTCtoK;
|
||||
return(OK);
|
||||
case DIO_DTEMP:
|
||||
case DIO_DTEMP:
|
||||
value->rValue = here->DIOdtemp;
|
||||
return(OK);
|
||||
case DIO_VOLTAGE:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified by Dietmar Warning 2003 and Paolo Nenzi 2003
|
||||
Modified by Paolo Nenzi 2003 and Dietmar Warning 2012
|
||||
**********/
|
||||
#ifndef DIO
|
||||
#define DIO
|
||||
|
|
@ -54,6 +54,8 @@ typedef struct sDIOinstance {
|
|||
unsigned DIOoff : 1; /* 'off' flag for diode */
|
||||
unsigned DIOareaGiven : 1; /* flag to indicate area was specified */
|
||||
unsigned DIOpjGiven : 1; /* flag to indicate perimeter was specified */
|
||||
unsigned DIOwGiven : 1; /* flag to indicate width was specified */
|
||||
unsigned DIOlGiven : 1; /* flag to indicate length was specified */
|
||||
unsigned DIOmGiven : 1; /* flag to indicate multiplier was specified */
|
||||
|
||||
unsigned DIOinitCondGiven : 1; /* flag to indicate ic was specified */
|
||||
|
|
@ -63,8 +65,10 @@ typedef struct sDIOinstance {
|
|||
unsigned DIOdtempGiven : 1; /* flag to indicate dtemp given */
|
||||
|
||||
double DIOarea; /* area factor for the diode */
|
||||
double DIOpj; /* perimeter for the diode */
|
||||
double DIOm; /* multiplier for the diode */
|
||||
double DIOpj; /* perimeter for the diode */
|
||||
double DIOw; /* width for the diode */
|
||||
double DIOl; /* length for the diode */
|
||||
double DIOm; /* multiplier for the diode */
|
||||
|
||||
double DIOinitCond; /* initial condition */
|
||||
double DIOtemp; /* temperature of the instance */
|
||||
|
|
@ -81,6 +85,8 @@ typedef struct sDIOinstance {
|
|||
/* the curve matching (Fc * Vj ) */
|
||||
double DIOtSatCur; /* temperature adjusted saturation current */
|
||||
double DIOtSatSWCur; /* temperature adjusted side wall saturation current */
|
||||
double DIOtTunSatCur; /* tunneling saturation current */
|
||||
double DIOtTunSatSWCur; /* sidewall tunneling saturation current */
|
||||
|
||||
double DIOtVcrit; /* temperature adjusted V crit */
|
||||
double DIOtF1; /* temperature adjusted f1 */
|
||||
|
|
@ -91,6 +97,11 @@ typedef struct sDIOinstance {
|
|||
double DIOtF2SW; /* coeff. for capacitance equation precomputation */
|
||||
double DIOtF3SW; /* coeff. for capacitance equation precomputation */
|
||||
|
||||
double DIOforwardKneeCurrent; /* Forward Knee current */
|
||||
double DIOreverseKneeCurrent; /* Reverse Knee current */
|
||||
double DIOjunctionCap; /* geometry adjusted junction capacitance */
|
||||
double DIOjunctionSWCap; /* geometry adjusted junction sidewall capacitance */
|
||||
|
||||
/*
|
||||
* naming convention:
|
||||
* x = vdiode
|
||||
|
|
@ -98,38 +109,38 @@ typedef struct sDIOinstance {
|
|||
|
||||
/* the following are relevant to s.s. sinusoidal distortion analysis */
|
||||
|
||||
#define DIONDCOEFFS 6
|
||||
#define DIONDCOEFFS 6
|
||||
|
||||
#ifndef NODISTO
|
||||
double DIOdCoeffs[DIONDCOEFFS];
|
||||
double DIOdCoeffs[DIONDCOEFFS];
|
||||
#else /* NODISTO */
|
||||
double *DIOdCoeffs;
|
||||
double *DIOdCoeffs;
|
||||
#endif /* NODISTO */
|
||||
|
||||
#ifndef CONFIG
|
||||
|
||||
#define id_x2 DIOdCoeffs[0]
|
||||
#define id_x3 DIOdCoeffs[1]
|
||||
#define cdif_x2 DIOdCoeffs[2]
|
||||
#define cdif_x3 DIOdCoeffs[3]
|
||||
#define cjnc_x2 DIOdCoeffs[4]
|
||||
#define cjnc_x3 DIOdCoeffs[5]
|
||||
#define id_x2 DIOdCoeffs[0]
|
||||
#define id_x3 DIOdCoeffs[1]
|
||||
#define cdif_x2 DIOdCoeffs[2]
|
||||
#define cdif_x3 DIOdCoeffs[3]
|
||||
#define cjnc_x2 DIOdCoeffs[4]
|
||||
#define cjnc_x3 DIOdCoeffs[5]
|
||||
|
||||
#endif
|
||||
|
||||
/* indices to array of diode noise sources */
|
||||
|
||||
#define DIORSNOIZ 0
|
||||
#define DIOIDNOIZ 1
|
||||
#define DIOFLNOIZ 2
|
||||
#define DIOTOTNOIZ 3
|
||||
#define DIORSNOIZ 0
|
||||
#define DIOIDNOIZ 1
|
||||
#define DIOFLNOIZ 2
|
||||
#define DIOTOTNOIZ 3
|
||||
|
||||
#define DIONSRCS 4
|
||||
|
||||
#ifndef NONOISE
|
||||
double DIOnVar[NSTATVARS][DIONSRCS];
|
||||
#else /* NONOISE */
|
||||
double **DIOnVar;
|
||||
double **DIOnVar;
|
||||
#endif /* NONOISE */
|
||||
|
||||
} DIOinstance ;
|
||||
|
|
@ -159,6 +170,7 @@ typedef struct sDIOmodel { /* model structure for a diode */
|
|||
* that have this model */
|
||||
IFuid DIOmodName; /* pointer to character string naming this model */
|
||||
|
||||
unsigned DIOlevelGiven : 1;
|
||||
unsigned DIOsatCurGiven : 1;
|
||||
unsigned DIOsatSWCurGiven : 1;
|
||||
|
||||
|
|
@ -166,6 +178,8 @@ typedef struct sDIOmodel { /* model structure for a diode */
|
|||
unsigned DIOresistTemp1Given : 1;
|
||||
unsigned DIOresistTemp2Given : 1;
|
||||
unsigned DIOemissionCoeffGiven : 1;
|
||||
unsigned DIOswEmissionCoeffGiven : 1;
|
||||
unsigned DIObrkdEmissionCoeffGiven : 1;
|
||||
unsigned DIOtransitTimeGiven : 1;
|
||||
unsigned DIOtranTimeTemp1Given : 1;
|
||||
unsigned DIOtranTimeTemp2Given : 1;
|
||||
|
|
@ -196,7 +210,16 @@ typedef struct sDIOmodel { /* model structure for a diode */
|
|||
unsigned DIOnomTempGiven : 1;
|
||||
unsigned DIOfNcoefGiven : 1;
|
||||
unsigned DIOfNexpGiven : 1;
|
||||
unsigned DIOareaGiven : 1;
|
||||
unsigned DIOpjGiven : 1;
|
||||
|
||||
unsigned DIOtunSatCurGiven : 1;
|
||||
unsigned DIOtunSatSWCurGiven : 1;
|
||||
unsigned DIOtunEmissionCoeffGiven : 1;
|
||||
unsigned DIOtunSaturationCurrentExpGiven : 1;
|
||||
unsigned DIOtunEGcorrectionFactorGiven : 1;
|
||||
|
||||
int DIOlevel; /* level selector */
|
||||
double DIOsatCur; /* saturation current */
|
||||
double DIOsatSWCur; /* Sidewall saturation current */
|
||||
|
||||
|
|
@ -205,6 +228,8 @@ typedef struct sDIOmodel { /* model structure for a diode */
|
|||
double DIOresistTemp2; /* series resistance 2nd order temp. coeff. */
|
||||
double DIOconductance; /* conductance corresponding to ohmic R */
|
||||
double DIOemissionCoeff; /* emission coefficient (N) */
|
||||
double DIOswEmissionCoeff; /* Sidewall emission coefficient (NS) */
|
||||
double DIObrkdEmissionCoeff; /* Breakdown emission coefficient (NBV) */
|
||||
double DIOtransitTime; /* transit time (TT) */
|
||||
double DIOtranTimeTemp1; /* transit time 1st order coefficient */
|
||||
double DIOtranTimeTemp2; /* transit time 2nd order coefficient */
|
||||
|
|
@ -216,8 +241,8 @@ typedef struct sDIOmodel { /* model structure for a diode */
|
|||
double DIOjunctionSWCap; /* Sidewall Junction Capacitance (Cjsw) */
|
||||
double DIOjunctionSWPot; /* Sidewall Junction Potential (Vjsw) or (PBSW) */
|
||||
double DIOgradingSWCoeff; /* Sidewall grading coefficient (mjsw) */
|
||||
double DIOforwardKneeCurrent; /* Forward Knee current */
|
||||
double DIOreverseKneeCurrent; /* Reverse Knee current */
|
||||
double DIOforwardKneeCurrent; /* Forward Knee current (IKF) */
|
||||
double DIOreverseKneeCurrent; /* Reverse Knee current (IKR) */
|
||||
|
||||
int DIOtlev; /* Diode temperature equation selector */
|
||||
int DIOtlevc; /* Diode temperature equation selector */
|
||||
|
|
@ -232,11 +257,19 @@ typedef struct sDIOmodel { /* model structure for a diode */
|
|||
double DIObreakdownVoltage; /* Voltage at reverse breakdown */
|
||||
double DIObreakdownCurrent; /* Current at above voltage */
|
||||
double DIOtcv; /* Reverse breakdown voltage temperature coefficient */
|
||||
double DIOarea; /* area factor for the diode */
|
||||
double DIOpj; /* perimeter for the diode */
|
||||
|
||||
double DIOnomTemp; /* nominal temperature (temp at which parms measured */
|
||||
double DIOnomTemp; /* nominal temperature at which parms measured */
|
||||
double DIOfNcoef;
|
||||
double DIOfNexp;
|
||||
|
||||
double DIOtunSatCur; /* tunneling saturation current (JTUN) */
|
||||
double DIOtunSatSWCur; /* sidewall tunneling saturation current (JTUNSW) */
|
||||
double DIOtunEmissionCoeff; /* tunneling emission coefficient (NTUN) */
|
||||
double DIOtunSaturationCurrentExp; /* exponent for the tunneling current temperature (XTITUN) */
|
||||
double DIOtunEGcorrectionFactor; /* EG correction factor for tunneling (KEG) */
|
||||
|
||||
} DIOmodel;
|
||||
|
||||
/* device parameters */
|
||||
|
|
@ -251,18 +284,21 @@ typedef struct sDIOmodel { /* model structure for a diode */
|
|||
#define DIO_AREA_SENS 9
|
||||
#define DIO_POWER 10
|
||||
#define DIO_TEMP 11
|
||||
#define DIO_QUEST_SENS_REAL 12
|
||||
#define DIO_QUEST_SENS_IMAG 13
|
||||
#define DIO_QUEST_SENS_MAG 14
|
||||
#define DIO_QUEST_SENS_PH 15
|
||||
#define DIO_QUEST_SENS_CPLX 16
|
||||
#define DIO_QUEST_SENS_DC 17
|
||||
#define DIO_QUEST_SENS_REAL 12
|
||||
#define DIO_QUEST_SENS_IMAG 13
|
||||
#define DIO_QUEST_SENS_MAG 14
|
||||
#define DIO_QUEST_SENS_PH 15
|
||||
#define DIO_QUEST_SENS_CPLX 16
|
||||
#define DIO_QUEST_SENS_DC 17
|
||||
#define DIO_CAP 18
|
||||
#define DIO_PJ 19
|
||||
#define DIO_M 20
|
||||
#define DIO_DTEMP 21
|
||||
#define DIO_W 20
|
||||
#define DIO_L 21
|
||||
#define DIO_M 22
|
||||
#define DIO_DTEMP 23
|
||||
|
||||
/* model parameters */
|
||||
#define DIO_MOD_LEVEL 100
|
||||
#define DIO_MOD_IS 101
|
||||
#define DIO_MOD_RS 102
|
||||
#define DIO_MOD_N 103
|
||||
|
|
@ -300,6 +336,15 @@ typedef struct sDIOmodel { /* model structure for a diode */
|
|||
#define DIO_MOD_TPB 135
|
||||
#define DIO_MOD_TPHP 136
|
||||
#define DIO_MOD_TCV 137
|
||||
#define DIO_MOD_NBV 138
|
||||
#define DIO_MOD_AREA 139
|
||||
#define DIO_MOD_PJ 140
|
||||
#define DIO_MOD_NS 141
|
||||
#define DIO_MOD_JTUN 142
|
||||
#define DIO_MOD_JTUNSW 143
|
||||
#define DIO_MOD_NTUN 144
|
||||
#define DIO_MOD_XTITUN 145
|
||||
#define DIO_MOD_KEG 146
|
||||
|
||||
#include "dioext.h"
|
||||
#endif /*DIO*/
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
Modified by Dietmar Warning 2003 and Paolo Nenzi 2003
|
||||
Modified by Paolo Nenzi 2003 and Dietmar Warning 2012
|
||||
**********/
|
||||
|
||||
#include "ngspice/ngspice.h"
|
||||
|
|
@ -23,12 +23,14 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
DIOmodel *model = (DIOmodel*)inModel;
|
||||
DIOinstance *here;
|
||||
double arg;
|
||||
double argsw;
|
||||
double capd;
|
||||
double cd;
|
||||
double cd, cdsw=0.0;
|
||||
double cdeq;
|
||||
double cdhat;
|
||||
double ceq;
|
||||
double csat; /* area-scaled saturation current */
|
||||
double csatsw; /* perimeter-scaled saturation current */
|
||||
double czero;
|
||||
double czof2;
|
||||
double argSW;
|
||||
|
|
@ -42,8 +44,9 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
|
||||
double delvd; /* change in diode voltage temporary */
|
||||
double evd;
|
||||
double evdsw;
|
||||
double evrev;
|
||||
double gd;
|
||||
double gd, gdsw=0.0;
|
||||
double geq;
|
||||
double gspr; /* area-scaled conductance */
|
||||
double sarg;
|
||||
|
|
@ -53,7 +56,8 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
double vd; /* current diode voltage */
|
||||
double vdtemp;
|
||||
double vt; /* K t / Q */
|
||||
double vte;
|
||||
double vte, vtesw, vtetun;
|
||||
double vtebrk;
|
||||
int Check;
|
||||
int error;
|
||||
int SenCond=0; /* sensitivity condition */
|
||||
|
|
@ -81,10 +85,12 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
#endif /* SENSDEBUG */
|
||||
|
||||
}
|
||||
csat=(here->DIOtSatCur*here->DIOarea+here->DIOtSatSWCur*here->DIOpj)*here->DIOm;
|
||||
gspr=here->DIOtConductance*here->DIOarea*here->DIOm;
|
||||
csat = here->DIOtSatCur;
|
||||
csatsw = here->DIOtSatSWCur;
|
||||
gspr = here->DIOtConductance * here->DIOarea;
|
||||
vt = CONSTKoverQ * here->DIOtemp;
|
||||
vte=model->DIOemissionCoeff * vt;
|
||||
vte = model->DIOemissionCoeff * vt;
|
||||
vtebrk = model->DIObrkdEmissionCoeff * vt;
|
||||
/*
|
||||
* initialization
|
||||
*/
|
||||
|
|
@ -167,11 +173,11 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
* limit new junction voltage
|
||||
*/
|
||||
if ( (model->DIObreakdownVoltageGiven) &&
|
||||
(vd < MIN(0,-here->DIOtBrkdwnV+10*vte))) {
|
||||
(vd < MIN(0,-here->DIOtBrkdwnV+10*vtebrk))) {
|
||||
vdtemp = -(vd+here->DIOtBrkdwnV);
|
||||
vdtemp = DEVpnjlim(vdtemp,
|
||||
-(*(ckt->CKTstate0 + here->DIOvoltage) +
|
||||
here->DIOtBrkdwnV),vte,
|
||||
here->DIOtBrkdwnV),vtebrk,
|
||||
here->DIOtVcrit,&Check);
|
||||
vd = -(vdtemp+here->DIOtBrkdwnV);
|
||||
} else {
|
||||
|
|
@ -182,61 +188,152 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
/*
|
||||
* compute dc current and derivitives
|
||||
*/
|
||||
next1: if (vd >= -3*vte) { /* forward */
|
||||
next1: if (model->DIOsatSWCurGiven) { /* consider sidewall currents */
|
||||
|
||||
evd = exp(vd/vte);
|
||||
cd = csat*(evd-1) + ckt->CKTgmin*vd;
|
||||
gd = csat*evd/vte + ckt->CKTgmin;
|
||||
if (model->DIOswEmissionCoeffGiven) { /* sidewall currents with own characteristic */
|
||||
|
||||
if( (model->DIOforwardKneeCurrent > 0.0) && (cd > 1.0e-18) ) {
|
||||
gd = gd-ckt->CKTgmin;
|
||||
cd = cd-ckt->CKTgmin*vd;
|
||||
ikf_area_m = model->DIOforwardKneeCurrent*here->DIOarea*here->DIOm;
|
||||
sqrt_ikf = sqrt(cd/ikf_area_m);
|
||||
gd = ((1+sqrt_ikf)*gd - cd*gd/(2*sqrt_ikf*ikf_area_m))/(1+2*sqrt_ikf+cd/ikf_area_m)+ckt->CKTgmin;
|
||||
cd = cd/(1+sqrt_ikf)+ckt->CKTgmin*vd;
|
||||
}
|
||||
vtesw = model->DIOswEmissionCoeff * vt;
|
||||
|
||||
} else if((!(model->DIObreakdownVoltageGiven)) || /* reverse */
|
||||
vd >= -here->DIOtBrkdwnV) {
|
||||
if (vd >= -3*vtesw) { /* sidewall forward */
|
||||
|
||||
arg = 3*vte/(vd*CONSTe);
|
||||
arg = arg * arg * arg;
|
||||
cd = -csat*(1+arg) + ckt->CKTgmin*vd ;
|
||||
gd = csat*3*arg/vd + ckt->CKTgmin;
|
||||
evdsw = exp(vd/vtesw);
|
||||
cdsw = csatsw*(evdsw-1);
|
||||
gdsw = csatsw*evdsw/vtesw;
|
||||
if (model->DIOtunSatSWCurGiven) {
|
||||
vtetun = model->DIOtunEmissionCoeff * vt;
|
||||
evd = exp(-vd/vtetun);
|
||||
cdsw = cdsw - here->DIOtTunSatSWCur * (evd - 1);
|
||||
gdsw = gdsw + here->DIOtTunSatSWCur * evd / vtetun;
|
||||
}
|
||||
|
||||
if( (model->DIOreverseKneeCurrent > 0.0) && (cd < -1.0e-18) ) {
|
||||
gd = gd-ckt->CKTgmin;
|
||||
cd = cd-ckt->CKTgmin*vd;
|
||||
ikr_area_m = model->DIOreverseKneeCurrent*here->DIOarea*here->DIOm;
|
||||
sqrt_ikr = sqrt(cd/(-ikr_area_m));
|
||||
gd = ((1+sqrt_ikr)*gd + cd*gd/(2*sqrt_ikr*ikr_area_m))/(1+2*sqrt_ikr - cd/ikr_area_m)+ckt->CKTgmin;
|
||||
cd = cd/(1+sqrt_ikr)+ckt->CKTgmin*vd;
|
||||
}
|
||||
} else if((!(model->DIObreakdownVoltageGiven)) || /* sidewall reverse */
|
||||
vd >= -here->DIOtBrkdwnV) {
|
||||
|
||||
} else { /* breakdown */
|
||||
if (model->DIOtunSatSWCurGiven) {
|
||||
evdsw = exp(vd/vtesw);
|
||||
cdsw = csatsw*(evdsw-1);
|
||||
gdsw = csatsw*evdsw/vtesw;
|
||||
vtetun = model->DIOtunEmissionCoeff * vt;
|
||||
evdsw = exp(-vd/vtetun);
|
||||
cdsw = cdsw - here->DIOtTunSatSWCur * (evdsw - 1);
|
||||
gdsw = gdsw + here->DIOtTunSatSWCur * evdsw / vtetun;
|
||||
} else {
|
||||
argsw = 3*vtesw/(vd*CONSTe);
|
||||
argsw = argsw * argsw * argsw;
|
||||
cdsw = -csatsw*(1+argsw);
|
||||
gdsw = csatsw*3*argsw/vd;
|
||||
}
|
||||
|
||||
evrev = exp(-(here->DIOtBrkdwnV+vd)/vte);
|
||||
cd = -csat*evrev + ckt->CKTgmin*vd;
|
||||
gd = csat*evrev/vte + ckt->CKTgmin;
|
||||
} else { /* sidewall breakdown */
|
||||
|
||||
evrev = exp(-(here->DIOtBrkdwnV+vd)/vtebrk);
|
||||
cdsw = -csatsw*evrev;
|
||||
gdsw = csatsw*evrev/vtebrk;
|
||||
if (model->DIOtunSatSWCurGiven) {
|
||||
evd = exp(vd/vte);
|
||||
cdsw = cdsw - csatsw*(evd-1);
|
||||
gdsw = gdsw - csatsw*evd/vte;
|
||||
vtetun = model->DIOtunEmissionCoeff * vt;
|
||||
evd = exp(-vd/vtetun);
|
||||
cdsw = cdsw - here->DIOtTunSatSWCur * (evd - 1);
|
||||
gdsw = gdsw + here->DIOtTunSatSWCur * evd / vtetun;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else { /* merge the current densities and use same characteristic as bottom diode */
|
||||
|
||||
csat = csat + csatsw;
|
||||
|
||||
if( (model->DIOreverseKneeCurrent > 0.0) && (cd < -1.0e-18) ) {
|
||||
gd = gd-ckt->CKTgmin;
|
||||
cd = cd-ckt->CKTgmin*vd;
|
||||
ikr_area_m = model->DIOreverseKneeCurrent*here->DIOarea*here->DIOm;
|
||||
sqrt_ikr = sqrt(cd/(-ikr_area_m));
|
||||
gd = ((1+sqrt_ikr)*gd + cd*gd/(2*sqrt_ikr*ikr_area_m))/(1+2*sqrt_ikr - cd/ikr_area_m)+ckt->CKTgmin;
|
||||
cd = cd/(1+sqrt_ikr)+ckt->CKTgmin*vd;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (vd >= -3*vte) { /* bottom forward */
|
||||
|
||||
evd = exp(vd/vte);
|
||||
cd = csat*(evd-1);
|
||||
gd = csat*evd/vte;
|
||||
if (model->DIOtunSatCurGiven) {
|
||||
vtetun = model->DIOtunEmissionCoeff * vt;
|
||||
evd = exp(-vd/vtetun);
|
||||
cd = cd - here->DIOtTunSatCur * (evd - 1);
|
||||
gd = gd + here->DIOtTunSatCur * evd / vtetun;
|
||||
}
|
||||
|
||||
} else if((!(model->DIObreakdownVoltageGiven)) || /* bottom reverse */
|
||||
vd >= -here->DIOtBrkdwnV) {
|
||||
|
||||
if (model->DIOtunSatCurGiven) {
|
||||
evd = exp(vd/vte);
|
||||
cd = csat*(evd-1);
|
||||
gd = csat*evd/vte;
|
||||
vtetun = model->DIOtunEmissionCoeff * vt;
|
||||
evd = exp(-vd/vtetun);
|
||||
cd = cd - here->DIOtTunSatCur * (evd - 1);
|
||||
gd = gd + here->DIOtTunSatCur * evd / vtetun;
|
||||
} else {
|
||||
arg = 3*vte/(vd*CONSTe);
|
||||
arg = arg * arg * arg;
|
||||
cd = -csat*(1+arg);
|
||||
gd = csat*3*arg/vd;
|
||||
}
|
||||
|
||||
} else { /* bottom breakdown */
|
||||
|
||||
evrev = exp(-(here->DIOtBrkdwnV+vd)/vtebrk);
|
||||
cd = -csat*evrev;
|
||||
gd = csat*evrev/vtebrk;
|
||||
if (model->DIOtunSatCurGiven) {
|
||||
evd = exp(vd/vte);
|
||||
cd = cd - csat*(evd-1);
|
||||
gd = gd - csat*evd/vte;
|
||||
vtetun = model->DIOtunEmissionCoeff * vt;
|
||||
evd = exp(-vd/vtetun);
|
||||
cd = cd - here->DIOtTunSatCur * (evd - 1);
|
||||
gd = gd + here->DIOtTunSatCur * evd / vtetun;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (model->DIOsatSWCurGiven) {
|
||||
|
||||
if (model->DIOswEmissionCoeffGiven) {
|
||||
|
||||
cd = cdsw + cd;
|
||||
gd = gdsw + gd;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (vd >= -3*vte) { /* limit forward */
|
||||
|
||||
if( (model->DIOforwardKneeCurrent > 0.0) && (cd > 1.0e-18) ) {
|
||||
ikf_area_m = here->DIOforwardKneeCurrent;
|
||||
sqrt_ikf = sqrt(cd/ikf_area_m);
|
||||
gd = ((1+sqrt_ikf)*gd - cd*gd/(2*sqrt_ikf*ikf_area_m))/(1+2*sqrt_ikf + cd/ikf_area_m) + ckt->CKTgmin*vd;
|
||||
cd = cd/(1+sqrt_ikf) + ckt->CKTgmin;
|
||||
}
|
||||
|
||||
} else { /* limit reverse */
|
||||
|
||||
if( (model->DIOreverseKneeCurrent > 0.0) && (cd < -1.0e-18) ) {
|
||||
ikr_area_m = here->DIOreverseKneeCurrent;
|
||||
sqrt_ikr = sqrt(cd/(-ikr_area_m));
|
||||
gd = ((1+sqrt_ikr)*gd + cd*gd/(2*sqrt_ikr*ikr_area_m))/(1+2*sqrt_ikr - cd/ikr_area_m) + ckt->CKTgmin*vd;
|
||||
cd = cd/(1+sqrt_ikr) + ckt->CKTgmin;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ((ckt->CKTmode & (MODETRAN | MODEAC | MODEINITSMSIG)) ||
|
||||
((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))) {
|
||||
/*
|
||||
* charge storage elements
|
||||
*/
|
||||
czero=here->DIOtJctCap*here->DIOarea*here->DIOm;
|
||||
czeroSW=here->DIOtJctSWCap*here->DIOpj*here->DIOm;
|
||||
czero=here->DIOtJctCap*here->DIOarea;
|
||||
czeroSW=here->DIOtJctSWCap*here->DIOpj;
|
||||
if (vd < here->DIOtDepCap){
|
||||
arg=1-vd/here->DIOtJctPot;
|
||||
argSW=1-vd/here->DIOtJctSWPot;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified by Dietmar Warning 2003 and Paolo Nenzi 2003
|
||||
Modified by Paolo Nenzi 2003 and Dietmar Warning 2012
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
|
@ -24,6 +24,9 @@ DIOmAsk (CKTcircuit *ckt, GENmodel *inModel, int which, IFvalue *value)
|
|||
NG_IGNORE(ckt);
|
||||
|
||||
switch (which) {
|
||||
case DIO_MOD_LEVEL:
|
||||
value->iValue = model->DIOlevel;
|
||||
return (OK);
|
||||
case DIO_MOD_IS:
|
||||
value->rValue = model->DIOsatCur;
|
||||
return(OK);
|
||||
|
|
@ -46,6 +49,9 @@ DIOmAsk (CKTcircuit *ckt, GENmodel *inModel, int which, IFvalue *value)
|
|||
case DIO_MOD_N:
|
||||
value->rValue = model->DIOemissionCoeff;
|
||||
return(OK);
|
||||
case DIO_MOD_NS:
|
||||
value->rValue = model->DIOswEmissionCoeff;
|
||||
return(OK);
|
||||
case DIO_MOD_TT:
|
||||
value->rValue = model->DIOtransitTime;
|
||||
return(OK);
|
||||
|
|
@ -85,6 +91,9 @@ DIOmAsk (CKTcircuit *ckt, GENmodel *inModel, int which, IFvalue *value)
|
|||
case DIO_MOD_IKR:
|
||||
value->rValue = model->DIOreverseKneeCurrent;
|
||||
return(OK);
|
||||
case DIO_MOD_NBV:
|
||||
value->rValue = model->DIObrkdEmissionCoeff;
|
||||
return(OK);
|
||||
|
||||
case DIO_MOD_TLEV:
|
||||
value->iValue = model->DIOtlev;
|
||||
|
|
@ -131,9 +140,30 @@ DIOmAsk (CKTcircuit *ckt, GENmodel *inModel, int which, IFvalue *value)
|
|||
case DIO_MOD_TCV:
|
||||
value->rValue = model->DIOtcv;
|
||||
return(OK);
|
||||
case DIO_MOD_AREA:
|
||||
value->rValue = model->DIOarea;
|
||||
return(OK);
|
||||
case DIO_MOD_PJ:
|
||||
value->rValue = model->DIOpj;
|
||||
return(OK);
|
||||
case DIO_MOD_COND:
|
||||
value->rValue = model->DIOconductance;
|
||||
return(OK);
|
||||
case DIO_MOD_JTUN:
|
||||
value->rValue = model->DIOtunSatCur;
|
||||
return(OK);
|
||||
case DIO_MOD_JTUNSW:
|
||||
value->rValue = model->DIOtunSatSWCur;
|
||||
return(OK);
|
||||
case DIO_MOD_NTUN:
|
||||
value->rValue = model->DIOtunEmissionCoeff;
|
||||
return(OK);
|
||||
case DIO_MOD_XTITUN:
|
||||
value->rValue = model->DIOtunSaturationCurrentExp;
|
||||
return(OK);
|
||||
case DIO_MOD_KEG:
|
||||
value->rValue = model->DIOtunEGcorrectionFactor;
|
||||
return(OK);
|
||||
default:
|
||||
return(E_BADPARM);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified by Dietmar Warning 2003 and Paolo Nenzi 2003
|
||||
Modified by Paolo Nenzi 2003 and Dietmar Warning 2012
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
|
@ -19,6 +19,10 @@ DIOmParam(int param, IFvalue *value, GENmodel *inModel)
|
|||
{
|
||||
DIOmodel *model = (DIOmodel*)inModel;
|
||||
switch(param) {
|
||||
case DIO_MOD_LEVEL:
|
||||
model->DIOlevel = value->iValue;
|
||||
model->DIOlevelGiven = TRUE;
|
||||
break;
|
||||
case DIO_MOD_IS:
|
||||
model->DIOsatCur = value->rValue;
|
||||
model->DIOsatCurGiven = TRUE;
|
||||
|
|
@ -48,6 +52,10 @@ DIOmParam(int param, IFvalue *value, GENmodel *inModel)
|
|||
model->DIOemissionCoeff = value->rValue;
|
||||
model->DIOemissionCoeffGiven = TRUE;
|
||||
break;
|
||||
case DIO_MOD_NS:
|
||||
model->DIOswEmissionCoeff = value->rValue;
|
||||
model->DIOswEmissionCoeffGiven = TRUE;
|
||||
break;
|
||||
case DIO_MOD_TT:
|
||||
model->DIOtransitTime = value->rValue;
|
||||
model->DIOtransitTimeGiven = TRUE;
|
||||
|
|
@ -100,6 +108,18 @@ DIOmParam(int param, IFvalue *value, GENmodel *inModel)
|
|||
model->DIOreverseKneeCurrent = value->rValue;
|
||||
model->DIOreverseKneeCurrentGiven = TRUE;
|
||||
break;
|
||||
case DIO_MOD_NBV:
|
||||
model->DIObrkdEmissionCoeff = value->rValue;
|
||||
model->DIObrkdEmissionCoeffGiven = TRUE;
|
||||
break;
|
||||
case DIO_MOD_AREA:
|
||||
model->DIOarea = value->rValue;
|
||||
model->DIOareaGiven = TRUE;
|
||||
break;
|
||||
case DIO_MOD_PJ:
|
||||
model->DIOpj = value->rValue;
|
||||
model->DIOpjGiven = TRUE;
|
||||
break;
|
||||
|
||||
case DIO_MOD_TLEV:
|
||||
model->DIOtlev = value->iValue;
|
||||
|
|
@ -153,10 +173,6 @@ DIOmParam(int param, IFvalue *value, GENmodel *inModel)
|
|||
model->DIOtcv = value->rValue;
|
||||
model->DIOtcvGiven = TRUE;
|
||||
break;
|
||||
case DIO_MOD_D:
|
||||
/* no action - we already know we are a diode, but this */
|
||||
/* makes life easier for spice-2 like parsers */
|
||||
break;
|
||||
case DIO_MOD_KF:
|
||||
model->DIOfNcoef = value->rValue;
|
||||
model->DIOfNcoefGiven = TRUE;
|
||||
|
|
@ -165,6 +181,30 @@ DIOmParam(int param, IFvalue *value, GENmodel *inModel)
|
|||
model->DIOfNexp = value->rValue;
|
||||
model->DIOfNexpGiven = TRUE;
|
||||
break;
|
||||
case DIO_MOD_JTUN:
|
||||
model->DIOtunSatCur = value->rValue;
|
||||
model->DIOtunSatCurGiven = TRUE;
|
||||
break;
|
||||
case DIO_MOD_JTUNSW:
|
||||
model->DIOtunSatSWCur = value->rValue;
|
||||
model->DIOtunSatSWCurGiven = TRUE;
|
||||
break;
|
||||
case DIO_MOD_NTUN:
|
||||
model->DIOtunEmissionCoeff = value->rValue;
|
||||
model->DIOtunEmissionCoeffGiven = TRUE;
|
||||
break;
|
||||
case DIO_MOD_XTITUN:
|
||||
model->DIOtunSaturationCurrentExp = value->rValue;
|
||||
model->DIOtunSaturationCurrentExpGiven = TRUE;
|
||||
break;
|
||||
case DIO_MOD_KEG:
|
||||
model->DIOtunEGcorrectionFactor = value->rValue;
|
||||
model->DIOtunEGcorrectionFactorGiven = TRUE;
|
||||
break;
|
||||
case DIO_MOD_D:
|
||||
/* no action - we already know we are a diode, but this */
|
||||
/* makes life easier for spice-2 like parsers */
|
||||
break;
|
||||
default:
|
||||
return(E_BADPARM);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified by Dietmar Warning 2003 and Paolo Nenzi 2003
|
||||
Modified by Paolo Nenzi 2003 and Dietmar Warning 2012
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
|
@ -31,6 +31,14 @@ DIOparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
|
|||
here->DIOpj = value->rValue;
|
||||
here->DIOpjGiven = TRUE;
|
||||
break;
|
||||
case DIO_W:
|
||||
here->DIOw = value->rValue;
|
||||
here->DIOwGiven = TRUE;
|
||||
break;
|
||||
case DIO_L:
|
||||
here->DIOl = value->rValue;
|
||||
here->DIOlGiven = TRUE;
|
||||
break;
|
||||
case DIO_M:
|
||||
here->DIOm = value->rValue;
|
||||
here->DIOmGiven = TRUE;
|
||||
|
|
@ -40,7 +48,7 @@ DIOparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
|
|||
here->DIOtemp = value->rValue+CONSTCtoK;
|
||||
here->DIOtempGiven = TRUE;
|
||||
break;
|
||||
case DIO_DTEMP:
|
||||
case DIO_DTEMP:
|
||||
here->DIOdtemp = value->rValue;
|
||||
here->DIOdtempGiven = TRUE;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ DIOpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s)
|
|||
/* loop through all the instances of the model */
|
||||
for (here = model->DIOinstances; here != NULL ;
|
||||
here=here->DIOnextInstance) {
|
||||
if (here->DIOowner != ARCHme) continue;
|
||||
gspr=here->DIOtConductance*here->DIOarea*here->DIOm;
|
||||
if (here->DIOowner != ARCHme) continue;
|
||||
gspr=here->DIOtConductance*here->DIOarea;
|
||||
geq= *(ckt->CKTstate0 + here->DIOconduct);
|
||||
xceq= *(ckt->CKTstate0 + here->DIOcapCurrent);
|
||||
*(here->DIOposPosPtr ) += gspr;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
Modified by Dietmar Warning 2003 and Paolo Nenzi 2003
|
||||
Modified by Paolo Nenzi 2003 and Dietmar Warning 2012
|
||||
**********/
|
||||
|
||||
/* load the diode structure with those pointers needed later
|
||||
|
|
@ -27,6 +27,9 @@ DIOsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
|||
/* loop through all the diode models */
|
||||
for( ; model != NULL; model = model->DIOnextModel ) {
|
||||
|
||||
if(!model->DIOlevelGiven) {
|
||||
model->DIOlevel = 1;
|
||||
}
|
||||
if(!model->DIOemissionCoeffGiven) {
|
||||
model->DIOemissionCoeff = 1;
|
||||
}
|
||||
|
|
@ -36,6 +39,9 @@ DIOsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
|||
if(!model->DIOsatSWCurGiven) {
|
||||
model->DIOsatSWCur = 0.0;
|
||||
}
|
||||
if(!model->DIOswEmissionCoeffGiven) {
|
||||
model->DIOswEmissionCoeff = 1;
|
||||
}
|
||||
if(!model->DIObreakdownCurrentGiven) {
|
||||
model->DIObreakdownCurrent = 1e-3;
|
||||
}
|
||||
|
|
@ -84,6 +90,9 @@ DIOsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
|||
if(!model->DIOreverseKneeCurrentGiven) {
|
||||
model->DIOreverseKneeCurrent = 0.0;
|
||||
}
|
||||
if(!model->DIObrkdEmissionCoeffGiven) {
|
||||
model->DIObrkdEmissionCoeff = model->DIOemissionCoeff;
|
||||
}
|
||||
if(!model->DIOtlevGiven) {
|
||||
model->DIOtlev = 0;
|
||||
}
|
||||
|
|
@ -123,21 +132,65 @@ DIOsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
|||
if(!model->DIOtcvGiven) {
|
||||
model->DIOtcv = 0.0;
|
||||
}
|
||||
if(!model->DIOareaGiven) {
|
||||
model->DIOarea = 1.0;
|
||||
}
|
||||
if(!model->DIOpjGiven) {
|
||||
model->DIOpj = 0.0;
|
||||
}
|
||||
if(!model->DIOtunSatCurGiven) {
|
||||
model->DIOtunSatCur = 0.0;
|
||||
}
|
||||
if(!model->DIOtunSatSWCurGiven) {
|
||||
model->DIOtunSatSWCur = 0.0;
|
||||
}
|
||||
if(!model->DIOtunEmissionCoeffGiven) {
|
||||
model->DIOtunEmissionCoeff = 30.0;
|
||||
}
|
||||
if(!model->DIOtunSaturationCurrentExpGiven) {
|
||||
model->DIOtunSaturationCurrentExp = 3.0;
|
||||
}
|
||||
if(!model->DIOtunEGcorrectionFactorGiven) {
|
||||
model->DIOtunEGcorrectionFactor = 1.0;
|
||||
}
|
||||
|
||||
/* loop through all the instances of the model */
|
||||
for (here = model->DIOinstances; here != NULL ;
|
||||
here=here->DIOnextInstance) {
|
||||
if (here->DIOowner != ARCHme) goto matrixpointers;
|
||||
|
||||
if(!here->DIOareaGiven) {
|
||||
here->DIOarea = 1;
|
||||
if((!here->DIOwGiven) && (!here->DIOlGiven)) {
|
||||
here->DIOarea = model->DIOarea;
|
||||
} else {
|
||||
here->DIOarea = 1;
|
||||
}
|
||||
}
|
||||
if(!here->DIOpjGiven) {
|
||||
here->DIOpj = 0;
|
||||
if((!here->DIOwGiven) && (!here->DIOlGiven)) {
|
||||
here->DIOpj = model->DIOpj;
|
||||
} else {
|
||||
here->DIOpj = 0;
|
||||
}
|
||||
}
|
||||
if(!here->DIOmGiven) {
|
||||
here->DIOm = 1;
|
||||
}
|
||||
|
||||
here->DIOarea = here->DIOarea * here->DIOm;
|
||||
if (model->DIOlevel == 1) {
|
||||
here->DIOpj = here->DIOpj * here->DIOm;
|
||||
} else { /* level=3 */
|
||||
if((here->DIOwGiven) && (here->DIOlGiven)) {
|
||||
here->DIOarea = here->DIOw * here->DIOl * here->DIOm;
|
||||
here->DIOpj = (2 * here->DIOw + 2 * here->DIOl) * here->DIOm;
|
||||
}
|
||||
}
|
||||
here->DIOforwardKneeCurrent = model->DIOforwardKneeCurrent * here->DIOarea;
|
||||
here->DIOreverseKneeCurrent = model->DIOreverseKneeCurrent * here->DIOarea;
|
||||
here->DIOjunctionCap = model->DIOjunctionCap * here->DIOarea;
|
||||
here->DIOjunctionSWCap = model->DIOjunctionSWCap * here->DIOpj;
|
||||
|
||||
here->DIOstate = *states;
|
||||
*states += 5;
|
||||
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN) ){
|
||||
|
|
@ -146,7 +199,9 @@ DIOsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
|||
|
||||
matrixpointers:
|
||||
if(model->DIOresist == 0) {
|
||||
|
||||
here->DIOposPrimeNode = here->DIOposNode;
|
||||
|
||||
} else if(here->DIOposPrimeNode == 0) {
|
||||
|
||||
CKTnode *tmpNode;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
Modified by Dietmar Warning 2003 and Paolo Nenzi 2003
|
||||
Modified by Paolo Nenzi 2003 and Dietmar Warning 2012
|
||||
**********/
|
||||
|
||||
/* perform the temperature update to the diode */
|
||||
|
|
@ -124,7 +124,7 @@ DIOtemp(GENmodel *inModel, CKTcircuit *ckt)
|
|||
if (model->DIOtlevc == 0) {
|
||||
pbo = (model->DIOjunctionPot-pbfact1)/fact1;
|
||||
gmaold = (model->DIOjunctionPot-pbo)/pbo;
|
||||
here->DIOtJctCap = model->DIOjunctionCap /
|
||||
here->DIOtJctCap = here->DIOjunctionCap /
|
||||
(1+here->DIOtGradingCoeff*
|
||||
(400e-6*(model->DIOnomTemp-REFTEMP)-gmaold) );
|
||||
here->DIOtJctPot = pbfact+fact2*pbo;
|
||||
|
|
@ -133,14 +133,14 @@ DIOtemp(GENmodel *inModel, CKTcircuit *ckt)
|
|||
(400e-6*(here->DIOtemp-REFTEMP)-gmanew);
|
||||
} else if (model->DIOtlevc == 1) {
|
||||
here->DIOtJctPot = model->DIOjunctionPot - model->DIOtpb*(here->DIOtemp-REFTEMP);
|
||||
here->DIOtJctCap = model->DIOjunctionCap *
|
||||
here->DIOtJctCap = here->DIOjunctionCap *
|
||||
(model->DIOcta*(here->DIOtemp-REFTEMP));
|
||||
}
|
||||
|
||||
if (model->DIOtlevc == 0) {
|
||||
pboSW = (model->DIOjunctionSWPot-pbfact1)/fact1;
|
||||
gmaSWold = (model->DIOjunctionSWPot-pboSW)/pboSW;
|
||||
here->DIOtJctSWCap = model->DIOjunctionSWCap /
|
||||
here->DIOtJctSWCap = here->DIOjunctionSWCap /
|
||||
(1+model->DIOgradingSWCoeff*
|
||||
(400e-6*(model->DIOnomTemp-REFTEMP)-gmaSWold) );
|
||||
here->DIOtJctSWPot = pbfact+fact2*pboSW;
|
||||
|
|
@ -149,19 +149,30 @@ DIOtemp(GENmodel *inModel, CKTcircuit *ckt)
|
|||
(400e-6*(here->DIOtemp-REFTEMP)-gmaSWnew);
|
||||
} else if (model->DIOtlevc == 1) {
|
||||
here->DIOtJctSWPot = model->DIOjunctionSWPot - model->DIOtphp*(here->DIOtemp-REFTEMP);
|
||||
here->DIOtJctSWCap = model->DIOjunctionSWCap *
|
||||
here->DIOtJctSWCap = here->DIOjunctionSWCap *
|
||||
(model->DIOctp*(here->DIOtemp-REFTEMP));
|
||||
}
|
||||
|
||||
here->DIOtSatCur = model->DIOsatCur * exp(
|
||||
here->DIOtSatCur = model->DIOsatCur * here->DIOarea * exp(
|
||||
((here->DIOtemp/model->DIOnomTemp)-1) *
|
||||
model->DIOactivationEnergy/(model->DIOemissionCoeff*vt) +
|
||||
model->DIOsaturationCurrentExp/model->DIOemissionCoeff*
|
||||
log(here->DIOtemp/model->DIOnomTemp) );
|
||||
here->DIOtSatSWCur = model->DIOsatSWCur * exp(
|
||||
here->DIOtSatSWCur = model->DIOsatSWCur * here->DIOpj * exp(
|
||||
((here->DIOtemp/model->DIOnomTemp)-1) *
|
||||
model->DIOactivationEnergy/(model->DIOemissionCoeff*vt) +
|
||||
model->DIOsaturationCurrentExp/model->DIOemissionCoeff*
|
||||
model->DIOactivationEnergy/(model->DIOswEmissionCoeff*vt) +
|
||||
model->DIOsaturationCurrentExp/model->DIOswEmissionCoeff*
|
||||
log(here->DIOtemp/model->DIOnomTemp) );
|
||||
|
||||
here->DIOtTunSatCur = model->DIOtunSatCur * here->DIOarea * exp(
|
||||
((here->DIOtemp/model->DIOnomTemp)-1) *
|
||||
model->DIOtunEGcorrectionFactor*model->DIOactivationEnergy/(model->DIOtunEmissionCoeff*vt) +
|
||||
model->DIOtunSaturationCurrentExp/model->DIOtunEmissionCoeff*
|
||||
log(here->DIOtemp/model->DIOnomTemp) );
|
||||
here->DIOtTunSatSWCur = model->DIOtunSatSWCur * here->DIOpj * exp(
|
||||
((here->DIOtemp/model->DIOnomTemp)-1) *
|
||||
model->DIOtunEGcorrectionFactor*model->DIOactivationEnergy/(model->DIOtunEmissionCoeff*vt) +
|
||||
model->DIOtunSaturationCurrentExp/model->DIOtunEmissionCoeff*
|
||||
log(here->DIOtemp/model->DIOnomTemp) );
|
||||
|
||||
/* the defintion of f1, just recompute after temperature adjusting
|
||||
|
|
@ -175,17 +186,14 @@ DIOtemp(GENmodel *inModel, CKTcircuit *ckt)
|
|||
/* and Vcrit */
|
||||
vte=model->DIOemissionCoeff*vt;
|
||||
|
||||
here->DIOtVcrit=vte*
|
||||
log(vte/(CONSTroot2*here->DIOtSatCur*here->DIOarea));
|
||||
here->DIOtVcrit = vte * log(vte/(CONSTroot2*here->DIOtSatCur));
|
||||
|
||||
/* and now to compute the breakdown voltage, again, using
|
||||
* temperature adjusted basic parameters */
|
||||
if (model->DIObreakdownVoltageGiven){
|
||||
cbv=model->DIObreakdownCurrent*here->DIOarea*here->DIOm;
|
||||
if (cbv < here->DIOtSatCur*here->DIOarea*here->DIOm *
|
||||
model->DIObreakdownVoltage/vt) {
|
||||
cbv=here->DIOtSatCur*here->DIOarea*here->DIOm *
|
||||
model->DIObreakdownVoltage/vt;
|
||||
cbv=model->DIObreakdownCurrent * here->DIOarea;
|
||||
if (cbv < here->DIOtSatCur * model->DIObreakdownVoltage/vt) {
|
||||
cbv=here->DIOtSatCur * model->DIObreakdownVoltage/vt;
|
||||
#ifdef TRACE
|
||||
emsg = TMALLOC(char, 100);
|
||||
if(emsg == NULL) return(E_NOMEM);
|
||||
|
|
@ -200,14 +208,14 @@ DIOtemp(GENmodel *inModel, CKTcircuit *ckt)
|
|||
xbv=model->DIObreakdownVoltage;
|
||||
} else {
|
||||
tol=ckt->CKTreltol*cbv;
|
||||
xbv=model->DIObreakdownVoltage-vt*log(1+cbv/
|
||||
(here->DIOtSatCur*here->DIOarea*here->DIOm));
|
||||
xbv=model->DIObreakdownVoltage-model->DIObrkdEmissionCoeff*vt*log(1+cbv/
|
||||
(here->DIOtSatCur));
|
||||
iter=0;
|
||||
for(iter=0 ; iter < 25 ; iter++) {
|
||||
xbv=model->DIObreakdownVoltage-vt*log(cbv/
|
||||
(here->DIOtSatCur*here->DIOarea*here->DIOm)+1-xbv/vt);
|
||||
xcbv=here->DIOtSatCur*here->DIOarea*here->DIOm *
|
||||
(exp((model->DIObreakdownVoltage-xbv)/vt)-1+xbv/vt);
|
||||
xbv=model->DIObreakdownVoltage-model->DIObrkdEmissionCoeff*vt*log(cbv/
|
||||
(here->DIOtSatCur)+1-xbv/vt);
|
||||
xcbv=here->DIOtSatCur *
|
||||
(exp((model->DIObreakdownVoltage-xbv)/(model->DIObrkdEmissionCoeff*vt))-1+xbv/vt);
|
||||
if (fabs(xcbv-cbv) <= tol) goto matched;
|
||||
}
|
||||
#ifdef TRACE
|
||||
|
|
|
|||
Loading…
Reference in New Issue