You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

134 lines
3.5 KiB

/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1988 Jaijeet S Roychowdhury
**********/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "diodefs.h"
#include "const.h"
#include "sperror.h"
#include "suffix.h"
/* actually load the current resistance value into the sparse matrix
* previously provided */
int
DIOdSetup(DIOmodel *model, CKTcircuit *ckt)
{
DIOinstance *here;
double arg;
double csat; /* area-scaled saturation current */
double czero;
double czof2;
double evd;
double evrev;
double gd;
double sarg;
double vd; /* current diode voltage */
double vt; /* K t / Q */
double vte;
double g2,g3;
double cdiff2,cdiff3;
double cjunc1,cjunc2,cjunc3;
/* loop through all the diode models */
for( ; model != NULL; model = model->DIOnextModel ) {
/* loop through all the instances of the model */
for (here = model->DIOinstances; here != NULL ;
here=here->DIOnextInstance) {
if (here->DIOowner != ARCHme) continue;
/*
* this routine loads diodes for dc and transient analyses.
*/
csat=here->DIOtSatCur*here->DIOarea;
vt = CONSTKoverQ * here->DIOtemp;
vte=model->DIOemissionCoeff * vt;
vd = *(ckt->CKTrhsOld + (here->DIOposPrimeNode)) -
*(ckt->CKTrhsOld + (here->DIOnegNode));
/*
* compute derivatives
*/
if (vd >= -5*vte) {
evd = exp(vd/vte);
gd = csat*evd/vte+ckt->CKTgmin;
g2 = 0.5*(gd-ckt->CKTgmin)/vte;
cdiff2 = g2*model->DIOtransitTime;
g3 = g2/3/vte;
cdiff3 = g3*model->DIOtransitTime;
}
else if((!(here->DIOtBrkdwnV))||
(vd >= -here->DIOtBrkdwnV)) {
gd = -csat/vd+ckt->CKTgmin;
g2=g3=cdiff2=cdiff3=0.0;
/* off */
}
else {
/* reverse breakdown */
/* why using csat instead of breakdowncurrent? */
evrev=exp(-(here->DIOtBrkdwnV+vd)/vt);
/*
cd = -csat*(evrev-1+here->DIOtBrkdwnV/vt);
*/
/* should there be a minus here above? */
gd=csat*evrev/vt;
g2 = -gd/2/vt;
g3 = -g2/3/vt;
cdiff3 = cdiff2 = 0;
}
/*
* junction charge storage elements
*/
czero=here->DIOtJctCap*here->DIOarea;
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);
}
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;
}
/*
* store small-signal parameters
*/
here->id_x2 = g2;
here->id_x3 = g3;
here->cdif_x2 = cdiff2;
here->cdif_x3 = cdiff3;
here->cjnc_x2 = cjunc2;
here->cjnc_x3 = cjunc3;
}
}
return(OK);
}