First attempt for geometry scaled diode (level=3)

This commit is contained in:
dwarning 2021-04-02 17:17:41 +02:00 committed by Holger Vogt
parent 4bee26b8b9
commit 2a55f50192
6 changed files with 139 additions and 1 deletions

View File

@ -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")
}; };

View File

@ -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"

View File

@ -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;

View File

@ -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);
} }

View File

@ -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 */

View File

@ -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) ){