devices/res, introduce TCE, exponential temperature coefficient

This commit is contained in:
rlar 2015-10-31 12:50:31 +01:00
parent 9a1170c032
commit 28c0c96bbc
11 changed files with 90 additions and 6 deletions

View File

@ -23,6 +23,7 @@ IFparm RESpTable[] = { /* parameters */
IOPU( "tc", RES_TC1, IF_REAL, "First order temp. coefficient"),
IOPU( "tc1", RES_TC1, IF_REAL, "First order temp. coefficient"),
IOPU( "tc2", RES_TC2, IF_REAL, "Second order temp. coefficient"),
IOPU( "tce", RES_TCE, IF_REAL, "exponential temp. coefficient"),
IOP( "bv_max", RES_BV_MAX, IF_REAL, "maximum voltage over resistor"),
IOPU( "scale", RES_SCALE, IF_REAL, "Scale factor"),
IOP( "noisy", RES_NOISY, IF_INTEGER, "Resistor generate noise"),
@ -51,6 +52,7 @@ IFparm RESmPTable[] = { /* model parameters */
IOPR( "tc1r", RES_MOD_TC1, IF_REAL,"First order temp. coefficient"),
IOPQO( "tc2", RES_MOD_TC2, IF_REAL,"Second order temp. coefficient"),
IOPR( "tc2r", RES_MOD_TC2, IF_REAL,"Second order temp. coefficient"),
IOPQ( "tce", RES_MOD_TCE, IF_REAL,"exponential temp. coefficient"),
IOPX( "defw", RES_MOD_DEFWIDTH, IF_REAL,"Default device width"),
IOPR( "w", RES_MOD_DEFWIDTH, IF_REAL,"Default device width"),
IOPX( "l", RES_MOD_DEFLENGTH,IF_REAL,"Default device length"),

View File

@ -70,6 +70,9 @@ RESask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value,
case RES_TC2:
value->rValue = fast->REStc2;
return(OK);
case RES_TCE:
value->rValue = fast->REStce;
return(OK);
case RES_BV_MAX:
value->rValue = fast->RESbv_max;
return(OK);

View File

@ -42,6 +42,7 @@ typedef struct sRESinstance {
double RESm; /* Multiplicity factor for this instance */
double REStc1; /* first temperature coefficient of resistors */
double REStc2; /* second temperature coefficient of resistors */
double REStce; /* exponential temperature coefficient of resistors */
double RESbv_max; /* Maximum resistor voltage */
int RESnoisy; /* Set if the resistor generates noise */
double RESeffNoiseArea; /* effective resistor area for noise calculation */
@ -64,6 +65,7 @@ typedef struct sRESinstance {
unsigned RESmGiven : 1; /* indicates M parameter specified */
unsigned REStc1Given : 1; /* indicates tc1 parameter specified */
unsigned REStc2Given : 1; /* indicates tc2 parameter specified */
unsigned REStceGiven : 1; /* indicates tce parameter specified */
unsigned RESnoisyGiven : 1; /* indicates if noisy is specified */
unsigned RESbv_maxGiven : 1; /* flags indicates maximum voltage is given */
int RESsenParmNo; /* parameter # for sensitivity use;
@ -102,6 +104,7 @@ typedef struct sRESmodel { /* model structure for a resistor */
double REStnom; /* temperature at which resistance measured */
double REStempCoeff1; /* first temperature coefficient of resistors */
double REStempCoeff2; /* second temperature coefficient of resistors */
double REStempCoeffe; /* exponential temperature coefficient of resistors */
double RESsheetRes; /* sheet resistance of devices in ohms/square */
double RESdefWidth; /* default width of a resistor */
double RESdefLength; /* default length of a resistor */
@ -117,6 +120,7 @@ typedef struct sRESmodel { /* model structure for a resistor */
unsigned REStnomGiven :1; /* flag to indicate nominal temp. was given */
unsigned REStc1Given :1; /* flag to indicate tc1 was specified */
unsigned REStc2Given :1; /* flag to indicate tc2 was specified */
unsigned REStceGiven :1; /* flag to indicate tce was specified */
unsigned RESsheetResGiven :1; /* flag to indicate sheet resistance given*/
unsigned RESdefWidthGiven :1; /* flag to indicate default width given */
unsigned RESdefLengthGiven :1; /* flag to indicate default length given */
@ -151,6 +155,7 @@ typedef struct sRESmodel { /* model structure for a resistor */
#define RES_TC1 16
#define RES_TC2 17
#define RES_BV_MAX 18
#define RES_TCE 19
/* model parameters */
#define RES_MOD_TC1 101
@ -168,6 +173,7 @@ typedef struct sRESmodel { /* model structure for a resistor */
#define RES_MOD_LF 113
#define RES_MOD_WF 114
#define RES_MOD_EF 115
#define RES_MOD_TCE 116
/* device questions */
#define RES_QUEST_SENS_REAL 201

View File

@ -33,6 +33,9 @@ RESmodAsk(CKTcircuit *ckt, GENmodel *inModel, int which, IFvalue *value)
case RES_MOD_TC2:
value->rValue = model->REStempCoeff2;
return(OK);
case RES_MOD_TCE:
value->rValue = model->REStempCoeffe;
return(OK);
case RES_MOD_RSH:
value->rValue = model->RESsheetRes;
return(OK);

View File

@ -30,6 +30,10 @@ RESmParam(int param, IFvalue *value, GENmodel *inModel)
model->REStempCoeff2 = value->rValue;
model->REStc2Given = TRUE;
break;
case RES_MOD_TCE:
model->REStempCoeffe = value->rValue;
model->REStceGiven = TRUE;
break;
case RES_MOD_RSH:
model->RESsheetRes = value->rValue;
model->RESsheetResGiven = TRUE;

View File

@ -70,6 +70,10 @@ RESparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
here->REStc2 = value->rValue;
here->REStc2Given = TRUE;
break;
case RES_TCE:
here->REStce = value->rValue;
here->REStceGiven = TRUE;
break;
case RES_NOISY:
here->RESnoisy = value->iValue;
here->RESnoisyGiven = TRUE;

View File

@ -32,6 +32,7 @@ RESsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit*ckt, int *state)
if(!model->RESdefLengthGiven) model->RESdefLength = 10e-6;
if(!model->REStc1Given) model->REStempCoeff1 = 0.0;
if(!model->REStc2Given) model->REStempCoeff2 = 0.0;
if(!model->REStceGiven) model->REStempCoeffe = 0.0;
if(!model->RESnarrowGiven) model->RESnarrow = 0.0;
if(!model->RESshortGiven) model->RESshort = 0.0;
if(!model->RESfNcoefGiven) model->RESfNcoef = 0.0;

View File

@ -23,7 +23,7 @@ REStemp(GENmodel *inModel, CKTcircuit *ckt)
RESinstance *here;
double factor;
double difference;
double tc1, tc2;
double tc1, tc2, tce;
/* loop through all the resistor models */
@ -61,8 +61,8 @@ REStemp(GENmodel *inModel, CKTcircuit *ckt)
difference = (here->REStemp + here->RESdtemp) - model->REStnom;
/* instance parameters tc1 and tc2 will override
model parameters tc1 and tc2 */
/* instance parameters tc1,tc2 and tce will override
model parameters tc1,tc2 and tce */
if (here->REStc1Given)
tc1 = here->REStc1; /* instance */
else
@ -73,8 +73,13 @@ REStemp(GENmodel *inModel, CKTcircuit *ckt)
else
tc2 = model->REStempCoeff2;
factor = 1.0 + tc1*difference +
tc2*difference*difference;
if (here->REStceGiven)
tce = here->REStce;
else
tce = model->REStempCoeffe;
factor = ((((tc2 * difference) + tc1) * difference) + 1.0) *
pow(1.01, tce * difference);
here -> RESconduct = (1.0/(here->RESresist * factor * here->RESscale));

View File

@ -1,7 +1,7 @@
## Process this file with automake to produce Makefile.in
TESTS = temper-1.cir temper-2.cir temper-3.cir
TESTS = temper-1.cir temper-2.cir temper-3.cir temper-res-1.cir
TESTS_ENVIRONMENT = ngspice_vpath=$(srcdir) $(SHELL) $(top_srcdir)/tests/bin/check.sh $(top_builddir)/src/ngspice

View File

@ -0,0 +1,55 @@
regression test temper-res-1.cir, TC1 TC2 and TCE
* check res model TC1 TC2, and TCE parameter
.model rtest r r=1000 tc1=2m tc2=30u tce=5m
v1 1 0 dc 5v
r1 1 0 rtest
v2 2 0 dc 5v
r2 2 0 1k tc1=2m tc2=30u tce=5m
.control
let success_count = 0
dc temp 10 100 10.0
let tc1 = 2m
let tc2 = 30u
let tce = 5m
let val1 = -v(1)/i(v1)
let val2 = -v(2)/i(v2)
let tdif = "temp-sweep" - 27.0
let gold = 1000.0 * ((tc2 * tdif + tc1) * tdif + 1) * (1.01^(tce * tdif))
* plot val1
* plot val1/gold - 1
* plot val2
* plot val2/gold - 1
let err1 = vecmax(abs(val1/gold - 1))
let err2 = vecmax(abs(val2/gold - 1))
echo "Note: err1 =" $&err1
echo "Note: err2 =" $&err2
if err1 > 1e-14 or err2 > 1e-14
echo "ERROR: test failed"
else
echo "INFO: success"
let success_count = success_count + 1
end
if success_count ne 1
quit 1
else
quit 0
end
.endc
.end

View File

@ -0,0 +1 @@
INFO: success