diff --git a/src/spicelib/devices/dio/dio.c b/src/spicelib/devices/dio/dio.c index 3b292ad41..05e464a94 100644 --- a/src/spicelib/devices/dio/dio.c +++ b/src/spicelib/devices/dio/dio.c @@ -19,6 +19,10 @@ IFparm DIOpTable[] = { /* parameters */ IOPU("w", DIO_W, IF_REAL, "Diode width"), IOPU("l", DIO_L, IF_REAL, "Diode length"), 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"), OP("vd", DIO_VOLTAGE,IF_REAL, "Diode voltage"), diff --git a/src/spicelib/devices/dio/diodefs.h b/src/spicelib/devices/dio/diodefs.h index 46573f4ec..1707daccc 100644 --- a/src/spicelib/devices/dio/diodefs.h +++ b/src/spicelib/devices/dio/diodefs.h @@ -76,12 +76,22 @@ typedef struct sDIOinstance { unsigned DIOtempGiven : 1; /* flag to indicate temperature was specified */ 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 DIOpj; /* perimeter for the diode */ double DIOw; /* width for the diode */ double DIOl; /* length 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 DIOtemp; /* temperature of the instance */ double DIOdtemp; /* delta temperature of instance */ @@ -338,6 +348,10 @@ enum { DIO_L, DIO_M, DIO_DTEMP, + DIO_LM, + DIO_LP, + DIO_WM, + DIO_WP, }; /* model parameters */ diff --git a/src/spicelib/devices/dio/dioparam.c b/src/spicelib/devices/dio/dioparam.c index fc81b17cc..be0d81c18 100644 --- a/src/spicelib/devices/dio/dioparam.c +++ b/src/spicelib/devices/dio/dioparam.c @@ -67,6 +67,24 @@ DIOparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select) case DIO_AREA_SENS: here->DIOsenParmNo = value->iValue; 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: return(E_BADPARM); } diff --git a/src/spicelib/devices/dio/diosetup.c b/src/spicelib/devices/dio/diosetup.c index 47eec1ef9..a9a518802 100644 --- a/src/spicelib/devices/dio/diosetup.c +++ b/src/spicelib/devices/dio/diosetup.c @@ -20,16 +20,11 @@ Modified by Paolo Nenzi 2003 and Dietmar Warning 2012 int DIOsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) { - double scale; - DIOmodel *model = (DIOmodel*)inModel; DIOinstance *here; int error; CKTnode *tmp; - if (!cp_getvar("scale", CP_REAL, &scale, 0)) - scale = 1; - /* loop through all the diode models */ 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->DIOpj = here->DIOpj * here->DIOm; + here->DIOcmetal = 0.0; + here->DIOcpoly = 0.0; if (model->DIOlevel == 3) { + double wm, lm, wp, lp; if((here->DIOwGiven) && (here->DIOlGiven)) { here->DIOarea = here->DIOw * 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->DIOreverseKneeCurrent = model->DIOreverseKneeCurrent * here->DIOarea; here->DIOjunctionCap = model->DIOjunctionCap * here->DIOarea; 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; *states += DIOnumStates; if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN) ){