Browse Source

new scalable diode model including tunnel component

dwarning 14 years ago
parent
commit
dcc22ada60
  1. 40
      src/spicelib/devices/dio/dio.c
  2. 4
      src/spicelib/devices/dio/dioacld.c
  3. 10
      src/spicelib/devices/dio/dioask.c
  4. 101
      src/spicelib/devices/dio/diodefs.h
  5. 183
      src/spicelib/devices/dio/dioload.c
  6. 32
      src/spicelib/devices/dio/diomask.c
  7. 50
      src/spicelib/devices/dio/diompar.c
  8. 12
      src/spicelib/devices/dio/dioparam.c
  9. 4
      src/spicelib/devices/dio/diopzld.c
  10. 61
      src/spicelib/devices/dio/diosetup.c
  11. 52
      src/spicelib/devices/dio/diotemp.c

40
src/spicelib/devices/dio/dio.c

@ -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")

4
src/spicelib/devices/dio/dioacld.c

@ -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;

10
src/spicelib/devices/dio/dioask.c

@ -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:

101
src/spicelib/devices/dio/diodefs.h

@ -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*/

183
src/spicelib/devices/dio/dioload.c

@ -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 */
vtesw = model->DIOswEmissionCoeff * vt;
if (vd >= -3*vtesw) { /* sidewall forward */
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;
}
} else if((!(model->DIObreakdownVoltageGiven)) || /* sidewall reverse */
vd >= -here->DIOtBrkdwnV) {
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;
}
} 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->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;
}
} else if((!(model->DIObreakdownVoltageGiven)) || /* reverse */
}
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) {
arg = 3*vte/(vd*CONSTe);
arg = arg * arg * arg;
cd = -csat*(1+arg) + ckt->CKTgmin*vd ;
gd = csat*3*arg/vd + ckt->CKTgmin;
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;
}
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 { /* 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;
}
} else { /* breakdown */
}
if (model->DIOsatSWCurGiven) {
if (model->DIOswEmissionCoeffGiven) {
evrev = exp(-(here->DIOtBrkdwnV+vd)/vte);
cd = -csat*evrev + ckt->CKTgmin*vd;
gd = csat*evrev/vte + ckt->CKTgmin;
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) ) {
gd = gd-ckt->CKTgmin;
cd = cd-ckt->CKTgmin*vd;
ikr_area_m = model->DIOreverseKneeCurrent*here->DIOarea*here->DIOm;
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;
cd = cd/(1+sqrt_ikr)+ckt->CKTgmin*vd;
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;

32
src/spicelib/devices/dio/diomask.c

@ -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);
}

50
src/spicelib/devices/dio/diompar.c

@ -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);
}

12
src/spicelib/devices/dio/dioparam.c

@ -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;

4
src/spicelib/devices/dio/diopzld.c

@ -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;

61
src/spicelib/devices/dio/diosetup.c

@ -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;

52
src/spicelib/devices/dio/diotemp.c

@ -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…
Cancel
Save