First attempt for geometry scaled diode (level=3)
This commit is contained in:
parent
4bee26b8b9
commit
2a55f50192
|
|
@ -109,6 +109,15 @@ IFparm DIOmPTable[] = { /* model parameters */
|
||||||
IOP( "isr", DIO_MOD_ISR, IF_REAL, "Recombination saturation current"),
|
IOP( "isr", DIO_MOD_ISR, IF_REAL, "Recombination saturation current"),
|
||||||
IOP( "nr", DIO_MOD_NR, IF_REAL, "Recombination current emission coefficient"),
|
IOP( "nr", DIO_MOD_NR, IF_REAL, "Recombination current emission coefficient"),
|
||||||
|
|
||||||
|
IOP( "lm", DIO_MOD_LM, IF_REAL, "Length of metal capacitor (level=3)"),
|
||||||
|
IOP( "lp", DIO_MOD_LP, IF_REAL, "Length of polysilicon capacitor (level=3)"),
|
||||||
|
IOP( "wm", DIO_MOD_WM, IF_REAL, "Width of metal capacitor (level=3)"),
|
||||||
|
IOP( "wp", DIO_MOD_WP, IF_REAL, "Width of polysilicon capacitor (level=3)"),
|
||||||
|
IOP( "xom", DIO_MOD_XOM, IF_REAL, "Thickness of the metal to bulk oxide (level=3)"),
|
||||||
|
IOP( "xoi", DIO_MOD_XOI, IF_REAL, "Thickness of the polysilicon to bulk oxide (level=3)"),
|
||||||
|
IOP( "xm", DIO_MOD_XM, IF_REAL, "Masking and etching effects in metal (level=3)"),
|
||||||
|
IOP( "xp", DIO_MOD_XP, IF_REAL, "Masking and etching effects in polysilicon (level=3)"),
|
||||||
|
|
||||||
IP( "d", DIO_MOD_D, IF_FLAG, "Diode model")
|
IP( "d", DIO_MOD_D, IF_FLAG, "Diode model")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,9 @@ typedef struct sDIOinstance {
|
||||||
double DIOjunctionSWCap; /* geometry adjusted junction sidewall capacitance */
|
double DIOjunctionSWCap; /* geometry adjusted junction sidewall capacitance */
|
||||||
double DIOtRecSatCur; /* temperature adjusted recombination saturation current */
|
double DIOtRecSatCur; /* temperature adjusted recombination saturation current */
|
||||||
|
|
||||||
|
double DIOcmetal; /* parasitic metal overlap capacitance */
|
||||||
|
double DIOcpoly; /* parasitic polysilicon overlap capacitance */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* naming convention:
|
* naming convention:
|
||||||
* x = vdiode
|
* x = vdiode
|
||||||
|
|
@ -235,6 +238,15 @@ typedef struct sDIOmodel { /* model structure for a diode */
|
||||||
unsigned DIOrecSatCurGiven : 1;
|
unsigned DIOrecSatCurGiven : 1;
|
||||||
unsigned DIOrecEmissionCoeffGiven : 1;
|
unsigned DIOrecEmissionCoeffGiven : 1;
|
||||||
|
|
||||||
|
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) */
|
||||||
|
unsigned DIOmetalOxideThickGiven : 1; /* Thickness of the metal to bulk oxide (level=3) */
|
||||||
|
unsigned DIOpolyOxideThickGiven : 1; /* Thickness of the polysilicon to bulk oxide (level=3) */
|
||||||
|
unsigned DIOmetalMaskOffsetGiven : 1; /* Masking and etching effects in metal (level=3)") */
|
||||||
|
unsigned DIOpolyMaskOffsetGiven : 1; /* Masking and etching effects in polysilicon (level=3) */
|
||||||
|
|
||||||
int DIOlevel; /* level selector */
|
int DIOlevel; /* level selector */
|
||||||
double DIOsatCur; /* saturation current */
|
double DIOsatCur; /* saturation current */
|
||||||
double DIOsatSWCur; /* Sidewall saturation current */
|
double DIOsatSWCur; /* Sidewall saturation current */
|
||||||
|
|
@ -290,6 +302,15 @@ typedef struct sDIOmodel { /* model structure for a diode */
|
||||||
double DIOrecSatCur; /* Recombination saturation current */
|
double DIOrecSatCur; /* Recombination saturation current */
|
||||||
double DIOrecEmissionCoeff; /* Recombination emission coefficient */
|
double DIOrecEmissionCoeff; /* Recombination emission coefficient */
|
||||||
|
|
||||||
|
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 DIOmetalOxideThick; /* Thickness of the metal to bulk oxide (level=3) */
|
||||||
|
double DIOpolyOxideThick; /* Thickness of the polysilicon to bulk oxide (level=3) */
|
||||||
|
double DIOmetalMaskOffset; /* Masking and etching effects in metal (level=3)") */
|
||||||
|
double DIOpolyMaskOffset; /* Masking and etching effects in polysilicon (level=3) */
|
||||||
|
|
||||||
} DIOmodel;
|
} DIOmodel;
|
||||||
|
|
||||||
/* device parameters */
|
/* device parameters */
|
||||||
|
|
@ -372,6 +393,15 @@ enum {
|
||||||
DIO_MOD_BV_MAX,
|
DIO_MOD_BV_MAX,
|
||||||
DIO_MOD_ISR,
|
DIO_MOD_ISR,
|
||||||
DIO_MOD_NR,
|
DIO_MOD_NR,
|
||||||
|
|
||||||
|
DIO_MOD_LM,
|
||||||
|
DIO_MOD_LP,
|
||||||
|
DIO_MOD_WM,
|
||||||
|
DIO_MOD_WP,
|
||||||
|
DIO_MOD_XOM,
|
||||||
|
DIO_MOD_XOI,
|
||||||
|
DIO_MOD_XM,
|
||||||
|
DIO_MOD_XP,
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "dioext.h"
|
#include "dioext.h"
|
||||||
|
|
|
||||||
|
|
@ -349,7 +349,8 @@ next1: if (model->DIOsatSWCurGiven) { /* sidewall current */
|
||||||
|
|
||||||
diffcap = here->DIOtTransitTime*gdb;
|
diffcap = here->DIOtTransitTime*gdb;
|
||||||
diffcapSW = here->DIOtTransitTime*gdsw;
|
diffcapSW = here->DIOtTransitTime*gdsw;
|
||||||
capd = diffcap + diffcapSW + deplcap + deplcapSW;
|
|
||||||
|
capd = diffcap + diffcapSW + deplcap + deplcapSW + here->DIOcmetal + here->DIOcpoly;
|
||||||
|
|
||||||
here->DIOcap = capd;
|
here->DIOcap = capd;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -178,6 +178,32 @@ DIOmAsk (CKTcircuit *ckt, GENmodel *inModel, int which, IFvalue *value)
|
||||||
case DIO_MOD_NR:
|
case DIO_MOD_NR:
|
||||||
value->rValue = model->DIOrecEmissionCoeff;
|
value->rValue = model->DIOrecEmissionCoeff;
|
||||||
return(OK);
|
return(OK);
|
||||||
|
|
||||||
|
case DIO_MOD_LM:
|
||||||
|
value->rValue = model->DIOlengthMetal;
|
||||||
|
return(OK);
|
||||||
|
case DIO_MOD_LP:
|
||||||
|
value->rValue = model->DIOlengthPoly;
|
||||||
|
return(OK);
|
||||||
|
case DIO_MOD_WM:
|
||||||
|
value->rValue = model->DIOwidthMetal;
|
||||||
|
return(OK);
|
||||||
|
case DIO_MOD_WP:
|
||||||
|
value->rValue = model->DIOwidthPoly;
|
||||||
|
return(OK);
|
||||||
|
case DIO_MOD_XOM:
|
||||||
|
value->rValue = model->DIOmetalOxideThick;
|
||||||
|
return(OK);
|
||||||
|
case DIO_MOD_XOI:
|
||||||
|
value->rValue = model->DIOpolyOxideThick;
|
||||||
|
return(OK);
|
||||||
|
case DIO_MOD_XM:
|
||||||
|
value->rValue = model->DIOmetalMaskOffset;
|
||||||
|
return(OK);
|
||||||
|
case DIO_MOD_XP:
|
||||||
|
value->rValue = model->DIOpolyMaskOffset;
|
||||||
|
return(OK);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return(E_BADPARM);
|
return(E_BADPARM);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -217,6 +217,40 @@ DIOmParam(int param, IFvalue *value, GENmodel *inModel)
|
||||||
model->DIOrecEmissionCoeff = value->rValue;
|
model->DIOrecEmissionCoeff = value->rValue;
|
||||||
model->DIOrecEmissionCoeffGiven = TRUE;
|
model->DIOrecEmissionCoeffGiven = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DIO_MOD_LM:
|
||||||
|
model->DIOlengthMetal = value->rValue;
|
||||||
|
model->DIOlengthMetalGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case DIO_MOD_LP:
|
||||||
|
model->DIOlengthPoly = value->rValue;
|
||||||
|
model->DIOlengthPolyGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case DIO_MOD_WM:
|
||||||
|
model->DIOwidthMetal = value->rValue;
|
||||||
|
model->DIOwidthMetalGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case DIO_MOD_WP:
|
||||||
|
model->DIOwidthPoly = value->rValue;
|
||||||
|
model->DIOwidthPolyGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case DIO_MOD_XOM:
|
||||||
|
model->DIOmetalOxideThick = value->rValue;
|
||||||
|
model->DIOmetalOxideThickGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case DIO_MOD_XOI:
|
||||||
|
model->DIOpolyOxideThick = value->rValue;
|
||||||
|
model->DIOpolyOxideThickGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case DIO_MOD_XM:
|
||||||
|
model->DIOmetalMaskOffset = value->rValue;
|
||||||
|
model->DIOmetalMaskOffsetGiven = TRUE;
|
||||||
|
break;
|
||||||
|
case DIO_MOD_XP:
|
||||||
|
model->DIOpolyMaskOffset = value->rValue;
|
||||||
|
model->DIOpolyMaskOffsetGiven = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
case DIO_MOD_D:
|
case DIO_MOD_D:
|
||||||
/* no action - we already know we are a diode, but this */
|
/* no action - we already know we are a diode, but this */
|
||||||
/* makes life easier for spice-2 like parsers */
|
/* makes life easier for spice-2 like parsers */
|
||||||
|
|
|
||||||
|
|
@ -15,15 +15,21 @@ Modified by Paolo Nenzi 2003 and Dietmar Warning 2012
|
||||||
#include "diodefs.h"
|
#include "diodefs.h"
|
||||||
#include "ngspice/sperror.h"
|
#include "ngspice/sperror.h"
|
||||||
#include "ngspice/suffix.h"
|
#include "ngspice/suffix.h"
|
||||||
|
#include "ngspice/fteext.h"
|
||||||
|
|
||||||
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)) {
|
||||||
|
|
||||||
|
|
@ -166,6 +172,31 @@ DIOsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
||||||
model->DIOrecSatCur = 1e-14;
|
model->DIOrecSatCur = 1e-14;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!model->DIOlengthMetal) {
|
||||||
|
model->DIOlengthMetal = 0.0;
|
||||||
|
}
|
||||||
|
if(!model->DIOlengthPoly) {
|
||||||
|
model->DIOlengthPoly = 0.0;
|
||||||
|
}
|
||||||
|
if(!model->DIOwidthMetal) {
|
||||||
|
model->DIOwidthMetal = 0.0;
|
||||||
|
}
|
||||||
|
if(!model->DIOwidthPoly) {
|
||||||
|
model->DIOwidthPoly = 0.0;
|
||||||
|
}
|
||||||
|
if(!model->DIOmetalOxideThick) {
|
||||||
|
model->DIOmetalOxideThick = 10e3;
|
||||||
|
}
|
||||||
|
if(!model->DIOpolyOxideThick) {
|
||||||
|
model->DIOpolyOxideThick = 10e3;
|
||||||
|
}
|
||||||
|
if(!model->DIOmetalMaskOffset) {
|
||||||
|
model->DIOmetalMaskOffset = 0.0;
|
||||||
|
}
|
||||||
|
if(!model->DIOpolyMaskOffset) {
|
||||||
|
model->DIOpolyMaskOffset = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
/* loop through all the instances of the model */
|
/* loop through all the instances of the model */
|
||||||
for (here = DIOinstances(model); here != NULL ;
|
for (here = DIOinstances(model); here != NULL ;
|
||||||
here=DIOnextInstance(here)) {
|
here=DIOnextInstance(here)) {
|
||||||
|
|
@ -201,6 +232,13 @@ DIOsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
||||||
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 = 3.9 * 8.854214871e-12 / model->DIOmetalOxideThick
|
||||||
|
* (model->DIOwidthMetal * scale + model->DIOmetalMaskOffset)
|
||||||
|
* (model->DIOlengthMetal * scale + model->DIOmetalMaskOffset);
|
||||||
|
here->DIOcpoly = 3.9 * 8.854214871e-12 / 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) ){
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue