From eb7649bdf4e7ea49dbaa2c9557e75d214d5e73cb Mon Sep 17 00:00:00 2001 From: pnenzi Date: Thu, 25 Sep 2003 06:51:48 +0000 Subject: [PATCH] New capacitor model (temperature, geometrical / physical parameters). --- src/spicelib/devices/cap/cap.c | 52 ++++++++++++-------- src/spicelib/devices/cap/capacld.c | 19 ++++---- src/spicelib/devices/cap/capask.c | 34 ++++++++++---- src/spicelib/devices/cap/capdefs.h | 73 ++++++++++++++++++++++------- src/spicelib/devices/cap/capdel.c | 7 +-- src/spicelib/devices/cap/capdest.c | 4 +- src/spicelib/devices/cap/capext.h | 22 --------- src/spicelib/devices/cap/capgetic.c | 5 +- src/spicelib/devices/cap/capload.c | 22 +++++---- src/spicelib/devices/cap/capmask.c | 31 ++++++++++-- src/spicelib/devices/cap/capmdel.c | 7 +-- src/spicelib/devices/cap/capmpar.c | 38 +++++++++++++-- src/spicelib/devices/cap/capparam.c | 23 +++++++-- src/spicelib/devices/cap/cappzld.c | 26 +++++----- src/spicelib/devices/cap/capsacl.c | 9 ++-- src/spicelib/devices/cap/capsetup.c | 53 ++++++++++++++++----- src/spicelib/devices/cap/capsload.c | 7 +-- src/spicelib/devices/cap/capsprt.c | 7 +-- src/spicelib/devices/cap/capsset.c | 7 +-- src/spicelib/devices/cap/capsupd.c | 5 +- src/spicelib/devices/cap/captemp.c | 44 +++++++++++++---- src/spicelib/devices/cap/captrunc.c | 6 +-- 22 files changed, 334 insertions(+), 167 deletions(-) diff --git a/src/spicelib/devices/cap/cap.c b/src/spicelib/devices/cap/cap.c index 695faa3c0..53482a6bc 100644 --- a/src/spicelib/devices/cap/cap.c +++ b/src/spicelib/devices/cap/cap.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: September 2003 - Paolo Nenzi **********/ #include "ngspice.h" @@ -9,28 +10,41 @@ Author: 1985 Thomas L. Quarles #include "suffix.h" IFparm CAPpTable[] = { /* parameters */ - IOPAP("capacitance", CAP_CAP, IF_REAL, "Device capacitance"), - IOPAU("ic", CAP_IC, IF_REAL, "Initial capacitor voltage"), - IOPAU("w", CAP_WIDTH, IF_REAL, "Device width"), - IOPAU("l", CAP_LENGTH, IF_REAL, "Device length"), - IP("sens_cap", CAP_CAP_SENS, IF_FLAG, "flag to request sens. WRT cap."), - OP("i", CAP_CURRENT,IF_REAL, "Device current"), - OP("p", CAP_POWER, IF_REAL, "Instantaneous device power"), - OPU("sens_dc", CAP_QUEST_SENS_DC, IF_REAL, "dc sensitivity "), - OPU("sens_real", CAP_QUEST_SENS_REAL, IF_REAL, "real part of ac sensitivity"), - OPU("sens_imag",CAP_QUEST_SENS_IMAG,IF_REAL, - "dc sens. & imag part of ac sens."), - OPU("sens_mag", CAP_QUEST_SENS_MAG, IF_REAL, "sensitivity of ac magnitude"), - OPU("sens_ph", CAP_QUEST_SENS_PH, IF_REAL, "sensitivity of ac phase"), - OPU("sens_cplx", CAP_QUEST_SENS_CPLX, IF_COMPLEX, "ac sensitivity") + IOPAP("capacitance", CAP_CAP, IF_REAL, "Device capacitance"), + IOPAU("ic", CAP_IC, IF_REAL, "Initial capacitor voltage"), + IOPZU("temp", CAP_TEMP, IF_REAL, "Instance operating temperature"), + IOPZ( "dtemp", CAP_DTEMP, IF_REAL, + "Instance temperature difference from the rest of the circuit"), + IOPAU("w", CAP_WIDTH, IF_REAL, "Device width"), + IOPAU("l", CAP_LENGTH, IF_REAL, "Device length"), + IOPU( "m", CAP_M, IF_REAL, "Parallel multiplier"), + IOPU( "scale", CAP_SCALE, IF_REAL, "Scale factor"), + IP( "sens_cap", CAP_CAP_SENS, IF_FLAG, "flag to request sens. WRT cap."), + OP( "i", CAP_CURRENT, IF_REAL, "Device current"), + OP( "p", CAP_POWER, IF_REAL, "Instantaneous device power"), + OPU( "sens_dc", CAP_QUEST_SENS_DC, IF_REAL, "dc sensitivity "), + OPU( "sens_real", CAP_QUEST_SENS_REAL, IF_REAL, "real part of ac sensitivity"), + OPU( "sens_imag", CAP_QUEST_SENS_IMAG, IF_REAL, + "dc sens. & imag part of ac sens."), + OPU( "sens_mag", CAP_QUEST_SENS_MAG, IF_REAL, "sensitivity of ac magnitude"), + OPU( "sens_ph", CAP_QUEST_SENS_PH, IF_REAL, "sensitivity of ac phase"), + OPU( "sens_cplx", CAP_QUEST_SENS_CPLX, IF_COMPLEX, "ac sensitivity") }; IFparm CAPmPTable[] = { /* names of model parameters */ - IOPA( "cj", CAP_MOD_CJ, IF_REAL, "Bottom Capacitance per area"), - IOPA( "cjsw", CAP_MOD_CJSW, IF_REAL, "Sidewall capacitance per meter"), - IOPX( "defw", CAP_MOD_DEFWIDTH,IF_REAL, "Default width"), - IP( "c", CAP_MOD_C, IF_FLAG, "Capacitor model"), - IOPA( "narrow", CAP_MOD_NARROW, IF_REAL, "width correction factor") + IOPA( "cap", CAP_MOD_CAP, IF_REAL, "Model capacitance"), + IOPA( "cj", CAP_MOD_CJ, IF_REAL, "Bottom Capacitance per area"), + IOPA( "cjsw", CAP_MOD_CJSW, IF_REAL, "Sidewall capacitance per meter"), + IOPX( "defw", CAP_MOD_DEFWIDTH, IF_REAL, "Default width"), + IOPX( "defl", CAP_MOD_DEFLENGTH,IF_REAL, "Default length"), + IOPA( "narrow", CAP_MOD_NARROW, IF_REAL, "width correction factor"), + IOPA( "short", CAP_MOD_SHORT, IF_REAL, "length correction factor"), + IOPA( "tc1", CAP_MOD_TC1, IF_REAL, "First order temp. coefficient"), + IOPA( "tc2", CAP_MOD_TC2, IF_REAL, "Second order temp. coefficient"), + IOPXU("tnom", CAP_MOD_TNOM, IF_REAL, "Parameter measurement temperature"), + IOPA( "di", CAP_MOD_DI, IF_REAL, "Relative dielectric constant"), + IOPA( "thick", CAP_MOD_THICK, IF_REAL, "Insulator thickness"), + IP( "c", CAP_MOD_C, IF_FLAG, "Capacitor model") }; char *CAPnames[] = { diff --git a/src/spicelib/devices/cap/capacld.c b/src/spicelib/devices/cap/capacld.c index 82b6760d0..e2c5c20db 100644 --- a/src/spicelib/devices/cap/capacld.c +++ b/src/spicelib/devices/cap/capacld.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: September 2003 Paolo Nenzi **********/ /* */ @@ -13,25 +14,27 @@ Author: 1985 Thomas L. Quarles int -CAPacLoad(inModel,ckt) - GENmodel *inModel; - CKTcircuit *ckt; - +CAPacLoad(GENmodel *inModel, CKTcircuit *ckt) { CAPmodel *model = (CAPmodel*)inModel; double val; + double m; CAPinstance *here; for( ; model != NULL; model = model->CAPnextModel) { for( here = model->CAPinstances;here != NULL; here = here->CAPnextInstance) { + if (here->CAPowner != ARCHme) continue; + + m = here -> CAPm; val = ckt->CKTomega * here->CAPcapac; - *(here->CAPposPosptr +1) += val; - *(here->CAPnegNegptr +1) += val; - *(here->CAPposNegptr +1) -= val; - *(here->CAPnegPosptr +1) -= val; + + *(here->CAPposPosptr +1) += m * val; + *(here->CAPnegNegptr +1) += m * val; + *(here->CAPposNegptr +1) -= m * val; + *(here->CAPnegPosptr +1) -= m * val; } } return(OK); diff --git a/src/spicelib/devices/cap/capask.c b/src/spicelib/devices/cap/capask.c index cfde81b20..87e1c94d2 100644 --- a/src/spicelib/devices/cap/capask.c +++ b/src/spicelib/devices/cap/capask.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: September 2003 Paolo Nenzi **********/ #include "ngspice.h" @@ -13,12 +14,8 @@ Author: 1985 Thomas L. Quarles /* ARGSUSED */ int -CAPask(ckt,inst, which, value, select) - CKTcircuit *ckt; - GENinstance *inst; - int which; - IFvalue *value; - IFvalue *select; +CAPask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value, + IFvalue *select) { CAPinstance *here = (CAPinstance *)inst; double vr; @@ -29,8 +26,15 @@ CAPask(ckt,inst, which, value, select) static char *msg = "Current and power not available for ac analysis"; switch(which) { + case CAP_TEMP: + value->rValue = here->CAPtemp - CONSTCtoK; + return(OK); + case CAP_DTEMP: + value->rValue = here->CAPdtemp; + return(OK); case CAP_CAP: - value->rValue=here->CAPcapac; + value->rValue=here->CAPcapac; + value->rValue *= here->CAPm; return(OK); case CAP_IC: value->rValue = here->CAPinitCond; @@ -41,6 +45,12 @@ CAPask(ckt,inst, which, value, select) case CAP_LENGTH: value->rValue = here->CAPlength; return(OK); + case CAP_SCALE: + value->rValue = here->CAPscale; + return(OK); + case CAP_M: + value->rValue = here->CAPm; + return(OK); case CAP_CURRENT: if (ckt->CKTcurrentAnalysis & DOING_AC) { errMsg = MALLOC(strlen(msg)+1); @@ -56,7 +66,10 @@ CAPask(ckt,inst, which, value, select) value->rValue = *(ckt->CKTstate0 + here->CAPccap); } } else value->rValue = *(ckt->CKTstate0 + here->CAPccap); - return(OK); + + value->rValue *= here->CAPm; + + return(OK); case CAP_POWER: if (ckt->CKTcurrentAnalysis & DOING_AC) { errMsg = MALLOC(strlen(msg)+1); @@ -76,7 +89,10 @@ CAPask(ckt,inst, which, value, select) } else value->rValue = *(ckt->CKTstate0 + here->CAPccap) * (*(ckt->CKTrhsOld + here->CAPposNode) - *(ckt->CKTrhsOld + here->CAPnegNode)); - return(OK); + + value->rValue *= here->CAPm; + + return(OK); case CAP_QUEST_SENS_DC: if(ckt->CKTsenInfo){ value->rValue = *(ckt->CKTsenInfo->SEN_Sap[select->iValue + 1]+ diff --git a/src/spicelib/devices/cap/capdefs.h b/src/spicelib/devices/cap/capdefs.h index 0ac039fce..03ff9c63b 100644 --- a/src/spicelib/devices/cap/capdefs.h +++ b/src/spicelib/devices/cap/capdefs.h @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: September 2003 Paolo Nenzi **********/ #ifndef CAP @@ -24,26 +25,34 @@ typedef struct sCAPinstance { IFuid CAPname; /* pointer to character string naming this instance */ int CAPowner; /* number of owner process */ int CAPstate; /* pointer to start of capacitor state vector */ - int CAPposNode; /* number of positive node of capacitor */ int CAPnegNode; /* number of negative node of capacitor */ + + double CAPtemp; /* temperature at which this capacitor operates */ + double CAPdtemp; /* delta-temperature of this instance */ double CAPcapac; /* capacitance */ double CAPinitCond; /* initial capacitor voltage if specified */ double CAPwidth; /* width of the capacitor */ double CAPlength; /* length of the capacitor */ + double CAPscale; /* scale factor */ + double CAPm; /* parallel multiplier */ double *CAPposPosptr; /* pointer to sparse matrix diagonal at - * (positive,positive) */ + * (positive,positive) */ double *CAPnegNegptr; /* pointer to sparse matrix diagonal at - * (negative,negative) */ + * (negative,negative) */ double *CAPposNegptr; /* pointer to sparse matrix offdiagonal at - * (positive,negative) */ + * (positive,negative) */ double *CAPnegPosptr; /* pointer to sparse matrix offdiagonal at - * (negative,positive) */ - unsigned CAPcapGiven : 1; /* flag to indicate capacitance was specified */ - unsigned CAPicGiven : 1; /* flag to indicate init. cond. was specified */ - unsigned CAPwidthGiven : 1; /* flag to indicate capacitor width given */ - unsigned CAPlengthGiven : 1; /* flag to indicate capacitor length given*/ + * (negative,positive) */ + unsigned CAPcapGiven : 1; /* flag to indicate capacitance was specified */ + unsigned CAPicGiven : 1; /* flag to indicate init. cond. was specified */ + unsigned CAPwidthGiven : 1; /* flag to indicate capacitor width given */ + unsigned CAPlengthGiven : 1; /* flag to indicate capacitor length given*/ + unsigned CAPtempGiven : 1; /* flag to indicate operating temp given */ + unsigned CAPdtempGiven : 1; /* flag to indicate delta temp given */ + unsigned CAPscaleGiven : 1; /* flag to indicate scale factor given */ + unsigned CAPmGiven : 1; /* flag to indicate parallel multiplier given */ int CAPsenParmNo; /* parameter # for sensitivity use; set equal to 0 if not a design parameter*/ @@ -65,14 +74,32 @@ typedef struct sCAPmodel { /* model structure for a capacitor */ CAPinstance * CAPinstances; /* pointer to list of instances that have this * model */ IFuid CAPmodName; /* pointer to character string naming this model */ - double CAPcj; /* Unit Area Capacitance ( F/ M**2 ) */ - double CAPcjsw; /* Unit Length Sidewall Capacitance ( F / M ) */ - double CAPdefWidth; /* the default width of a capacitor */ - double CAPnarrow; /* amount by which length/width are less than drawn */ - unsigned CAPcjGiven : 1; /* Unit Area Capacitance ( F/ M**2 ) */ - unsigned CAPcjswGiven : 1; /* Unit Length Sidewall Capacitance( F/M )*/ - unsigned CAPdefWidthGiven : 1; /* flag indicates default width given*/ - unsigned CAPnarrowGiven : 1; /* flag indicates narrowing factor given */ + + double CAPtnom; /* temperature at which capacitance measured */ + double CAPtempCoeff1; /* linear temperature coefficient */ + double CAPtempCoeff2; /* quadratic temperature coefficient */ + double CAPmCap; /* Model default capacitance */ + double CAPcj; /* Unit Area Capacitance ( F/ M**2 ) */ + double CAPcjsw; /* Unit Length Sidewall Capacitance ( F / M ) */ + double CAPdefWidth; /* the default width of a capacitor */ + double CAPdefLength; /* the default length of a capacitor */ + double CAPnarrow; /* amount by which width are less than drawn */ + double CAPshort; /* amount by which length are less than drawn */ + double CAPdi; /* Relative dielectric constant */ + double CAPthick; /* Insulator thickness */ + unsigned CAPmCapGiven : 1; /* flag indicates default capacitance given */ + unsigned CAPcjGiven : 1; /* Unit Area Capacitance ( F/ M**2 ) */ + unsigned CAPcjswGiven : 1; /* Unit Length Sidewall Capacitance( F/M )*/ + unsigned CAPdefWidthGiven : 1; /* flag indicates default width given*/ + unsigned CAPdefLengthGiven : 1; /* flag indicates deafult lenght given */ + unsigned CAPnarrowGiven : 1; /* flag indicates narrowing factor given */ + unsigned CAPshortGiven : 1; /* flag indicates shortening factor given */ + unsigned CAPtnomGiven : 1; /* flag indicates nominal temp. given */ + unsigned CAPtc1Given : 1; /* flag indicates tc1 was specified */ + unsigned CAPtc2Given : 1; /* flag indicates tc2 was specified */ + unsigned CAPdiGiven : 1; /* flag indicates epsilon-ins given */ + unsigned CAPthickGiven : 1; /* flags indicates insulator thickness given */ + } CAPmodel; /* device parameters */ @@ -83,6 +110,10 @@ typedef struct sCAPmodel { /* model structure for a capacitor */ #define CAP_CAP_SENS 5 #define CAP_CURRENT 6 #define CAP_POWER 7 +#define CAP_TEMP 8 +#define CAP_DTEMP 9 +#define CAP_SCALE 10 +#define CAP_M 11 /* model parameters */ #define CAP_MOD_CJ 101 @@ -90,6 +121,14 @@ typedef struct sCAPmodel { /* model structure for a capacitor */ #define CAP_MOD_DEFWIDTH 103 #define CAP_MOD_C 104 #define CAP_MOD_NARROW 105 +#define CAP_MOD_SHORT 106 +#define CAP_MOD_TC1 107 +#define CAP_MOD_TC2 108 +#define CAP_MOD_TNOM 109 +#define CAP_MOD_DI 110 +#define CAP_MOD_THICK 111 +#define CAP_MOD_CAP 112 +#define CAP_MOD_DEFLENGTH 113 /* device questions */ #define CAP_QUEST_SENS_REAL 201 diff --git a/src/spicelib/devices/cap/capdel.c b/src/spicelib/devices/cap/capdel.c index 05aa1e2a8..18966b810 100644 --- a/src/spicelib/devices/cap/capdel.c +++ b/src/spicelib/devices/cap/capdel.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: September 2003 Paolo Nenzi **********/ /* */ @@ -12,11 +13,7 @@ Author: 1985 Thomas L. Quarles int -CAPdelete(inModel,name,inst) - GENmodel *inModel; - IFuid name; - GENinstance **inst; - +CAPdelete(GENmodel *inModel, IFuid name, GENinstance **inst) { CAPinstance **fast = (CAPinstance**)inst; diff --git a/src/spicelib/devices/cap/capdest.c b/src/spicelib/devices/cap/capdest.c index a5ebf7b5f..c89886b23 100644 --- a/src/spicelib/devices/cap/capdest.c +++ b/src/spicelib/devices/cap/capdest.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: September 2003 Paolo Nenzi **********/ /* */ @@ -11,8 +12,7 @@ Author: 1985 Thomas L. Quarles void -CAPdestroy(inModel) - GENmodel **inModel; +CAPdestroy(GENmodel **inModel) { diff --git a/src/spicelib/devices/cap/capext.h b/src/spicelib/devices/cap/capext.h index fc66a6da5..4fd5c6d0d 100644 --- a/src/spicelib/devices/cap/capext.h +++ b/src/spicelib/devices/cap/capext.h @@ -3,7 +3,6 @@ Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles **********/ -#ifdef __STDC__ extern int CAPacLoad(GENmodel*,CKTcircuit*); extern int CAPask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*); extern int CAPdelete(GENmodel*,IFuid,GENinstance**); @@ -23,25 +22,4 @@ extern int CAPsUpdate(GENmodel*,CKTcircuit*); extern int CAPsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); extern int CAPtemp(GENmodel*,CKTcircuit*); extern int CAPtrunc(GENmodel*,CKTcircuit*,double*); -#else /* stdc */ -extern int CAPacLoad(); -extern int CAPask(); -extern int CAPdelete(); -extern void CAPdestroy(); -extern int CAPgetic(); -extern int CAPload(); -extern int CAPmAsk(); -extern int CAPmDelete(); -extern int CAPmParam(); -extern int CAPparam(); -extern int CAPpzLoad(); -extern int CAPsAcLoad(); -extern int CAPsLoad(); -extern void CAPsPrint(); -extern int CAPsSetup(); -extern int CAPsUpdate(); -extern int CAPsetup(); -extern int CAPtemp(); -extern int CAPtrunc(); -#endif /* stdc */ diff --git a/src/spicelib/devices/cap/capgetic.c b/src/spicelib/devices/cap/capgetic.c index ea87cf0f3..13cfcfe91 100644 --- a/src/spicelib/devices/cap/capgetic.c +++ b/src/spicelib/devices/cap/capgetic.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: September 2003 Paolo Nenzi **********/ #include "ngspice.h" @@ -10,9 +11,7 @@ Author: 1985 Thomas L. Quarles #include "suffix.h" int -CAPgetic(inModel,ckt) - GENmodel *inModel; - CKTcircuit *ckt; +CAPgetic(GENmodel *inModel, CKTcircuit *ckt) { diff --git a/src/spicelib/devices/cap/capload.c b/src/spicelib/devices/cap/capload.c index 7b0ea40c8..d2452ace1 100644 --- a/src/spicelib/devices/cap/capload.c +++ b/src/spicelib/devices/cap/capload.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: September 2003 Paolo Nenzi **********/ #include "ngspice.h" @@ -11,10 +12,7 @@ Author: 1985 Thomas L. Quarles #include "suffix.h" int -CAPload(inModel,ckt) - - GENmodel *inModel; - CKTcircuit *ckt; +CAPload(GENmodel *inModel, CKTcircuit *ckt) /* actually load the current capacitance value into the * sparse matrix previously provided */ @@ -26,6 +24,7 @@ CAPload(inModel,ckt) double geq; double ceq; int error; + double m; /* check if capacitors are in the circuit or are open circuited */ if(ckt->CKTmode & (MODETRAN|MODEAC|MODETRANOP) ) { @@ -41,8 +40,11 @@ CAPload(inModel,ckt) /* loop through all the instances of the model */ for (here = model->CAPinstances; here != NULL ; here=here->CAPnextInstance) { + if (here->CAPowner != ARCHme) continue; + m = here->CAPm; + if(cond1) { vcap = here->CAPinitCond; } else { @@ -71,12 +73,12 @@ CAPload(inModel,ckt) *(ckt->CKTstate1+here->CAPccap) = *(ckt->CKTstate0+here->CAPccap); } - *(here->CAPposPosptr) += geq; - *(here->CAPnegNegptr) += geq; - *(here->CAPposNegptr) -= geq; - *(here->CAPnegPosptr) -= geq; - *(ckt->CKTrhs+here->CAPposNode) -= ceq; - *(ckt->CKTrhs+here->CAPnegNode) += ceq; + *(here->CAPposPosptr) += m * geq; + *(here->CAPnegNegptr) += m * geq; + *(here->CAPposNegptr) -= m * geq; + *(here->CAPnegPosptr) -= m * geq; + *(ckt->CKTrhs+here->CAPposNode) -= m * ceq; + *(ckt->CKTrhs+here->CAPnegNode) += m * ceq; } else *(ckt->CKTstate0+here->CAPqcap) = here->CAPcapac * vcap; } diff --git a/src/spicelib/devices/cap/capmask.c b/src/spicelib/devices/cap/capmask.c index 7413667e3..a345d4bb1 100644 --- a/src/spicelib/devices/cap/capmask.c +++ b/src/spicelib/devices/cap/capmask.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: September 2003 Paolo Nenzi **********/ /* */ @@ -16,14 +17,22 @@ Author: 1985 Thomas L. Quarles /* ARGSUSED */ int -CAPmAsk(ckt,inst,which,value) - CKTcircuit *ckt; - GENmodel *inst; - int which; - IFvalue *value; +CAPmAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value) { CAPmodel *here = (CAPmodel*)inst; switch(which) { + case CAP_MOD_TNOM: + value->rValue = here->CAPtnom-CONSTCtoK; + return(OK); + case CAP_MOD_TC1: + value->rValue = here->CAPtempCoeff1; + return(OK); + case CAP_MOD_TC2: + value->rValue = here->CAPtempCoeff2; + return(OK); + case CAP_MOD_CAP: + value->rValue = here->CAPmCap; + return(OK); case CAP_MOD_CJ: value->rValue = here->CAPcj; return(OK); @@ -33,9 +42,21 @@ CAPmAsk(ckt,inst,which,value) case CAP_MOD_DEFWIDTH: value->rValue = here->CAPdefWidth; return(OK); + case CAP_MOD_DEFLENGTH: + value->rValue = here->CAPdefLength; + return(OK); case CAP_MOD_NARROW: value->rValue = here->CAPnarrow; return(OK); + case CAP_MOD_SHORT: + value->rValue = here->CAPshort; + return(OK); + case CAP_MOD_DI: + value->rValue = here->CAPdi; + return(OK); + case CAP_MOD_THICK: + value->rValue = here->CAPthick; + return(OK); default: return(E_BADPARM); } diff --git a/src/spicelib/devices/cap/capmdel.c b/src/spicelib/devices/cap/capmdel.c index a22c80c8c..c82abc3b1 100644 --- a/src/spicelib/devices/cap/capmdel.c +++ b/src/spicelib/devices/cap/capmdel.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: Spetember 2003 Paolo Nenzi **********/ /* */ @@ -12,11 +13,7 @@ Author: 1985 Thomas L. Quarles int -CAPmDelete(inModel,modname,kill) - GENmodel **inModel; - IFuid modname; - GENmodel *kill; - +CAPmDelete(GENmodel **inModel, IFuid modname, GENmodel *kill) { CAPmodel *modfast = (CAPmodel*)kill; diff --git a/src/spicelib/devices/cap/capmpar.c b/src/spicelib/devices/cap/capmpar.c index 928a6a2c3..d02eb1bff 100644 --- a/src/spicelib/devices/cap/capmpar.c +++ b/src/spicelib/devices/cap/capmpar.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: September 2003 Paolo Nenzi **********/ /* */ @@ -13,13 +14,26 @@ Author: 1985 Thomas L. Quarles int -CAPmParam(param,value,inModel) - int param; - IFvalue *value; - GENmodel *inModel; +CAPmParam(int param, IFvalue *value, GENmodel *inModel) { CAPmodel *mod = (CAPmodel*)inModel; switch(param) { + case CAP_MOD_TNOM: + mod->CAPtnom = value->rValue+CONSTCtoK; + mod->CAPtnomGiven = TRUE; + break; + case CAP_MOD_TC1: + mod->CAPtempCoeff1 = value->rValue; + mod->CAPtc1Given = TRUE; + break; + case CAP_MOD_TC2: + mod->CAPtempCoeff2 = value->rValue; + mod->CAPtc2Given = TRUE; + break; + case CAP_MOD_CAP: + mod->CAPmCap = value->rValue; + mod->CAPmCapGiven = TRUE; + break; case CAP_MOD_CJ : mod->CAPcj = value->rValue; mod->CAPcjGiven = TRUE; @@ -32,10 +46,26 @@ CAPmParam(param,value,inModel) mod->CAPdefWidth = value->rValue; mod->CAPdefWidthGiven = TRUE; break; + case CAP_MOD_DEFLENGTH: + mod->CAPdefLength = value->rValue; + mod->CAPdefLengthGiven = TRUE; + break; case CAP_MOD_NARROW: mod->CAPnarrow = value->rValue; mod->CAPnarrowGiven = TRUE; break; + case CAP_MOD_SHORT: + mod->CAPshort = value->rValue; + mod->CAPshortGiven = TRUE; + break; + case CAP_MOD_DI: + mod->CAPdi = value->rValue; + mod->CAPdiGiven = TRUE; + break; + case CAP_MOD_THICK: + mod->CAPthick = value->rValue; + mod->CAPthickGiven = TRUE; + break; case CAP_MOD_C: /* just being reassured by the user that we are a capacitor */ /* no-op */ diff --git a/src/spicelib/devices/cap/capparam.c b/src/spicelib/devices/cap/capparam.c index 69d286a2e..32d1b1b04 100644 --- a/src/spicelib/devices/cap/capparam.c +++ b/src/spicelib/devices/cap/capparam.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: September 2003 Paolo Nenzi **********/ /* */ @@ -14,11 +15,7 @@ Author: 1985 Thomas L. Quarles /* ARGSUSED */ int -CAPparam(param,value,inst,select) - int param; - IFvalue *value; - GENinstance *inst; - IFvalue *select; +CAPparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select) { CAPinstance *here = (CAPinstance*)inst; switch(param) { @@ -30,6 +27,14 @@ CAPparam(param,value,inst,select) here->CAPinitCond = value->rValue; here->CAPicGiven = TRUE; break; + case CAP_TEMP: + here->CAPtemp = value->rValue + CONSTCtoK; + here->CAPtempGiven = TRUE; + break; + case CAP_DTEMP: + here->CAPdtemp = value->rValue; + here->CAPdtempGiven = TRUE; + break; case CAP_WIDTH: here->CAPwidth = value->rValue; here->CAPwidthGiven = TRUE; @@ -38,6 +43,14 @@ CAPparam(param,value,inst,select) here->CAPlength = value->rValue; here->CAPlengthGiven = TRUE; break; + case CAP_M: + here->CAPm = value->rValue; + here->CAPmGiven = TRUE; + break; + case CAP_SCALE: + here->CAPscale = value->rValue; + here->CAPscaleGiven = TRUE; + break; case CAP_CAP_SENS: here->CAPsenParmNo = value->iValue; break; diff --git a/src/spicelib/devices/cap/cappzld.c b/src/spicelib/devices/cap/cappzld.c index fe2e9ade0..38b0bdb29 100644 --- a/src/spicelib/devices/cap/cappzld.c +++ b/src/spicelib/devices/cap/cappzld.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: September 2003 Paolo Nenzi **********/ /* */ @@ -15,30 +16,31 @@ Author: 1985 Thomas L. Quarles /* ARGSUSED */ int -CAPpzLoad(inModel,ckt,s) - GENmodel *inModel; - CKTcircuit *ckt; - SPcomplex *s; +CAPpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s) { CAPmodel *model = (CAPmodel*)inModel; double val; + double m; CAPinstance *here; for( ; model != NULL; model = model->CAPnextModel) { for( here = model->CAPinstances;here != NULL; here = here->CAPnextInstance) { + if (here->CAPowner != ARCHme) continue; val = here->CAPcapac; - *(here->CAPposPosptr ) += val * s->real; - *(here->CAPposPosptr +1) += val * s->imag; - *(here->CAPnegNegptr ) += val * s->real; - *(here->CAPnegNegptr +1) += val * s->imag; - *(here->CAPposNegptr ) -= val * s->real; - *(here->CAPposNegptr +1) -= val * s->imag; - *(here->CAPnegPosptr ) -= val * s->real; - *(here->CAPnegPosptr +1) -= val * s->imag; + m = here->CAPm; + + *(here->CAPposPosptr ) += m * val * s->real; + *(here->CAPposPosptr +1) += m * val * s->imag; + *(here->CAPnegNegptr ) += m * val * s->real; + *(here->CAPnegNegptr +1) += m * val * s->imag; + *(here->CAPposNegptr ) -= m * val * s->real; + *(here->CAPposNegptr +1) -= m * val * s->imag; + *(here->CAPnegPosptr ) -= m * val * s->real; + *(here->CAPnegPosptr +1) -= m * val * s->imag; } } return(OK); diff --git a/src/spicelib/devices/cap/capsacl.c b/src/spicelib/devices/cap/capsacl.c index f8fb7d78e..e9be2d46b 100644 --- a/src/spicelib/devices/cap/capsacl.c +++ b/src/spicelib/devices/cap/capsacl.c @@ -1,6 +1,9 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: September 2003 Paolo Nenzi + +This function is obsolete (was used by an old sensitivity analysis) **********/ /* */ @@ -18,11 +21,7 @@ Author: 1985 Thomas L. Quarles int -CAPsAcLoad(inModel,ckt) - -GENmodel *inModel; -CKTcircuit *ckt; - +CAPsAcLoad(GENmodel *inModel, CKTcircuit *ckt) { CAPmodel *model = (CAPmodel*)inModel; CAPinstance *here; diff --git a/src/spicelib/devices/cap/capsetup.c b/src/spicelib/devices/cap/capsetup.c index 986690987..4209ecde9 100644 --- a/src/spicelib/devices/cap/capsetup.c +++ b/src/spicelib/devices/cap/capsetup.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: September 2003 Paolo Nenzi **********/ /* */ @@ -14,11 +15,7 @@ Author: 1985 Thomas L. Quarles /*ARGSUSED*/ int -CAPsetup(matrix,inModel,ckt,states) - SMPmatrix *matrix; - GENmodel *inModel; - CKTcircuit *ckt; - int *states; +CAPsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) /* load the capacitor structure with those pointers needed later * for fast matrix loading */ @@ -31,19 +28,53 @@ CAPsetup(matrix,inModel,ckt,states) for( ; model != NULL; model = model->CAPnextModel ) { /*Default Value Processing for Model Parameters */ - if (!model->CAPcjGiven) { - model->CAPcj = 0; + if (!model->CAPmCapGiven) { + model->CAPmCap = 0.0; } if (!model->CAPcjswGiven){ - model->CAPcjsw = 0; + model->CAPcjsw = 0.0; } if (!model->CAPdefWidthGiven) { model->CAPdefWidth = 10.e-6; } - if (!model->CAPnarrowGiven) { - model->CAPnarrow = 0; + if (!model->CAPdefLengthGiven) { + model->CAPdefLength = 0.0; } - + if (!model->CAPnarrowGiven) { + model->CAPnarrow = 0.0; + } + if (!model->CAPshortGiven) { + model->CAPshort = 0.0; + } + if (!model->CAPtc1Given) { + model->CAPtempCoeff1 = 0.0; + } + if (!model->CAPtc2Given) { + model->CAPtempCoeff2 = 0.0; + } + if (!model->CAPtnomGiven) { + model->CAPtnom = ckt->CKTnomTemp; + } + if (!model->CAPdiGiven) { + model->CAPdi = 0.0; + } + if (!model->CAPthickGiven) { + model->CAPthick = 0.0; + } + + if (!model->CAPcjGiven) { + if((model->CAPthickGiven) + && (model->CAPthick > 0.0)) { + + if (model->CAPdiGiven) + model->CAPcj = (model->CAPdi * CONSTepsZero) / model->CAPthick; + else + model->CAPcj = CONSTepsSiO2 / model->CAPthick; + } else { + model->CAPcj = 0.0; + } + } + /* loop through all the instances of the model */ for (here = model->CAPinstances; here != NULL ; here=here->CAPnextInstance) { diff --git a/src/spicelib/devices/cap/capsload.c b/src/spicelib/devices/cap/capsload.c index 3d672e800..3a8b8958a 100644 --- a/src/spicelib/devices/cap/capsload.c +++ b/src/spicelib/devices/cap/capsload.c @@ -1,6 +1,9 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: September 2003 Paolo Nenzi + +This function is obsolete (was used by an old sensitivity analysis) **********/ /* */ @@ -18,9 +21,7 @@ Author: 1985 Thomas L. Quarles int -CAPsLoad(inModel,ckt) -GENmodel *inModel; -CKTcircuit *ckt; +CAPsLoad(GENmodel *inModel, CKTcircuit *ckt) { CAPmodel *model = (CAPmodel*)inModel; CAPinstance *here; diff --git a/src/spicelib/devices/cap/capsprt.c b/src/spicelib/devices/cap/capsprt.c index 8c6ed0b19..c75c45536 100644 --- a/src/spicelib/devices/cap/capsprt.c +++ b/src/spicelib/devices/cap/capsprt.c @@ -1,6 +1,9 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: September 2003 Paolo Nenzi + +This function is obsolete (was used by an old sensitivity analysis) **********/ /* */ @@ -18,9 +21,7 @@ Author: 1985 Thomas L. Quarles void -CAPsPrint(inModel,ckt) - GENmodel *inModel; - CKTcircuit *ckt; +CAPsPrint(GENmodel *inModel, CKTcircuit *ckt) { CAPmodel *model = (CAPmodel*)inModel; CAPinstance *here; diff --git a/src/spicelib/devices/cap/capsset.c b/src/spicelib/devices/cap/capsset.c index adcc21a8b..519101abf 100644 --- a/src/spicelib/devices/cap/capsset.c +++ b/src/spicelib/devices/cap/capsset.c @@ -1,6 +1,9 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: September 2003 Paolo Nenzi + +This function is obsolete (was used by an old sensitivity analysis) **********/ /* */ @@ -18,9 +21,7 @@ Author: 1985 Thomas L. Quarles int -CAPsSetup(info,inModel) - SENstruct *info; - GENmodel *inModel; +CAPsSetup(SENstruct *info, GENmodel *inModel) { CAPmodel *model = (CAPmodel*)inModel; diff --git a/src/spicelib/devices/cap/capsupd.c b/src/spicelib/devices/cap/capsupd.c index fd50cbd19..38410c1bd 100644 --- a/src/spicelib/devices/cap/capsupd.c +++ b/src/spicelib/devices/cap/capsupd.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: September 2003 Paolo Nenzi **********/ /* */ @@ -16,9 +17,7 @@ Author: 1985 Thomas L. Quarles int -CAPsUpdate(inModel,ckt) - GENmodel *inModel; - CKTcircuit *ckt; +CAPsUpdate(GENmodel *inModel, CKTcircuit *ckt) { CAPmodel *model = (CAPmodel*)inModel; CAPinstance *here; diff --git a/src/spicelib/devices/cap/captemp.c b/src/spicelib/devices/cap/captemp.c index 07c71df20..16f1bd9e1 100644 --- a/src/spicelib/devices/cap/captemp.c +++ b/src/spicelib/devices/cap/captemp.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: September 2003 Paolo Nenzi **********/ /* */ @@ -18,13 +19,13 @@ Author: 1985 Thomas L. Quarles /*ARGSUSED*/ int -CAPtemp(inModel,ckt) - GENmodel *inModel; - CKTcircuit *ckt; +CAPtemp(GENmodel *inModel, CKTcircuit *ckt) { CAPmodel *model = (CAPmodel*)inModel; CAPinstance *here; + double difference; + double factor; /* loop through all the capacitor models */ for( ; model != NULL; model = model->CAPnextModel ) { @@ -35,19 +36,44 @@ CAPtemp(inModel,ckt) if (here->CAPowner != ARCHme) continue; /* Default Value Processing for Capacitor Instance */ + if(!here->CAPtempGiven) { + here->CAPtemp = ckt->CKTtemp; + if(!here->CAPdtempGiven) here->CAPdtemp = 0.0; + } else { /* CAPtempGiven */ + here->CAPdtemp = 0.0; + if (here->CAPdtempGiven) + printf("%s: Instance temperature specified, dtemp ignored\n", + here->CAPname); + } + if (!here->CAPwidthGiven) { here->CAPwidth = model->CAPdefWidth; } - if (!here->CAPcapGiven) { - here->CAPcapac = + if (!here->CAPscaleGiven) here->CAPscale = 1.0; + if (!here->CAPmGiven) here->CAPm = 1.0; + + if (!here->CAPcapGiven) { /* No instance capacitance given */ + if (!model->CAPmCapGiven){ /* No model capacitange given */ + here->CAPcapac = model->CAPcj * (here->CAPwidth - model->CAPnarrow) * - (here->CAPlength - model->CAPnarrow) + + (here->CAPlength - model->CAPshort) + model->CAPcjsw * 2 * ( - (here->CAPlength - model->CAPnarrow) + + (here->CAPlength - model->CAPshort) + (here->CAPwidth - model->CAPnarrow) ); - } - } + } else { + here->CAPcapac = model->CAPmCap; + } + } + + difference = (here->CAPtemp + here->CAPdtemp) - model->CAPtnom; + + factor = 1.0 + (model->CAPtempCoeff1)*difference + + (model->CAPtempCoeff2)*difference*difference; + + here->CAPcapac = here->CAPcapac * factor * here->CAPscale; + + } } return(OK); } diff --git a/src/spicelib/devices/cap/captrunc.c b/src/spicelib/devices/cap/captrunc.c index fd99909a5..b53971cdc 100644 --- a/src/spicelib/devices/cap/captrunc.c +++ b/src/spicelib/devices/cap/captrunc.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: September 2003 Paolo Nenzi **********/ /* */ @@ -13,10 +14,7 @@ Author: 1985 Thomas L. Quarles int -CAPtrunc(inModel,ckt,timeStep) - GENmodel *inModel; - CKTcircuit *ckt; - double *timeStep; +CAPtrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep) { CAPmodel *model = (CAPmodel*)inModel; CAPinstance *here;