Browse Source

devices/res, introduce TCE, exponential temperature coefficient

pre-master-46
rlar 11 years ago
parent
commit
28c0c96bbc
  1. 2
      src/spicelib/devices/res/res.c
  2. 3
      src/spicelib/devices/res/resask.c
  3. 6
      src/spicelib/devices/res/resdefs.h
  4. 3
      src/spicelib/devices/res/resmask.c
  5. 4
      src/spicelib/devices/res/resmpar.c
  6. 4
      src/spicelib/devices/res/resparam.c
  7. 1
      src/spicelib/devices/res/ressetup.c
  8. 15
      src/spicelib/devices/res/restemp.c
  9. 2
      tests/regression/temper/Makefile.am
  10. 55
      tests/regression/temper/temper-res-1.cir
  11. 1
      tests/regression/temper/temper-res-1.out

2
src/spicelib/devices/res/res.c

@ -23,6 +23,7 @@ IFparm RESpTable[] = { /* parameters */
IOPU( "tc", RES_TC1, IF_REAL, "First order temp. coefficient"), IOPU( "tc", RES_TC1, IF_REAL, "First order temp. coefficient"),
IOPU( "tc1", 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( "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"), IOP( "bv_max", RES_BV_MAX, IF_REAL, "maximum voltage over resistor"),
IOPU( "scale", RES_SCALE, IF_REAL, "Scale factor"), IOPU( "scale", RES_SCALE, IF_REAL, "Scale factor"),
IOP( "noisy", RES_NOISY, IF_INTEGER, "Resistor generate noise"), 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"), IOPR( "tc1r", RES_MOD_TC1, IF_REAL,"First order temp. coefficient"),
IOPQO( "tc2", RES_MOD_TC2, IF_REAL,"Second 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"), 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"), IOPX( "defw", RES_MOD_DEFWIDTH, IF_REAL,"Default device width"),
IOPR( "w", 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"), IOPX( "l", RES_MOD_DEFLENGTH,IF_REAL,"Default device length"),

3
src/spicelib/devices/res/resask.c

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

6
src/spicelib/devices/res/resdefs.h

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

3
src/spicelib/devices/res/resmask.c

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

4
src/spicelib/devices/res/resmpar.c

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

4
src/spicelib/devices/res/resparam.c

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

1
src/spicelib/devices/res/ressetup.c

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

15
src/spicelib/devices/res/restemp.c

@ -23,7 +23,7 @@ REStemp(GENmodel *inModel, CKTcircuit *ckt)
RESinstance *here; RESinstance *here;
double factor; double factor;
double difference; double difference;
double tc1, tc2;
double tc1, tc2, tce;
/* loop through all the resistor models */ /* loop through all the resistor models */
@ -61,8 +61,8 @@ REStemp(GENmodel *inModel, CKTcircuit *ckt)
difference = (here->REStemp + here->RESdtemp) - model->REStnom; 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) if (here->REStc1Given)
tc1 = here->REStc1; /* instance */ tc1 = here->REStc1; /* instance */
else else
@ -73,8 +73,13 @@ REStemp(GENmodel *inModel, CKTcircuit *ckt)
else else
tc2 = model->REStempCoeff2; 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)); here -> RESconduct = (1.0/(here->RESresist * factor * here->RESscale));

2
tests/regression/temper/Makefile.am

@ -1,7 +1,7 @@
## Process this file with automake to produce Makefile.in ## 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 TESTS_ENVIRONMENT = ngspice_vpath=$(srcdir) $(SHELL) $(top_srcdir)/tests/bin/check.sh $(top_builddir)/src/ngspice

55
tests/regression/temper/temper-res-1.cir

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

1
tests/regression/temper/temper-res-1.out

@ -0,0 +1 @@
INFO: success
Loading…
Cancel
Save