Browse Source

Enhanced diode model (preliminary commit).

pre-master-46
pnenzi 23 years ago
parent
commit
980ede1032
  1. 30
      src/spicelib/devices/dio/dio.c
  2. 9
      src/spicelib/devices/dio/dioacld.c
  3. 19
      src/spicelib/devices/dio/dioask.c
  4. 4
      src/spicelib/devices/dio/dioconv.c
  5. 91
      src/spicelib/devices/dio/diodefs.h
  6. 5
      src/spicelib/devices/dio/diodel.c
  7. 3
      src/spicelib/devices/dio/diodest.c
  8. 6
      src/spicelib/devices/dio/diodisto.c
  9. 94
      src/spicelib/devices/dio/diodset.c
  10. 31
      src/spicelib/devices/dio/dioext.h
  11. 4
      src/spicelib/devices/dio/diogetic.c
  12. 8
      src/spicelib/devices/dio/dioinit.c
  13. 110
      src/spicelib/devices/dio/dioload.c
  14. 45
      src/spicelib/devices/dio/diomask.c
  15. 5
      src/spicelib/devices/dio/diomdel.c
  16. 58
      src/spicelib/devices/dio/diompar.c
  17. 49
      src/spicelib/devices/dio/dionoise.c
  18. 20
      src/spicelib/devices/dio/dioparam.c
  19. 9
      src/spicelib/devices/dio/diopzld.c
  20. 10
      src/spicelib/devices/dio/diosacl.c
  21. 50
      src/spicelib/devices/dio/diosetup.c
  22. 4
      src/spicelib/devices/dio/diosload.c
  23. 4
      src/spicelib/devices/dio/diosprt.c
  24. 4
      src/spicelib/devices/dio/diosset.c
  25. 4
      src/spicelib/devices/dio/diosupd.c
  26. 128
      src/spicelib/devices/dio/diotemp.c
  27. 5
      src/spicelib/devices/dio/diotrunc.c

30
src/spicelib/devices/dio/dio.c

@ -1,6 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
Modified by Dietmar Warning 2003
**********/
#include "ngspice.h"
@ -11,14 +12,18 @@ Author: 1985 Thomas L. Quarles
IFparm DIOpTable[] = { /* parameters */
IOPU("off", DIO_OFF, IF_FLAG, "Initially off"),
IOPU("temp", DIO_TEMP, IF_REAL, "Instance temperature"),
IOPAU("ic", DIO_IC, IF_REAL, "Initial device voltage"),
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"),
IP("sens_area",DIO_AREA_SENS,IF_FLAG,"flag to request sensitivity WRT area"),
OP("vd",DIO_VOLTAGE,IF_REAL, "Diode voltage"),
OP("vd", DIO_VOLTAGE,IF_REAL, "Diode voltage"),
OP("id", DIO_CURRENT,IF_REAL, "Diode current"),
OPR("c", DIO_CURRENT,IF_REAL, "Diode current"),
OP("gd", DIO_CONDUCT,IF_REAL, "Diode conductance"),
OP("cd", DIO_CAP, IF_REAL, "Diode capacitance"),
OP("cd", DIO_CAP, IF_REAL, "Diode capacitance"),
OPU("charge", DIO_CHARGE, IF_REAL, "Diode capacitor charge"),
OPU("capcur", DIO_CAPCUR, IF_REAL, "Diode capacitor current"),
OPU("p", DIO_POWER, IF_REAL, "Diode power"),
@ -32,15 +37,32 @@ IFparm DIOpTable[] = { /* parameters */
};
IFparm DIOmPTable[] = { /* model parameters */
IOP( "is", DIO_MOD_IS, IF_REAL, "Saturation current"),
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"),
IOPU( "tnom",DIO_MOD_TNOM,IF_REAL, "Parameter measurement temperature"),
IOP( "rs", DIO_MOD_RS, IF_REAL, "Ohmic resistance"),
IOP( "trs", DIO_MOD_TRS, IF_REAL, "Ohmic resistance temp. coeff."),
IOP( "n", DIO_MOD_N, IF_REAL, "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."),
IOPA( "cjo", DIO_MOD_CJO, IF_REAL, "Junction capacitance"),
IOPR( "cj0", DIO_MOD_CJO, IF_REAL, "Junction capacitance"),
IOP( "vj", DIO_MOD_VJ, IF_REAL, "Junction potential"),
IOP( "m", DIO_MOD_M, IF_REAL, "Grading coefficient"),
IOPR("mj", DIO_MOD_M, IF_REAL, "Grading coefficient"),
IOP("tm1", DIO_MOD_TM1, IF_REAL, " Grading coefficient 1st temp. coeff."),
IOP("tm1", DIO_MOD_TM2, IF_REAL, " Grading coefficient 2nd temp. coeff."),
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( "eg", DIO_MOD_EG, IF_REAL, "Activation energy"),
IOP( "xti", DIO_MOD_XTI, IF_REAL, "Saturation current temperature exp."),
IOP( "kf", DIO_MOD_KF, IF_REAL, "flicker noise coefficient"),

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

@ -1,6 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
Modified by Dietmar Warning 2003
**********/
/*
*/
@ -13,10 +14,7 @@ Author: 1985 Thomas L. Quarles
int
DIOacLoad(inModel,ckt)
GENmodel *inModel;
CKTcircuit *ckt;
DIOacLoad(GENmodel *inModel, CKTcircuit *ckt)
{
DIOmodel *model = (DIOmodel*)inModel;
double gspr;
@ -31,8 +29,7 @@ DIOacLoad(inModel,ckt)
for (here = model->DIOinstances; here != NULL ;
here=here->DIOnextInstance) {
if (here->DIOowner != ARCHme) continue;
gspr=model->DIOconductance*here->DIOarea;
gspr=here->DIOtConductance*here->DIOarea*here->DIOm;
geq= *(ckt->CKTstate0 + here->DIOconduct);
xceq= *(ckt->CKTstate0 + here->DIOcapCurrent) * ckt->CKTomega;
*(here->DIOposPosPtr ) += gspr;

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

@ -1,6 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
Modified by Dietmar Warning 2003
**********/
#include "ngspice.h"
@ -14,12 +15,8 @@ Author: 1985 Thomas L. Quarles
/* ARGSUSED */
int
DIOask (ckt,inst,which,value,select)
CKTcircuit *ckt;
GENinstance *inst;
int which;
IFvalue *value;
IFvalue *select;
DIOask (CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value,
IFvalue *select)
{
DIOinstance *here = (DIOinstance*)inst;
double vr;
@ -39,9 +36,19 @@ DIOask (ckt,inst,which,value,select)
case DIO_AREA:
value->rValue = here->DIOarea;
return(OK);
case DIO_PJ:
value->rValue = here->DIOpj;
return(OK);
case DIO_M:
value->rValue = here->DIOm;
return(OK);
case DIO_TEMP:
value->rValue = here->DIOtemp-CONSTCtoK;
return(OK);
case DIO_DTEMP:
value->rValue = here->DIOdtemp;
return(OK);
case DIO_VOLTAGE:
value->rValue = *(ckt->CKTstate0+here->DIOvoltage);
return(OK);

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

@ -13,9 +13,7 @@ Author: 1985 Thomas L. Quarles
#include "suffix.h"
int
DIOconvTest(inModel,ckt)
GENmodel *inModel;
CKTcircuit *ckt;
DIOconvTest(GENmodel *inModel, CKTcircuit *ckt)
/* Check the devices for convergence
*/
{

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

@ -1,6 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
Modified by Dietmar Warning 2003
**********/
#ifndef DIO
#define DIO
@ -52,23 +53,43 @@ 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 DIOmGiven : 1; /* flag to indicate multiplier was specified */
unsigned DIOinitCondGiven : 1; /* flag to indicate ic was specified */
unsigned DIOsenPertFlag :1; /* indictes whether the the parameter of
the particular instance is to be perturbed */
unsigned DIOtempGiven : 1; /* flag to indicate temperature was specified */
unsigned DIOdtempGiven : 1; /* flag to indicate dtemp given */
double DIOarea; /* area factor for the diode */
double DIOinitCond; /* initial condition */
double DIOtemp; /* temperature of the instance */
double DIOtJctPot; /* temperature adjusted junction potential */
double DIOtJctCap; /* temperature adjusted junction capacitance */
double DIOpj; /* perimeter for the diode */
double DIOm; /* multiplier for the diode */
double DIOinitCond; /* initial condition */
double DIOtemp; /* temperature of the instance */
double DIOdtemp; /* delta temperature of instance */
double DIOtJctPot; /* temperature adjusted junction potential */
double DIOtJctCap; /* temperature adjusted junction capacitance */
double DIOtJctSWPot; /* temperature adjusted sidewall junction potential */
double DIOtJctSWCap; /* temperature adjusted sidewall junction capacitance */
double DIOtTransitTime; /* temperature adjusted transit time */
double DIOtGradingCoeff; /* temperature adjusted grading coefficient (MJ) */
double DIOtConductance; /* temperature adjusted series conductance */
double DIOtDepCap; /* temperature adjusted transition point in */
/* the curve matching (Fc * Vj ) */
double DIOtSatCur; /* temperature adjusted saturation current */
double DIOtSatSWCur; /* temperature adjusted side wall saturation current */
double DIOtVcrit; /* temperature adjusted V crit */
double DIOtF1; /* temperature adjusted f1 */
double DIOtBrkdwnV; /* temperature adjusted breakdown voltage */
double DIOtF2; /* coeff. for capacitance equation precomputation */
double DIOtF3; /* coeff. for capacitance equation precomputation */
double DIOtF2SW; /* coeff. for capacitance equation precomputation */
double DIOtF3SW; /* coeff. for capacitance equation precomputation */
/*
* naming convention:
@ -139,15 +160,29 @@ typedef struct sDIOmodel { /* model structure for a diode */
IFuid DIOmodName; /* pointer to character string naming this model */
unsigned DIOsatCurGiven : 1;
unsigned DIOsatSWCurGiven : 1;
unsigned DIOresistGiven : 1;
unsigned DIOresistTemp1Given : 1;
unsigned DIOemissionCoeffGiven : 1;
unsigned DIOtransitTimeGiven : 1;
unsigned DIOtranTimeTemp1Given : 1;
unsigned DIOtranTimeTemp2Given : 1;
unsigned DIOjunctionCapGiven : 1;
unsigned DIOjunctionPotGiven : 1;
unsigned DIOgradingCoeffGiven : 1;
unsigned DIOgradCoeffTemp1Given : 1;
unsigned DIOgradCoeffTemp2Given : 1;
unsigned DIOjunctionSWCapGiven : 1;
unsigned DIOjunctionSWPotGiven : 1;
unsigned DIOgradingSWCoeffGiven : 1;
unsigned DIOforwardKneeCurrentGiven : 1;
unsigned DIOreverseKneeCurrentGiven : 1;
unsigned DIOactivationEnergyGiven : 1;
unsigned DIOsaturationCurrentExpGiven : 1;
unsigned DIOdepletionCapCoeffGiven : 1;
unsigned DIOdepletionSWcapCoeffGiven :1;
unsigned DIObreakdownVoltageGiven : 1;
unsigned DIObreakdownCurrentGiven : 1;
unsigned DIOnomTempGiven : 1;
@ -155,20 +190,33 @@ typedef struct sDIOmodel { /* model structure for a diode */
unsigned DIOfNexpGiven : 1;
double DIOsatCur; /* saturation current */
double DIOresist; /* ohmic series resistance */
double DIOconductance; /* conductance corresponding to ohmic R */
double DIOemissionCoeff; /* emission coefficient (N) */
double DIOtransitTime; /* transit time (TT) */
double DIOjunctionCap; /* Junction Capacitance (Cj0) */
double DIOjunctionPot; /* Junction Potential (Vj) or (PB) */
double DIOgradingCoeff; /* grading coefficient (m) */
double DIOsatSWCur; /* Sidewall saturation current */
double DIOresist; /* ohmic series resistance */
double DIOresistTemp1; /* series resistance 1st order temp. coeff. */
double DIOconductance; /* conductance corresponding to ohmic R */
double DIOemissionCoeff; /* emission coefficient (N) */
double DIOtransitTime; /* transit time (TT) */
double DIOtranTimeTemp1; /* transit time 1st order coefficient */
double DIOtranTimeTemp2; /* transit time 2nd order coefficient */
double DIOjunctionCap; /* Junction Capacitance (Cj0) */
double DIOjunctionPot; /* Junction Potential (Vj) or (PB) */
double DIOgradingCoeff; /* grading coefficient (m) or (mj) */
double DIOgradCoeffTemp1; /* grading coefficient 1st order temp. coeff.*/
double DIOgradCoeffTemp2; /* grading coefficient 2nd order temp. coeff.*/
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 DIOactivationEnergy; /* activation energy (EG) */
double DIOsaturationCurrentExp; /* Saturation current exponential (XTI) */
double DIOdepletionCapCoeff; /* Depletion Cap fraction coefficient (FC)*/
double DIOdepletionSWcapCoeff; /* Depletion sw-Cap fraction coefficient (FCS)*/
double DIObreakdownVoltage; /* Voltage at reverse breakdown */
double DIObreakdownCurrent; /* Current at above voltage */
double DIOf2; /* coefficient for capacitance equation precomputation */
double DIOf3; /* coefficient for capacitance equation precomputation */
double DIOnomTemp; /* nominal temperature (temp at which parms measured */
double DIOfNcoef;
double DIOfNexp;
@ -195,6 +243,9 @@ typedef struct sDIOmodel { /* model structure for a diode */
#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
/* model parameters */
#define DIO_MOD_IS 101
@ -214,6 +265,18 @@ typedef struct sDIOmodel { /* model structure for a diode */
#define DIO_MOD_TNOM 115
#define DIO_MOD_KF 116
#define DIO_MOD_AF 117
#define DIO_MOD_JSW 118
#define DIO_MOD_CJSW 119
#define DIO_MOD_VJSW 120
#define DIO_MOD_MJSW 121
#define DIO_MOD_IKF 122
#define DIO_MOD_IKR 123
#define DIO_MOD_FCS 124
#define DIO_MOD_TTT1 125
#define DIO_MOD_TTT2 126
#define DIO_MOD_TM1 127
#define DIO_MOD_TM2 128
#define DIO_MOD_TRS 129
#include "dioext.h"
#endif /*DIO*/

5
src/spicelib/devices/dio/diodel.c

@ -12,10 +12,7 @@ Author: 1985 Thomas L. Quarles
int
DIOdelete(inModel,name,kill)
GENmodel *inModel;
IFuid name;
GENinstance **kill;
DIOdelete(GENmodel *inModel, IFuid name, GENinstance **kill)
{
DIOmodel *model = (DIOmodel*)inModel;
DIOinstance **fast = (DIOinstance**)kill;

3
src/spicelib/devices/dio/diodest.c

@ -11,8 +11,7 @@ Author: 1985 Thomas L. Quarles
void
DIOdestroy(inModel)
GENmodel **inModel;
DIOdestroy(GENmodel **inModel)
{
DIOmodel **model = (DIOmodel**)inModel;
DIOinstance *here;

6
src/spicelib/devices/dio/diodisto.c

@ -11,11 +11,7 @@ Author: 1988 Jaijeet S Roychowdhury
#include "suffix.h"
int
DIOdisto(mode,genmodel,ckt)
GENmodel *genmodel;
CKTcircuit *ckt;
int mode;
DIOdisto( int mode, GENmodel *genmodel, CKTcircuit *ckt)
/* assuming here that ckt->CKTomega has been initialised to
* the correct value
*/

94
src/spicelib/devices/dio/diodset.c

@ -1,6 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1988 Jaijeet S Roychowdhury
Modified by Dietmar Warning 2003
**********/
#include "ngspice.h"
@ -12,7 +13,7 @@ Author: 1988 Jaijeet S Roychowdhury
/* actually load the current resistance value into the sparse matrix
* previously provided */
* previously provided - for distortion analysis */
int
DIOdSetup(DIOmodel *model, CKTcircuit *ckt)
{
@ -31,6 +32,13 @@ DIOdSetup(DIOmodel *model, CKTcircuit *ckt)
double g2,g3;
double cdiff2,cdiff3;
double cjunc1,cjunc2,cjunc3;
double cd;
double sqrt_ikf;
double ikf_area_m;
double sqrt_ikr;
double ikr_area_m;
double czeroSW;
double cjunc1SW,cjunc2SW,cjunc3SW;
/* loop through all the diode models */
for( ; model != NULL; model = model->DIOnextModel ) {
@ -44,10 +52,7 @@ DIOdSetup(DIOmodel *model, CKTcircuit *ckt)
* this routine loads diodes for dc and transient analyses.
*/
csat=here->DIOtSatCur*here->DIOarea;
csat=(here->DIOtSatCur*here->DIOarea+here->DIOtSatSWCur*here->DIOpj)*here->DIOm;
vt = CONSTKoverQ * here->DIOtemp;
vte=model->DIOemissionCoeff * vt;
vd = *(ckt->CKTrhsOld + (here->DIOposPrimeNode)) -
@ -58,11 +63,17 @@ DIOdSetup(DIOmodel *model, CKTcircuit *ckt)
*/
if (vd >= -5*vte) {
evd = exp(vd/vte);
cd = csat*(evd-1)+ckt->CKTgmin*vd;
gd = csat*evd/vte+ckt->CKTgmin;
if((model->DIOforwardKneeCurrentGiven) && (model->DIOforwardKneeCurrent > 0.0) && (cd > 1.0e-18) ) {
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;
}
g2 = 0.5*(gd-ckt->CKTgmin)/vte;
cdiff2 = g2*model->DIOtransitTime;
cdiff2 = g2 * here->DIOtTransitTime;
g3 = g2/3/vte;
cdiff3 = g3*model->DIOtransitTime;
cdiff3 = g3 * here->DIOtTransitTime;
}
else if((!(here->DIOtBrkdwnV))||
(vd >= -here->DIOtBrkdwnV)) {
@ -86,35 +97,54 @@ DIOdSetup(DIOmodel *model, CKTcircuit *ckt)
/*
* junction charge storage elements
*/
czero=here->DIOtJctCap*here->DIOarea;
czero=here->DIOtJctCap*here->DIOarea*here->DIOm;
if (czero != 0.0) {
if (vd < here->DIOtDepCap){
arg=1-vd/model->DIOjunctionPot;
sarg=exp(-model->DIOgradingCoeff*log(arg));
/* the expression for depletion charge
model->DIOjunctionPot*czero*
(1-arg*sarg)/(1-model->DIOgradingCoeff);
*/
cjunc1 = czero*sarg;
cjunc2 = cjunc1/2/model->DIOjunctionPot*model->DIOgradingCoeff/arg;
cjunc3 = cjunc2/3/model->DIOjunctionPot/arg*(model->DIOgradingCoeff + 1);
if (vd < here->DIOtDepCap){
arg=1-vd/model->DIOjunctionPot;
sarg=exp(-here->DIOtGradingCoeff*log(arg));
/* the expression for depletion charge
model->DIOjunctionPot*czero*
(1-arg*sarg)/(1-here->DIOtGradingCoeff);
*/
cjunc1 = czero*sarg;
cjunc2 = cjunc1/2/model->DIOjunctionPot*here->DIOtGradingCoeff/arg;
cjunc3 = cjunc2/3/model->DIOjunctionPot/arg*(here->DIOtGradingCoeff + 1);
}
else {
czof2=czero/here->DIOtF2;
/* depletion charge equation
czero*here->DIOtF1+czof2*
(model->DIOtF3*(vd-here->DIOtDepCap)+
(here->DIOtGradingCoeff/(model->DIOjunctionPot+
model->DIOjunctionPot))*(vd*vd-here->DIOtDepCap*
here->DIOtDepCap));
*/
cjunc2 = czof2/2/model->DIOjunctionPot*here->DIOtGradingCoeff;
cjunc3 =0.0;
}
}
else {
czof2=czero/model->DIOf2;
/* depletion charge equation
czero*here->DIOtF1+czof2*
(model->DIOf3*(vd-here->DIOtDepCap)+
(model->DIOgradingCoeff/(model->DIOjunctionPot+
model->DIOjunctionPot))*(vd*vd-here->DIOtDepCap*
here->DIOtDepCap));
*/
cjunc2 = czof2/2/model->DIOjunctionPot*model->DIOgradingCoeff;
cjunc3 =0.0;
else
{
cjunc1 = cjunc2 = cjunc3 = 0.0;
}
czeroSW=+here->DIOtJctSWCap*here->DIOpj*here->DIOm;
if (czeroSW != 0.0) {
if (vd < here->DIOtDepCap){
arg=1-vd/model->DIOjunctionSWPot;
sarg=exp(-model->DIOgradingSWCoeff*log(arg));
cjunc1SW = czeroSW*sarg;
cjunc2SW = cjunc1SW/2/model->DIOjunctionSWPot*model->DIOgradingSWCoeff/arg;
cjunc3SW = cjunc2SW/3/model->DIOjunctionSWPot/arg*(model->DIOgradingSWCoeff + 1);
}
else {
czof2=czeroSW/here->DIOtF2SW;
cjunc2SW = czof2/2/model->DIOjunctionSWPot*model->DIOgradingSWCoeff;
cjunc3SW = 0.0;
}
}
else
{
cjunc1 = cjunc2 = cjunc3 = 0.0;
cjunc1SW = cjunc2SW = cjunc3SW = 0.0;
}
/*
@ -125,8 +155,8 @@ DIOdSetup(DIOmodel *model, CKTcircuit *ckt)
here->id_x3 = g3;
here->cdif_x2 = cdiff2;
here->cdif_x3 = cdiff3;
here->cjnc_x2 = cjunc2;
here->cjnc_x3 = cjunc3;
here->cjnc_x2 = cjunc2+cjunc2SW;
here->cjnc_x3 = cjunc3+cjunc3SW;
}
}
return(OK);

31
src/spicelib/devices/dio/dioext.h

@ -4,8 +4,6 @@ Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
**********/
#ifdef __STDC__
extern int DIOacLoad(GENmodel*,CKTcircuit*);
extern int DIOask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*);
extern int DIOconvTest(GENmodel *,CKTcircuit*);
@ -29,34 +27,5 @@ extern int DIOtemp(GENmodel*,CKTcircuit*);
extern int DIOtrunc(GENmodel*,CKTcircuit*,double*);
extern int DIOdisto(int,GENmodel*,CKTcircuit*);
extern int DIOnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
extern int DIOdSetup(DIOmodel*,CKTcircuit*);
#else /* stdc */
extern int DIOacLoad();
extern int DIOask();
extern int DIOconvTest();
extern int DIOdelete();
extern void DIOdestroy();
extern int DIOgetic();
extern int DIOload();
extern int DIOmAsk();
extern int DIOmDelete();
extern int DIOmParam();
extern int DIOparam();
extern int DIOpzLoad();
extern int DIOsAcLoad();
extern int DIOsLoad();
extern int DIOsSetup();
extern void DIOsPrint();
extern int DIOsUpdate();
extern int DIOsetup();
extern int DIOunsetup();
extern int DIOtemp();
extern int DIOtrunc();
extern int DIOdisto();
extern int DIOnoise();
#endif /* stdc */

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

@ -13,9 +13,7 @@ Author: 1985 Thomas L. Quarles
int
DIOgetic(inModel,ckt)
GENmodel *inModel;
CKTcircuit *ckt;
DIOgetic(GENmodel *inModel, CKTcircuit *ckt)
{
DIOmodel *model = (DIOmodel*)inModel;
DIOinstance *here;

8
src/spicelib/devices/dio/dioinit.c

@ -1,7 +1,7 @@
#include <config.h>
#include "config.h"
#include <devdefs.h>
#include <cktdefs.h>
#include "devdefs.h"
#include "cktdefs.h"
#include "diodefs.h"
#include "dioitf.h"
@ -72,7 +72,7 @@ SPICEdev DIOinfo = {
#ifdef CIDER
DEVdump : NULL,
DEVacct : NULL,
#endif
#endif
DEVinstSize : &DIOiSize,
DEVmodSize : &DIOmSize
};

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

@ -2,6 +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
**********/
#include "ngspice.h"
@ -14,9 +15,7 @@ Modified: 2000 AlansFixes
#include "suffix.h"
int
DIOload(inModel,ckt)
GENmodel *inModel;
CKTcircuit *ckt;
DIOload(GENmodel *inModel, CKTcircuit *ckt)
/* actually load the current resistance value into the
* sparse matrix previously provided
*/
@ -32,6 +31,16 @@ DIOload(inModel,ckt)
double csat; /* area-scaled saturation current */
double czero;
double czof2;
double argSW;
double czeroSW;
double czof2SW;
double sargSW;
double cd_new;
double sqrt_ikr;
double sqrt_ikf;
double ikf_area_m;
double ikr_area_m;
double delvd; /* change in diode voltage temporary */
double evd;
double evrev;
@ -71,9 +80,8 @@ DIOload(inModel,ckt)
#endif /* SENSDEBUG */
}
csat=here->DIOtSatCur*here->DIOarea;
gspr=model->DIOconductance*here->DIOarea;
csat=(here->DIOtSatCur*here->DIOarea+here->DIOtSatSWCur*here->DIOpj)*here->DIOm;
gspr=here->DIOtConductance*here->DIOarea*here->DIOm;
vt = CONSTKoverQ * here->DIOtemp;
vte=model->DIOemissionCoeff * vt;
/*
@ -172,44 +180,86 @@ DIOload(inModel,ckt)
/*
* compute dc current and derivitives
*/
next1: if (vd >= -3*vte) {
evd = exp(vd/vte);
cd = csat*(evd-1)+ckt->CKTgmin*vd;
gd = csat*evd/vte+ckt->CKTgmin;
} else if((!(model->DIObreakdownVoltageGiven)) ||
next1: if (vd >= -3*vte) { /* forward */
evd = exp(vd/vte);
cd = csat*(evd-1);
gd = csat*evd/vte;
if( (model->DIOforwardKneeCurrentGiven) && (model->DIOforwardKneeCurrent > 0.0) && (cd > 1.0e-18) ) {
ikf_area_m = model->DIOforwardKneeCurrent*here->DIOarea*here->DIOm;
sqrt_ikf = sqrt(cd/ikf_area_m);
cd_new = cd/(1+sqrt_ikf);
gd = ((1+sqrt_ikf)*gd - cd*gd/(2*sqrt_ikf*ikf_area_m))/(1+2*sqrt_ikf+cd/ikf_area_m);
cd = cd_new;
}
cd = cd + ckt->CKTgmin*vd;
gd = gd + ckt->CKTgmin;
} else if((!(model->DIObreakdownVoltageGiven)) || /* reverse*/
vd >= -here->DIOtBrkdwnV) {
arg=3*vte/(vd*CONSTe);
arg=3*vte/(vd*CONSTe);
arg = arg * arg * arg;
cd = -csat*(1+arg)+ckt->CKTgmin*vd;
gd = csat*3*arg/vd+ckt->CKTgmin;
} else {
cd = -csat*(1+arg);
gd = csat*3*arg/vd;
if( (model->DIOreverseKneeCurrentGiven) && (model->DIOreverseKneeCurrent > 0.0) && (cd < -1.0e-18) ) {
ikr_area_m = model->DIOreverseKneeCurrent*here->DIOarea*here->DIOm;
sqrt_ikr = sqrt(cd/(-ikr_area_m));
cd_new = cd/(1+sqrt_ikr);
gd = ((1+sqrt_ikr)*gd + cd*gd/(2*sqrt_ikr*ikr_area_m))/(1+2*sqrt_ikr - cd/ikr_area_m);
cd = cd_new;
}
cd = cd + ckt->CKTgmin*vd;
gd = gd + ckt->CKTgmin;
} else { /* breakdown */
evrev=exp(-(here->DIOtBrkdwnV+vd)/vte);
cd = -csat*evrev+ckt->CKTgmin*vd;
gd=csat*evrev/vte + ckt->CKTgmin;
cd = -csat*evrev;
gd = csat*evrev/vte;
if( (model->DIOreverseKneeCurrentGiven) && (model->DIOreverseKneeCurrent > 0.0) && (cd < -1.0e-18) ) {
ikr_area_m = model->DIOreverseKneeCurrent*here->DIOarea*here->DIOm;
sqrt_ikr = sqrt(cd/(-ikr_area_m));
cd_new = cd/(1+sqrt_ikr);
gd = ((1+sqrt_ikr)*gd + cd*gd/(2*sqrt_ikr*ikr_area_m))/(1+2*sqrt_ikr - cd/ikr_area_m);
cd = cd_new;
}
cd = cd + ckt->CKTgmin*vd;
gd = gd + ckt->CKTgmin;
}
if ((ckt->CKTmode & (MODETRAN | MODEAC | MODEINITSMSIG)) ||
((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))) {
/*
* charge storage elements
*/
czero=here->DIOtJctCap*here->DIOarea;
czero=here->DIOtJctCap*here->DIOarea*here->DIOm;
czeroSW=here->DIOtJctSWCap*here->DIOpj*here->DIOm;
if (vd < here->DIOtDepCap){
arg=1-vd/here->DIOtJctPot;
sarg=exp(-model->DIOgradingCoeff*log(arg));
argSW=1-vd/here->DIOtJctSWPot;
sarg=exp(-here->DIOtGradingCoeff*log(arg));
sargSW=exp(-model->DIOgradingSWCoeff*log(argSW));
*(ckt->CKTstate0 + here->DIOcapCharge) =
model->DIOtransitTime*cd+here->DIOtJctPot*
czero* (1-arg*sarg)/(1-model->DIOgradingCoeff);
capd=model->DIOtransitTime*gd+czero*sarg;
here->DIOtTransitTime*cd+
here->DIOtJctPot*czero*(1-arg*sarg)/(1-here->DIOtGradingCoeff)+
here->DIOtJctSWPot*czeroSW*(1-argSW*sargSW)/(1-model->DIOgradingSWCoeff);
capd=here->DIOtTransitTime*gd+czero*sarg+czeroSW*sargSW;
} else {
czof2=czero/model->DIOf2;
czof2=czero/here->DIOtF2;
czof2SW=czeroSW/here->DIOtF2SW;
*(ckt->CKTstate0 + here->DIOcapCharge) =
model->DIOtransitTime*cd+czero*here->DIOtF1+czof2*
(model->DIOf3*(vd-here->DIOtDepCap)+
(model->DIOgradingCoeff/(here->DIOtJctPot+
here->DIOtJctPot))*(vd*vd-here->DIOtDepCap*
here->DIOtDepCap));
capd=model->DIOtransitTime*gd+czof2*(model->DIOf3+
model->DIOgradingCoeff*vd/here->DIOtJctPot);
here->DIOtTransitTime*cd+czero*here->DIOtF1+
czof2*(here->DIOtF3*(vd-here->DIOtDepCap)+(here->DIOtGradingCoeff/(here->DIOtJctPot+here->DIOtJctPot))*(vd*vd-here->DIOtDepCap*here->DIOtDepCap))+
czof2SW*(here->DIOtF3SW*(vd-here->DIOtDepCap)+(model->DIOgradingSWCoeff/(here->DIOtJctSWPot+here->DIOtJctSWPot))*(vd*vd-here->DIOtDepCap*here->DIOtDepCap));
capd=here->DIOtTransitTime*gd+
czof2*(here->DIOtF3+here->DIOtGradingCoeff*vd/here->DIOtJctPot)+
czof2SW*(here->DIOtF3SW+model->DIOgradingSWCoeff*vd/here->DIOtJctSWPot);
}
here->DIOcap = capd;

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

@ -1,6 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
Modified by Dietmar Warning 2003
**********/
/*
*/
@ -16,29 +17,38 @@ Author: 1985 Thomas L. Quarles
/* ARGSUSED */
int
DIOmAsk (ckt,inModel,which, value)
CKTcircuit *ckt;
int which;
IFvalue *value;
GENmodel *inModel;
DIOmAsk (CKTcircuit *ckt, GENmodel *inModel, int which, IFvalue *value)
{
DIOmodel *model = (DIOmodel*)inModel;
switch (which) {
case DIO_MOD_IS:
value->rValue = model->DIOsatCur;
return(OK);
case DIO_MOD_JSW:
value->rValue = model->DIOsatSWCur;
return(OK);
case DIO_MOD_TNOM:
value->rValue = model->DIOnomTemp-CONSTCtoK;
return(OK);
case DIO_MOD_RS:
value->rValue = model->DIOresist;
return(OK);
case DIO_MOD_TRS:
value->rValue = model->DIOresistTemp1;
return(OK);
case DIO_MOD_N:
value->rValue = model->DIOemissionCoeff;
return(OK);
case DIO_MOD_TT:
value->rValue = model->DIOtransitTime;
return(OK);
case DIO_MOD_TTT1:
value->rValue = model->DIOtranTimeTemp1;
return(OK);
case DIO_MOD_TTT2:
value->rValue = model->DIOtranTimeTemp2;
return(OK);
case DIO_MOD_CJO:
value->rValue = model->DIOjunctionCap;
return(OK);
@ -48,6 +58,28 @@ DIOmAsk (ckt,inModel,which, value)
case DIO_MOD_M:
value->rValue = model->DIOgradingCoeff;
return(OK);
case DIO_MOD_TM1:
value->rValue = model->DIOgradCoeffTemp1;
return(OK);
case DIO_MOD_TM2:
value->rValue = model->DIOgradCoeffTemp2;
return(OK);
case DIO_MOD_CJSW:
value->rValue = model->DIOjunctionSWCap;
return(OK);
case DIO_MOD_VJSW:
value->rValue = model->DIOjunctionSWPot;
return(OK);
case DIO_MOD_MJSW:
value->rValue = model->DIOgradingSWCoeff;
return(OK);
case DIO_MOD_IKF:
value->rValue = model->DIOforwardKneeCurrent;
return(OK);
case DIO_MOD_IKR:
value->rValue = model->DIOreverseKneeCurrent;
return(OK);
case DIO_MOD_EG:
value->rValue = model->DIOactivationEnergy;
return (OK);
@ -57,6 +89,9 @@ DIOmAsk (ckt,inModel,which, value)
case DIO_MOD_FC:
value->rValue = model->DIOdepletionCapCoeff;
return(OK);
case DIO_MOD_FCS:
value->rValue = model->DIOdepletionSWcapCoeff;
return(OK);
case DIO_MOD_KF:
value->rValue = model->DIOfNcoef;
return(OK);

5
src/spicelib/devices/dio/diomdel.c

@ -12,10 +12,7 @@ Author: 1985 Thomas L. Quarles
int
DIOmDelete(inModel,modname,kill)
GENmodel **inModel;
IFuid modname;
GENmodel *kill;
DIOmDelete(GENmodel **inModel, IFuid modname, GENmodel *kill)
{
DIOmodel **model = (DIOmodel**)inModel;
DIOmodel *modfast = (DIOmodel*)kill;

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

@ -1,6 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
Modified by Dietmar Warning 2003
**********/
/*
*/
@ -14,10 +15,7 @@ Author: 1985 Thomas L. Quarles
int
DIOmParam(param,value,inModel)
int param;
IFvalue *value;
GENmodel *inModel;
DIOmParam(int param, IFvalue *value, GENmodel *inModel)
{
DIOmodel *model = (DIOmodel*)inModel;
switch(param) {
@ -25,6 +23,11 @@ DIOmParam(param,value,inModel)
model->DIOsatCur = value->rValue;
model->DIOsatCurGiven = TRUE;
break;
case DIO_MOD_JSW:
model->DIOsatSWCur = value->rValue;
model->DIOsatSWCurGiven = TRUE;
break;
case DIO_MOD_TNOM:
model->DIOnomTemp = value->rValue+CONSTCtoK;
model->DIOnomTempGiven = TRUE;
@ -33,6 +36,10 @@ DIOmParam(param,value,inModel)
model->DIOresist = value->rValue;
model->DIOresistGiven = TRUE;
break;
case DIO_MOD_TRS:
model->DIOresistTemp1 = value->rValue;
model->DIOresistTemp1Given = TRUE;
break;
case DIO_MOD_N:
model->DIOemissionCoeff = value->rValue;
model->DIOemissionCoeffGiven = TRUE;
@ -41,6 +48,14 @@ DIOmParam(param,value,inModel)
model->DIOtransitTime = value->rValue;
model->DIOtransitTimeGiven = TRUE;
break;
case DIO_MOD_TTT1:
model->DIOtranTimeTemp1 = value->rValue;
model->DIOtranTimeTemp1Given = TRUE;
break;
case DIO_MOD_TTT2:
model->DIOtranTimeTemp2 = value->rValue;
model->DIOtranTimeTemp2Given = TRUE;
break;
case DIO_MOD_CJO:
model->DIOjunctionCap = value->rValue;
model->DIOjunctionCapGiven = TRUE;
@ -53,6 +68,35 @@ DIOmParam(param,value,inModel)
model->DIOgradingCoeff = value->rValue;
model->DIOgradingCoeffGiven = TRUE;
break;
case DIO_MOD_TM1:
model->DIOgradCoeffTemp1 = value->rValue;
model->DIOgradCoeffTemp1Given = TRUE;
break;
case DIO_MOD_TM2:
model->DIOgradCoeffTemp2 = value->rValue;
model->DIOgradCoeffTemp2Given = TRUE;
break;
case DIO_MOD_CJSW:
model->DIOjunctionSWCap = value->rValue;
model->DIOjunctionSWCapGiven = TRUE;
break;
case DIO_MOD_VJSW:
model->DIOjunctionSWPot = value->rValue;
model->DIOjunctionSWPotGiven = TRUE;
break;
case DIO_MOD_MJSW:
model->DIOgradingSWCoeff = value->rValue;
model->DIOgradingSWCoeffGiven = TRUE;
break;
case DIO_MOD_IKF:
model->DIOforwardKneeCurrent = value->rValue;
model->DIOforwardKneeCurrentGiven = TRUE;
break;
case DIO_MOD_IKR:
model->DIOreverseKneeCurrent = value->rValue;
model->DIOreverseKneeCurrentGiven = TRUE;
break;
case DIO_MOD_EG:
model->DIOactivationEnergy = value->rValue;
model->DIOactivationEnergyGiven = TRUE;
@ -65,7 +109,11 @@ DIOmParam(param,value,inModel)
model->DIOdepletionCapCoeff = value->rValue;
model->DIOdepletionCapCoeffGiven = TRUE;
break;
case DIO_MOD_BV:
case DIO_MOD_FCS:
model->DIOdepletionSWcapCoeff = value->rValue;
model->DIOdepletionSWcapCoeffGiven = TRUE;
break;
case DIO_MOD_BV:
model->DIObreakdownVoltage = value->rValue;
model->DIObreakdownVoltageGiven = TRUE;
break;

49
src/spicelib/devices/dio/dionoise.c

@ -1,6 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1987 Gary W. Ng
Modified by Dietmar Warning 2003
**********/
#include "ngspice.h"
@ -24,13 +25,8 @@ extern void NevalSrc();
extern double Nintegrate();
int
DIOnoise (mode, operation, genmodel, ckt, data, OnDens)
int mode;
int operation;
GENmodel *genmodel;
CKTcircuit *ckt;
Ndata *data;
double *OnDens;
DIOnoise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt,
Ndata *data, double *OnDens)
{
DIOmodel *firstModel = (DIOmodel *) genmodel;
DIOmodel *model;
@ -69,12 +65,10 @@ DIOnoise (mode, operation, genmodel, ckt, data, OnDens)
for (i=0; i < DIONSRCS; i++) {
(void)sprintf(name,"onoise_%s%s",inst->DIOname,DIOnNames[i]);
data->namelist = (IFuid *)trealloc((char *)data->namelist,(data->numPlots + 1)*sizeof(IFuid));
if (!data->namelist) return(E_NOMEM);
(*(SPfrontEnd->IFnewUid))(ckt,
&(data->namelist[data->numPlots++]),
(IFuid)NULL,name,UID_OTHER,(void **)NULL);
data->namelist = (IFuid *)trealloc((char *)data->namelist,(data->numPlots + 1)*sizeof(IFuid));
if (!data->namelist) return(E_NOMEM);
(*(SPfrontEnd->IFnewUid))(ckt, &(data->namelist[data->numPlots++]),
(IFuid)NULL,name,UID_OTHER,(void **)NULL);
/* we've added one more plot */
}
@ -84,26 +78,20 @@ if (!data->namelist) return(E_NOMEM);
for (i=0; i < DIONSRCS; i++) {
(void)sprintf(name,"onoise_total_%s%s",inst->DIOname,DIOnNames[i]);
data->namelist = (IFuid *)trealloc((char *)data->namelist,(data->numPlots + 1)*sizeof(IFuid));
if (!data->namelist) return(E_NOMEM);
(*(SPfrontEnd->IFnewUid))(ckt,
&(data->namelist[data->numPlots++]),
(IFuid)NULL,name,UID_OTHER,(void **)NULL);
data->namelist = (IFuid *)trealloc((char *)data->namelist,(data->numPlots + 1)*sizeof(IFuid));
if (!data->namelist) return(E_NOMEM);
(*(SPfrontEnd->IFnewUid))(ckt, &(data->namelist[data->numPlots++]),
(IFuid)NULL,name,UID_OTHER,(void **)NULL);
/* we've added one more plot */
(void)sprintf(name,"inoise_total_%s%s",inst->DIOname,DIOnNames[i]);
data->namelist = (IFuid *)trealloc((char *)data->namelist,(data->numPlots + 1)*sizeof(IFuid));
if (!data->namelist) return(E_NOMEM);
(*(SPfrontEnd->IFnewUid))(ckt,
&(data->namelist[data->numPlots++]),
(IFuid)NULL,name,UID_OTHER,(void **)NULL);
data->namelist = (IFuid *)trealloc((char *)data->namelist,(data->numPlots + 1)*sizeof(IFuid));
if (!data->namelist) return(E_NOMEM);
(*(SPfrontEnd->IFnewUid))(ckt, &(data->namelist[data->numPlots++]),
(IFuid)NULL,name,UID_OTHER,(void **)NULL);
/* we've added one more plot */
}
break;
}
@ -116,8 +104,7 @@ if (!data->namelist) return(E_NOMEM);
case N_DENS:
NevalSrc(&noizDens[DIORSNOIZ],&lnNdens[DIORSNOIZ],
ckt,THERMNOISE,inst->DIOposPrimeNode,inst->DIOposNode,
model->DIOconductance * inst->DIOarea);
inst->DIOtConductance * inst->DIOarea * inst->DIOm);
NevalSrc(&noizDens[DIOIDNOIZ],&lnNdens[DIOIDNOIZ],
ckt,SHOTNOISE,inst->DIOposPrimeNode, inst->DIOnegNode,
*(ckt->CKTstate0 + inst->DIOcurrent));
@ -127,8 +114,8 @@ if (!data->namelist) return(E_NOMEM);
(double)0.0);
noizDens[DIOFLNOIZ] *= model->DIOfNcoef *
exp(model->DIOfNexp *
log(MAX(fabs(*(ckt->CKTstate0 + inst->DIOcurrent)),N_MINLOG))) /
data->freq;
log(MAX(fabs(*(ckt->CKTstate0 + inst->DIOcurrent)/inst->DIOm),N_MINLOG))) /
data->freq * inst->DIOm;
lnNdens[DIOFLNOIZ] =
log(MAX(noizDens[DIOFLNOIZ],N_MINLOG));

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

@ -1,6 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
Modified by Dietmar Warning 2003
**********/
/*
*/
@ -15,11 +16,7 @@ Author: 1985 Thomas L. Quarles
/* ARGSUSED */
int
DIOparam(param,value,inst,select)
int param;
IFvalue *value;
GENinstance *inst;
IFvalue *select;
DIOparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
{
DIOinstance *here = (DIOinstance*)inst;
switch(param) {
@ -27,10 +24,23 @@ DIOparam(param,value,inst,select)
here->DIOarea = value->rValue;
here->DIOareaGiven = TRUE;
break;
case DIO_PJ:
here->DIOpj = value->rValue;
here->DIOpjGiven = TRUE;
break;
case DIO_M:
here->DIOm = value->rValue;
here->DIOmGiven = TRUE;
break;
case DIO_TEMP:
here->DIOtemp = value->rValue+CONSTCtoK;
here->DIOtempGiven = TRUE;
break;
case DIO_DTEMP:
here->DIOdtemp = value->rValue;
here->DIOdtempGiven = TRUE;
break;
case DIO_OFF:
here->DIOoff = value->iValue;
break;

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

@ -1,6 +1,7 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
Modified by Dietmar Warning 2003
**********/
/*
*/
@ -14,10 +15,7 @@ Author: 1985 Thomas L. Quarles
int
DIOpzLoad(inModel,ckt,s)
GENmodel *inModel;
CKTcircuit *ckt;
SPcomplex *s;
DIOpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s)
{
DIOmodel *model = (DIOmodel*)inModel;
double gspr;
@ -32,8 +30,7 @@ DIOpzLoad(inModel,ckt,s)
for (here = model->DIOinstances; here != NULL ;
here=here->DIOnextInstance) {
if (here->DIOowner != ARCHme) continue;
gspr=model->DIOresist*here->DIOarea;
gspr=here->DIOtConductance*here->DIOarea*here->DIOm;
geq= *(ckt->CKTstate0 + here->DIOconduct);
xceq= *(ckt->CKTstate0 + here->DIOcapCurrent);
*(here->DIOposPosPtr ) += gspr;

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

@ -19,9 +19,7 @@ Author: 1985 Thomas L. Quarles
int
DIOsAcLoad(inModel,ckt)
GENmodel *inModel;
CKTcircuit *ckt;
DIOsAcLoad(GENmodel *inModel, CKTcircuit *ckt)
{
DIOmodel *model = (DIOmodel*)inModel;
DIOinstance *here;
@ -111,7 +109,7 @@ DIOsAcLoad(inModel,ckt)
geq0 = *(here->DIOsenGeq);
xceq0 = *(here->DIOsenCeq) * ckt->CKTomega;
A0 = here->DIOarea;
gspr0=model->DIOconductance*A0;
gspr0=here->DIOtConductance*A0;
cpos0 = gspr0 * vspr;
icpos0 = gspr0 * ivspr;
cposprm0 = geq0 * vd - xceq0 * ivd - cpos0;
@ -146,7 +144,7 @@ DIOsAcLoad(inModel,ckt)
*(here->DIOsenCeq + 1)= *(ckt->CKTstate0 + here->DIOcapCurrent);
here->DIOarea = A0;
}
gspr=model->DIOconductance*Apert;
gspr=here->DIOtConductance*Apert;
geq = *(here->DIOsenGeq + 1);
xceq = *(here->DIOsenCeq + 1) * ckt->CKTomega;
flag = 0;
@ -173,7 +171,7 @@ pertvd: /* Perturbation of Diode Voltage */
*(here->DIOsenCeq + 2)= *(ckt->CKTstate0 + here->DIOcapCurrent);
*(ckt->CKTstate0 + here->DIOvoltage) = A0;
}
gspr=model->DIOconductance*here->DIOarea;
gspr=here->DIOtConductance*here->DIOarea;
geq = *(here->DIOsenGeq + 2);
xceq = *(here->DIOsenCeq + 2) * ckt->CKTomega;

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

@ -2,6 +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
**********/
/* load the diode structure with those pointers needed later
@ -16,11 +17,7 @@ Modified: 2000 AlansFixes
#include "suffix.h"
int
DIOsetup(matrix,inModel,ckt,states)
SMPmatrix *matrix;
GENmodel *inModel;
CKTcircuit *ckt;
int *states;
DIOsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
{
DIOmodel *model = (DIOmodel*)inModel;
DIOinstance *here;
@ -36,6 +33,10 @@ DIOsetup(matrix,inModel,ckt,states)
if(!model->DIOsatCurGiven) {
model->DIOsatCur = 1e-14;
}
if(!model->DIOsatSWCurGiven) {
model->DIOsatSWCur = 0.0;
}
if(!model->DIObreakdownCurrentGiven) {
model->DIObreakdownCurrent = 1e-3;
}
@ -45,15 +46,45 @@ DIOsetup(matrix,inModel,ckt,states)
if(!model->DIOgradingCoeffGiven) {
model->DIOgradingCoeff = .5;
}
if(!model->DIOgradCoeffTemp1Given) {
model->DIOgradCoeffTemp1 = 0.0;
}
if(!model->DIOgradCoeffTemp2Given) {
model->DIOgradCoeffTemp2 = 0.0;
}
if(!model->DIOdepletionCapCoeffGiven) {
model->DIOdepletionCapCoeff = .5;
}
if(!model->DIOdepletionSWcapCoeffGiven) {
model->DIOdepletionSWcapCoeff = .5;
}
if(!model->DIOtransitTimeGiven) {
model->DIOtransitTime = 0;
}
if(!model->DIOtranTimeTemp1Given) {
model->DIOtranTimeTemp1 = 0.0;
}
if(!model->DIOtranTimeTemp2Given) {
model->DIOtranTimeTemp2 = 0.0;
}
if(!model->DIOjunctionCapGiven) {
model->DIOjunctionCap = 0;
}
if(!model->DIOjunctionSWCapGiven) {
model->DIOjunctionSWCap = 0;
}
if(!model->DIOjunctionSWPotGiven){
model->DIOjunctionSWPot = 1;
}
if(!model->DIOgradingSWCoeffGiven) {
model->DIOgradingSWCoeff = .33;
}
if(!model->DIOforwardKneeCurrentGiven) {
model->DIOforwardKneeCurrent = 1e-3;
}
if(!model->DIOreverseKneeCurrentGiven) {
model->DIOreverseKneeCurrent = 1e-3;
}
if(!model->DIOactivationEnergyGiven) {
model->DIOactivationEnergy = 1.11;
}
@ -66,6 +97,9 @@ DIOsetup(matrix,inModel,ckt,states)
if(!model->DIOfNexpGiven) {
model->DIOfNexp = 1.0;
}
if(!model->DIOresistTemp1Given) {
model->DIOresistTemp1 = 0.0;
}
/* loop through all the instances of the model */
for (here = model->DIOinstances; here != NULL ;
@ -75,6 +109,12 @@ DIOsetup(matrix,inModel,ckt,states)
if(!here->DIOareaGiven) {
here->DIOarea = 1;
}
if(!here->DIOpjGiven) {
here->DIOpj = 0;
}
if(!here->DIOmGiven) {
here->DIOm = 1;
}
here->DIOstate = *states;
*states += 5;

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

@ -18,9 +18,7 @@ Author: 1985 Thomas L. Quarles
int
DIOsLoad(inModel,ckt)
GENmodel *inModel;
CKTcircuit *ckt;
DIOsLoad(GENmodel *inModel, CKTcircuit *ckt)
{
DIOmodel *model = (DIOmodel*)inModel;
DIOinstance *here;

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

@ -18,9 +18,7 @@ Author: 1985 Thomas L. Quarles
void
DIOsPrint(inModel,ckt)
GENmodel *inModel;
CKTcircuit *ckt;
DIOsPrint(GENmodel *inModel, CKTcircuit *ckt)
{
DIOmodel *model = (DIOmodel*)inModel;
DIOinstance *here;

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

@ -18,9 +18,7 @@ Author: 1985 Thomas L. Quarles
int
DIOsSetup(info,inModel)
SENstruct *info;
GENmodel *inModel;
DIOsSetup(SENstruct *info, GENmodel *inModel)
{
DIOmodel *model = (DIOmodel*)inModel;
DIOinstance *here;

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

@ -16,9 +16,7 @@ Author: 1985 Thomas L. Quarles
int
DIOsUpdate(inModel,ckt)
GENmodel *inModel;
CKTcircuit *ckt;
DIOsUpdate(GENmodel *inModel, CKTcircuit *ckt)
{
DIOmodel *model = (DIOmodel*)inModel;
DIOinstance *here;

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

@ -2,6 +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
**********/
/* perform the temperature update to the diode */
@ -14,12 +15,10 @@ Modified: 2000 AlansFixes
#include "suffix.h"
int
DIOtemp(inModel,ckt)
GENmodel *inModel;
CKTcircuit *ckt;
DIOtemp(GENmodel *inModel, CKTcircuit *ckt)
{
DIOmodel *model = (DIOmodel*)inModel;
double xfc;
double xfc, xfcs;
double vte;
double cbv;
double xbv;
@ -27,6 +26,8 @@ DIOtemp(inModel,ckt)
double tol;
double vt;
double vtnom;
double difference;
double factor;
DIOinstance *here;
int iter;
char *emsg;
@ -58,22 +59,53 @@ DIOtemp(inModel,ckt)
&(model->DIOmodName));
model->DIOdepletionCapCoeff=.95;
}
if(!model->DIOresistGiven || model->DIOresist==0) {
model->DIOconductance = 0;
/* limit sidewall depletion cap coeff to max of .95 */
if(model->DIOdepletionSWcapCoeff>.95) {
(*(SPfrontEnd->IFerror))(ERR_WARNING,
"%s: coefficient Fcs too large, limited to 0.95",
&(model->DIOmodName));
model->DIOdepletionSWcapCoeff=.95;
}
if((!model->DIOresistGiven) || (model->DIOresist==0)) {
model->DIOconductance = 0.0;
} else {
model->DIOconductance = 1/model->DIOresist;
}
xfc=log(1-model->DIOdepletionCapCoeff);
xfcs=log(1-model->DIOdepletionSWcapCoeff);
for(here=model->DIOinstances;here;here=here->DIOnextInstance) {
double egfet1,arg1,fact1,pbfact1,pbo,gmaold;
double fact2,pbfact,arg,egfet,gmanew;
double egfet1,arg1,fact1,pbfact1,pbo,gmaold,pboSW,gmaSWold;
double fact2,pbfact,arg,egfet,gmanew,gmaSWnew;
if (here->DIOowner != ARCHme) continue;
/* loop through all the instances */
if(!here->DIOtempGiven) here->DIOtemp = ckt->CKTtemp;
if(!here->DIOdtempGiven) here->DIOdtemp = 0.0;
if(!here->DIOtempGiven)
here->DIOtemp = ckt->CKTtemp + here->DIOdtemp;
/* Junction grading temperature adjust */
difference = here->DIOtemp - model->DIOnomTemp;
factor = 1.0 + (model->DIOgradCoeffTemp1 * difference)
+ (model->DIOgradCoeffTemp2 * difference * difference);
here->DIOtGradingCoeff = model->DIOgradingCoeff * factor;
/* limit temperature adjusted grading coeff
* to max of .9
*/
if(here->DIOtGradingCoeff>.9) {
(*(SPfrontEnd->IFerror))(ERR_WARNING,
"%s: temperature adjusted grading coefficient too large, limited to 0.9",
&(here->DIOname));
here->DIOtGradingCoeff=.9;
}
vt = CONSTKoverQ * here->DIOtemp;
/* this part gets really ugly - I won't even try to
* explain these equations */
* explain these equations */
fact2 = here->DIOtemp/REFTEMP;
egfet = 1.16-(7.02e-4*here->DIOtemp*here->DIOtemp)/
(here->DIOtemp+1108);
@ -86,26 +118,42 @@ DIOtemp(inModel,ckt)
1.1150877/(2*CONSTboltz*REFTEMP);
fact1 = model->DIOnomTemp/REFTEMP;
pbfact1 = -2 * vtnom*(1.5*log(fact1)+CHARGE*arg1);
pbo = (model->DIOjunctionPot-pbfact1)/fact1;
gmaold = (model->DIOjunctionPot -pbo)/pbo;
here->DIOtJctCap = model->DIOjunctionCap/
(1+model->DIOgradingCoeff*
(1+here->DIOtGradingCoeff*
(400e-6*(model->DIOnomTemp-REFTEMP)-gmaold) );
here->DIOtJctPot = pbfact+fact2*pbo;
gmanew = (here->DIOtJctPot-pbo)/pbo;
here->DIOtJctCap *= 1+model->DIOgradingCoeff*
here->DIOtJctCap *= 1+here->DIOtGradingCoeff*
(400e-6*(here->DIOtemp-REFTEMP)-gmanew);
pboSW = (model->DIOjunctionSWPot-pbfact1)/fact1;
gmaSWold = (model->DIOjunctionSWPot -pboSW)/pboSW;
here->DIOtJctSWCap = model->DIOjunctionSWCap/
(1+model->DIOgradingSWCoeff*
(400e-6*(model->DIOnomTemp-REFTEMP)-gmaSWold) );
here->DIOtJctSWPot = pbfact+fact2*pboSW;
gmaSWnew = (here->DIOtJctSWPot-pboSW)/pboSW;
here->DIOtJctSWCap *= 1+model->DIOgradingSWCoeff*
(400e-6*(here->DIOtemp-REFTEMP)-gmaSWnew);
here->DIOtSatCur = model->DIOsatCur * 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->DIOtemp/model->DIOnomTemp)-1) *
model->DIOactivationEnergy/(model->DIOemissionCoeff*vt) +
model->DIOsaturationCurrentExp/model->DIOemissionCoeff*
log(here->DIOtemp/model->DIOnomTemp) );
/* the defintion of f1, just recompute after temperature adjusting
* all the variables used in it */
here->DIOtF1=here->DIOtJctPot*
(1-exp((1-model->DIOgradingCoeff)*xfc))/
(1-model->DIOgradingCoeff);
(1-exp((1-here->DIOtGradingCoeff)*xfc))/
(1-here->DIOtGradingCoeff);
/* same for Depletion Capacitance */
here->DIOtDepCap=model->DIOdepletionCapCoeff*
here->DIOtJctPot;
@ -118,35 +166,37 @@ DIOtemp(inModel,ckt)
/* and now to copute the breakdown voltage, again, using
* temperature adjusted basic parameters */
if (model->DIObreakdownVoltageGiven){
cbv=model->DIObreakdownCurrent;
if (cbv < here->DIOtSatCur*model->DIObreakdownVoltage/vt){
cbv=here->DIOtSatCur*model->DIObreakdownVoltage/vt;
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;
emsg = MALLOC(100);
if(emsg == (char *)NULL) return(E_NOMEM);
(void)sprintf(emsg,
"%%s: breakdown current increased to %g to resolve",
"%%s: breakdown current increased to %g to resolve",
cbv);
(*(SPfrontEnd->IFerror))(ERR_WARNING,emsg,&(here->DIOname));
FREE(emsg);
(*(SPfrontEnd->IFerror))(ERR_WARNING,
"incompatibility with specified saturation current",(IFuid*)NULL);
"incompatibility with specified saturation current",(IFuid*)NULL);
xbv=model->DIObreakdownVoltage;
} else {
tol=ckt->CKTreltol*cbv;
xbv=model->DIObreakdownVoltage-vt*log(1+cbv/
here->DIOtSatCur);
(here->DIOtSatCur*here->DIOarea*here->DIOm));
iter=0;
for(iter=0 ; iter < 25 ; iter++) {
xbv=model->DIObreakdownVoltage-vt*log(cbv/
here->DIOtSatCur+1-xbv/vt);
xcbv=here->DIOtSatCur*(exp((model->DIObreakdownVoltage
-xbv)/vt)-1+xbv/vt);
(here->DIOtSatCur*here->DIOarea*here->DIOm)+1-xbv/vt);
xcbv=here->DIOtSatCur*here->DIOarea*here->DIOm *
(exp((model->DIObreakdownVoltage-xbv)/vt)-1+xbv/vt);
if (fabs(xcbv-cbv) <= tol) goto matched;
}
emsg = MALLOC(100);
if(emsg == (char *)NULL) return(E_NOMEM);
(void)sprintf(emsg,
"%%s: unable to match forward and reverse diode regions: bv = %g, ibv = %g",
"%%s: unable to match forward and reverse diode regions: bv = %g, ibv = %g",
xbv,xcbv);
(*(SPfrontEnd->IFerror))(ERR_WARNING,emsg,&here->DIOname);
FREE(emsg);
@ -154,10 +204,30 @@ DIOtemp(inModel,ckt)
matched:
here->DIOtBrkdwnV = xbv;
}
}
model->DIOf2=exp((1+model->DIOgradingCoeff)*xfc);
model->DIOf3=1-model->DIOdepletionCapCoeff*
(1+model->DIOgradingCoeff);
}
/* transit time temperature adjust */
difference = here->DIOtemp - model->DIOnomTemp;
factor = 1.0 + (model->DIOtranTimeTemp1 * difference)
+ (model->DIOtranTimeTemp2 * difference * difference);
here->DIOtTransitTime = model->DIOtransitTime * factor;
/* Series resistance temperature adjust */
here->DIOtConductance = model->DIOconductance;
if(model->DIOresistGiven && model->DIOresist!=0.0) {
difference = here->DIOtemp - model->DIOnomTemp;
factor = 1.0 + (model->DIOresistTemp1)*difference;
here->DIOtConductance = model->DIOconductance / factor;
}
here->DIOtF2=exp((1+here->DIOtGradingCoeff)*xfc);
here->DIOtF3=1-model->DIOdepletionCapCoeff*
(1+here->DIOtGradingCoeff);
here->DIOtF2SW=exp((1+model->DIOgradingSWCoeff)*xfcs);
here->DIOtF3SW=1-model->DIOdepletionSWcapCoeff*
(1+model->DIOgradingSWCoeff);
} /* instance */
} /* model */
return(OK);
}

5
src/spicelib/devices/dio/diotrunc.c

@ -13,10 +13,7 @@ Author: 1985 Thomas L. Quarles
int
DIOtrunc(inModel,ckt,timeStep)
GENmodel *inModel;
CKTcircuit *ckt;
double *timeStep;
DIOtrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep)
{
DIOmodel *model = (DIOmodel*)inModel;
DIOinstance *here;

Loading…
Cancel
Save