vbic model implementation including self-heating effect

This commit is contained in:
dwarning 2019-09-05 18:57:20 +02:00 committed by Holger Vogt
parent 1c8992bf15
commit 134e92b78f
8 changed files with 3050 additions and 1262 deletions

View File

@ -1873,24 +1873,26 @@ devmodtranslate(struct card *s, char *subname, wordlist * const orig_modnames)
tfree(name);
name = gettok_node(&t); /* this can be either a model name or a node name. */
wlsub = wl_find(name, orig_modnames);
if (!wlsub)
if (*t) { /* There is another token - perhaps a model */
bxx_printf(&buffer, "%s ", name);
tfree(name);
name = gettok(&t);
if (name == NULL) {
name = copy(""); /* allow 'tfree' */
} else {
found = 0;
while (!found) {
wlsub = wl_find(name, orig_modnames);
}
#ifdef ADMS
if (!wlsub)
if (*t) { /* There is another token - perhaps a model */
bxx_printf(&buffer, "%s ", name);
tfree(name);
name = gettok(&t);
}
#endif
if (wlsub) {
found = 1;
break;
} else {
bxx_printf(&buffer, "%s ", name);
tfree(name);
name = gettok(&t);
if (name == NULL) { /* No token anymore - leave */
name = copy(""); /* allow 'tfree' */
break;
}
}
} /* while */
}
translate_mod_name(&buffer, name, subname, orig_modnames);
tfree(name);

View File

@ -188,7 +188,8 @@ char *VBICnames[] = {
"collector",
"base",
"emitter",
"substrate"
"substrate",
"temp"
};

View File

@ -24,7 +24,7 @@ VBICask(CKTcircuit *ckt, GENinstance *instPtr, int which, IFvalue *value, IFvalu
{
VBICinstance *here = (VBICinstance*)instPtr;
NG_IGNORE(select);
NG_IGNORE(select);
switch(which) {
case VBIC_AREA:

View File

@ -52,6 +52,7 @@ typedef struct sVBICinstance {
const int VBICbaseNode; /* number of base node of vbic */
const int VBICemitNode; /* number of emitter node of vbic */
const int VBICsubsNode; /* number of substrate node of vbic */
const int VBICtempNode; /* number of the temperature node of the vbic */
int VBICcollCXNode; /* number of internal collector node of vbic */
int VBICcollCINode; /* number of internal collector node of vbic */
int VBICbaseBXNode; /* number of internal base node of vbic */
@ -207,6 +208,27 @@ typedef struct sVBICinstance {
double *VBICsubsSIBaseBPPtr; /* pointer to sparse matrix at
* (substrate,substrate) */
/* self heating */
double *VBICcollTempPtr;
double *VBICbaseTempPtr;
double *VBICemitTempPtr;
double *VBICsubsTempPtr;
double *VBICcollCItempPtr;
double *VBICcollCXtempPtr;
double *VBICbaseBItempPtr;
double *VBICbaseBXtempPtr;
double *VBICbaseBPtempPtr;
double *VBICemitEItempPtr;
double *VBICsubsSItempPtr;
double *VBICtempCollCIPtr;
double *VBICtempCollCXPtr;
double *VBICtempBaseBIPtr;
double *VBICtempBaseBXPtr;
double *VBICtempBaseBPPtr;
double *VBICtempEmitEIPtr;
double *VBICtempSubsPtr;
double *VBICtempTempPtr;
unsigned VBICareaGiven :1; /* flag to indicate area was specified */
unsigned VBICoff :1; /* 'off' flag for vbic */
unsigned VBICicVBEGiven :1; /* flag to indicate VBE init. cond. given */
@ -221,6 +243,9 @@ typedef struct sVBICinstance {
double VBICcapbcx;
double VBICcapbep;
double VBICcapbcp;
double VBICcapcth;
int VBIC_selfheat; /* self-heating enabled */
#ifndef NONOISE
double VBICnVar[NSTATVARS][VBICNSRCS];
@ -321,7 +346,13 @@ typedef struct sVBICinstance {
#define VBICirs_Vrs VBICstate+64
#define VBICire_Vre VBICstate+65
#define VBICnumStates 66
#define VBICqcth VBICstate+66 /* thermal capacitor charge */
#define VBICcqcth VBICstate+67 /* thermal capacitor current */
#define VBICvrth VBICstate+68
#define VBICicth_Vrth VBICstate+69
#define VBICnumStates 70
/* per model data */
typedef struct sVBICmodel { /* model structure for a vbic */

File diff suppressed because it is too large Load Diff

View File

@ -472,22 +472,31 @@ VBICsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
}
}
if((model->VBICthermalResistGiven) && (model->VBICthermalResist > 0.0))
here->VBIC_selfheat = 1;
else
here->VBIC_selfheat = 0;
if((model->VBICthermalResistGiven) && (model->VBICthermalCapacitance < 1e-12))
model->VBICthermalCapacitance = 1e-12;
if(here->VBICcollCINode == 0) {
error = CKTmkVolt(ckt, &tmp, here->VBICname, "collCI");
if(error) return(error);
here->VBICcollCINode = tmp->number;
error = CKTmkVolt(ckt, &tmp, here->VBICname, "collCI");
if(error) return(error);
here->VBICcollCINode = tmp->number;
}
if(here->VBICbaseBPNode == 0) {
error = CKTmkVolt(ckt, &tmp, here->VBICname, "baseBP");
if(error) return(error);
here->VBICbaseBPNode = tmp->number;
error = CKTmkVolt(ckt, &tmp, here->VBICname, "baseBP");
if(error) return(error);
here->VBICbaseBPNode = tmp->number;
}
if(here->VBICbaseBINode == 0) {
error = CKTmkVolt(ckt, &tmp, here->VBICname, "baseBI");
if(error) return(error);
here->VBICbaseBINode = tmp->number;
error = CKTmkVolt(ckt, &tmp, here->VBICname, "baseBI");
if(error) return(error);
here->VBICbaseBINode = tmp->number;
}
/* macro to make elements with built in test for out of memory */
@ -549,6 +558,28 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
TSTALLOC(VBICsubsSIBaseBIPtr,VBICsubsSINode,VBICbaseBINode);
TSTALLOC(VBICsubsSIBaseBPPtr,VBICsubsSINode,VBICbaseBPNode);
if (here->VBIC_selfheat) {
TSTALLOC(VBICcollTempPtr,VBICcollNode,VBICtempNode);
TSTALLOC(VBICbaseTempPtr,VBICbaseNode,VBICtempNode);
TSTALLOC(VBICemitTempPtr,VBICemitNode,VBICtempNode);
TSTALLOC(VBICsubsTempPtr,VBICsubsNode,VBICtempNode);
TSTALLOC(VBICcollCItempPtr,VBICcollCINode,VBICtempNode);
TSTALLOC(VBICcollCXtempPtr,VBICcollCXNode,VBICtempNode);
TSTALLOC(VBICbaseBItempPtr,VBICbaseBINode,VBICtempNode);
TSTALLOC(VBICbaseBXtempPtr,VBICbaseBXNode,VBICtempNode);
TSTALLOC(VBICbaseBPtempPtr,VBICbaseBPNode,VBICtempNode);
TSTALLOC(VBICemitEItempPtr,VBICemitEINode,VBICtempNode);
TSTALLOC(VBICsubsSItempPtr,VBICsubsSINode,VBICtempNode);
TSTALLOC(VBICtempCollCIPtr,VBICtempNode,VBICcollCINode);
TSTALLOC(VBICtempCollCXPtr,VBICtempNode,VBICcollCXNode);
TSTALLOC(VBICtempBaseBIPtr,VBICtempNode,VBICbaseBINode);
TSTALLOC(VBICtempBaseBXPtr,VBICtempNode,VBICbaseBXNode);
TSTALLOC(VBICtempBaseBPPtr,VBICtempNode,VBICbaseBPNode);
TSTALLOC(VBICtempEmitEIPtr,VBICtempNode,VBICemitEINode);
TSTALLOC(VBICtempSubsPtr,VBICtempNode,VBICsubsNode);
TSTALLOC(VBICtempTempPtr,VBICtempNode,VBICtempNode);
}
}
}
return(OK);

View File

@ -17,7 +17,7 @@ Spice3 Implementation: 2003 Dietmar Warning DAnalyse GmbH
/* ARGSUSED */
int iret, vbic_4T_it_cf_t(double *, double *, double *);
int iret, vbic_4T_et_cf_t(double *, double *, double *);
int
VBICtemp(GENmodel *inModel, CKTcircuit *ckt)
@ -151,7 +151,7 @@ VBICtemp(GENmodel *inModel, CKTcircuit *ckt)
pnom[106] = model->VBICrevVersion;
pnom[107] = model->VBICrefVersion;
iret = vbic_4T_it_cf_t(p,pnom,&TAMB);
iret = vbic_4T_et_cf_t(p,pnom,&TAMB);
here->VBICtextCollResist = p[1];
here->VBICtintCollResist = p[2];
@ -195,7 +195,7 @@ VBICtemp(GENmodel *inModel, CKTcircuit *ckt)
return(OK);
}
int vbic_4T_it_cf_t(double *p, double *pnom, double *TAMB)
int vbic_4T_et_cf_t(double *p, double *pnom, double *TAMB)
{
double Tini, Tdev, Vtv, rT, dT, xvar1;
double xvar2, xvar3, xvar4, xvar5, xvar6, psiio;

View File

@ -21,7 +21,8 @@ model_numnodes(int type)
type == INPtypelook("bjt504t"))
return 5;
#else
NG_IGNORE(type);
if (type == INPtypelook("VBIC"))
return 5;
#endif
return 4;
@ -37,13 +38,8 @@ void INP2Q(CKTcircuit *ckt, INPtables * tab, struct card *current, CKTnode *gnod
int type; /* the type the model says it is */
char *line; /* the part of the current line left to parse */
char *name; /* the resistor's name */
#ifdef ADMS
const int max_i = 5;
CKTnode *node[5];
#else
const int max_i = 4;
CKTnode *node[4];
#endif
int error; /* error code temporary */
int numnodes; /* flag indicating 4 or 5 nodes */
GENinstance *fast; /* pointer to the actual instance */