Introduce element parameter handling for geometry scaled diode (level=3)

This commit is contained in:
dwarning 2021-04-05 10:05:00 +02:00 committed by Holger Vogt
parent 56c8a24dd7
commit a7cf70e615
4 changed files with 61 additions and 12 deletions

View File

@ -19,6 +19,10 @@ IFparm DIOpTable[] = { /* parameters */
IOPU("w", DIO_W, IF_REAL, "Diode width"), IOPU("w", DIO_W, IF_REAL, "Diode width"),
IOPU("l", DIO_L, IF_REAL, "Diode length"), IOPU("l", DIO_L, IF_REAL, "Diode length"),
IOPU("m", DIO_M, IF_REAL, "Multiplier"), IOPU("m", DIO_M, IF_REAL, "Multiplier"),
IOPU("lm", DIO_LM, IF_REAL, "Length of metal capacitor (level=3)"),
IOPU("lp", DIO_LP, IF_REAL, "Length of polysilicon capacitor (level=3)"),
IOPU("wm", DIO_WM, IF_REAL, "Width of metal capacitor (level=3)"),
IOPU("wp", DIO_WP, IF_REAL, "Width of polysilicon capacitor (level=3)"),
IP("sens_area",DIO_AREA_SENS,IF_FLAG,"flag to request sensitivity WRT area"), 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"),

View File

@ -76,12 +76,22 @@ typedef struct sDIOinstance {
unsigned DIOtempGiven : 1; /* flag to indicate temperature was specified */ unsigned DIOtempGiven : 1; /* flag to indicate temperature was specified */
unsigned DIOdtempGiven : 1; /* flag to indicate dtemp given */ unsigned DIOdtempGiven : 1; /* flag to indicate dtemp given */
unsigned DIOlengthMetalGiven : 1; /* Length of metal capacitor (level=3) */
unsigned DIOlengthPolyGiven : 1; /* Length of polysilicon capacitor (level=3) */
unsigned DIOwidthMetalGiven : 1; /* Width of metal capacitor (level=3) */
unsigned DIOwidthPolyGiven : 1; /* Width of polysilicon capacitor (level=3) */
double DIOarea; /* area factor for the diode */ double DIOarea; /* area factor for the diode */
double DIOpj; /* perimeter for the diode */ double DIOpj; /* perimeter for the diode */
double DIOw; /* width for the diode */ double DIOw; /* width for the diode */
double DIOl; /* length for the diode */ double DIOl; /* length for the diode */
double DIOm; /* multiplier for the diode */ double DIOm; /* multiplier for the diode */
double DIOlengthMetal; /* Length of metal capacitor (level=3) */
double DIOlengthPoly; /* Length of polysilicon capacitor (level=3) */
double DIOwidthMetal; /* Width of metal capacitor (level=3) */
double DIOwidthPoly; /* Width of polysilicon capacitor (level=3) */
double DIOinitCond; /* initial condition */ double DIOinitCond; /* initial condition */
double DIOtemp; /* temperature of the instance */ double DIOtemp; /* temperature of the instance */
double DIOdtemp; /* delta temperature of instance */ double DIOdtemp; /* delta temperature of instance */
@ -338,6 +348,10 @@ enum {
DIO_L, DIO_L,
DIO_M, DIO_M,
DIO_DTEMP, DIO_DTEMP,
DIO_LM,
DIO_LP,
DIO_WM,
DIO_WP,
}; };
/* model parameters */ /* model parameters */

View File

@ -67,6 +67,24 @@ DIOparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
case DIO_AREA_SENS: case DIO_AREA_SENS:
here->DIOsenParmNo = value->iValue; here->DIOsenParmNo = value->iValue;
break; break;
case DIO_LM:
here->DIOlengthMetal = value->rValue * scale;
here->DIOlengthMetalGiven = TRUE;
break;
case DIO_LP:
here->DIOlengthPoly = value->rValue * scale;
here->DIOlengthPolyGiven = TRUE;
break;
case DIO_WM:
here->DIOwidthMetal = value->rValue * scale;
here->DIOwidthMetalGiven = TRUE;
break;
case DIO_WP:
here->DIOwidthPoly = value->rValue * scale;
here->DIOwidthPolyGiven = TRUE;
break;
default: default:
return(E_BADPARM); return(E_BADPARM);
} }

View File

@ -20,16 +20,11 @@ Modified by Paolo Nenzi 2003 and Dietmar Warning 2012
int int
DIOsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) DIOsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
{ {
double scale;
DIOmodel *model = (DIOmodel*)inModel; DIOmodel *model = (DIOmodel*)inModel;
DIOinstance *here; DIOinstance *here;
int error; int error;
CKTnode *tmp; CKTnode *tmp;
if (!cp_getvar("scale", CP_REAL, &scale, 0))
scale = 1;
/* loop through all the diode models */ /* loop through all the diode models */
for( ; model != NULL; model = DIOnextModel(model)) { for( ; model != NULL; model = DIOnextModel(model)) {
@ -221,24 +216,42 @@ DIOsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
here->DIOarea = here->DIOarea * here->DIOm; here->DIOarea = here->DIOarea * here->DIOm;
here->DIOpj = here->DIOpj * here->DIOm; here->DIOpj = here->DIOpj * here->DIOm;
here->DIOcmetal = 0.0;
here->DIOcpoly = 0.0;
if (model->DIOlevel == 3) { if (model->DIOlevel == 3) {
double wm, lm, wp, lp;
if((here->DIOwGiven) && (here->DIOlGiven)) { if((here->DIOwGiven) && (here->DIOlGiven)) {
here->DIOarea = here->DIOw * here->DIOl * here->DIOm; here->DIOarea = here->DIOw * here->DIOl * here->DIOm;
here->DIOpj = (2 * here->DIOw + 2 * here->DIOl) * here->DIOm; here->DIOpj = (2 * here->DIOw + 2 * here->DIOl) * here->DIOm;
} }
if (here->DIOwidthMetalGiven)
wm = here->DIOwidthMetal;
else
wm = model->DIOwidthMetal;
if (here->DIOlengthMetalGiven)
lm = here->DIOlengthMetal;
else
lm = model->DIOlengthMetal;
if (here->DIOwidthPolyGiven)
wp = here->DIOwidthPoly;
else
wp = model->DIOwidthPoly;
if (here->DIOlengthPolyGiven)
lp = here->DIOlengthPoly;
else
lp = model->DIOlengthPoly;
here->DIOcmetal = CONSTepsSiO2 / model->DIOmetalOxideThick * here->DIOm
* (wm + model->DIOmetalMaskOffset)
* (lm + model->DIOmetalMaskOffset);
here->DIOcpoly = CONSTepsSiO2 / model->DIOpolyOxideThick * here->DIOm
* (wp + model->DIOpolyMaskOffset)
* (lp + model->DIOpolyMaskOffset);
} }
here->DIOforwardKneeCurrent = model->DIOforwardKneeCurrent * here->DIOarea; here->DIOforwardKneeCurrent = model->DIOforwardKneeCurrent * here->DIOarea;
here->DIOreverseKneeCurrent = model->DIOreverseKneeCurrent * here->DIOarea; here->DIOreverseKneeCurrent = model->DIOreverseKneeCurrent * here->DIOarea;
here->DIOjunctionCap = model->DIOjunctionCap * here->DIOarea; here->DIOjunctionCap = model->DIOjunctionCap * here->DIOarea;
here->DIOjunctionSWCap = model->DIOjunctionSWCap * here->DIOpj; here->DIOjunctionSWCap = model->DIOjunctionSWCap * here->DIOpj;
here->DIOcmetal = CONSTepsSiO2 / model->DIOmetalOxideThick
* (model->DIOwidthMetal * scale + model->DIOmetalMaskOffset)
* (model->DIOlengthMetal * scale + model->DIOmetalMaskOffset);
here->DIOcpoly = CONSTepsSiO2 / model->DIOpolyOxideThick
* (model->DIOwidthPoly * scale + model->DIOpolyMaskOffset)
* (model->DIOlengthPoly * scale + model->DIOpolyMaskOffset);
here->DIOstate = *states; here->DIOstate = *states;
*states += DIOnumStates; *states += DIOnumStates;
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN) ){ if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN) ){