From 88ef78e53bdf0885630a621b47869d01d70b6460 Mon Sep 17 00:00:00 2001 From: dwarning Date: Sun, 15 Mar 2015 10:16:16 +0100 Subject: [PATCH] introduce geometry and frequency dependency for the flicker noise model --- src/spicelib/devices/res/res.c | 5 ++++- src/spicelib/devices/res/resdefs.h | 10 ++++++++++ src/spicelib/devices/res/resmask.c | 9 +++++++++ src/spicelib/devices/res/resmpar.c | 12 ++++++++++++ src/spicelib/devices/res/resnoise.c | 2 +- src/spicelib/devices/res/ressetup.c | 9 +++++++++ 6 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/spicelib/devices/res/res.c b/src/spicelib/devices/res/res.c index 6b507d0c3..9006151eb 100644 --- a/src/spicelib/devices/res/res.c +++ b/src/spicelib/devices/res/res.c @@ -58,7 +58,10 @@ IFparm RESmPTable[] = { /* model parameters */ IOPXU( "tnom", RES_MOD_TNOM, IF_REAL,"Parameter measurement temperature"), IOP( "r", RES_MOD_R, IF_REAL,"Resistor model default value"), IOPR( "res", RES_MOD_R, IF_REAL,"Resistor model default value"), - IOP( "bv_max", RES_MOD_BV_MAX, IF_REAL,"maximum voltage over resistor") + IOP( "bv_max", RES_MOD_BV_MAX, IF_REAL,"maximum voltage over resistor"), + IOP( "lf", RES_MOD_LF, IF_REAL,"noise area length exponent"), + IOP( "wf", RES_MOD_WF, IF_REAL,"noise area width exponent"), + IOP( "ef", RES_MOD_EF, IF_REAL,"noise frequency exponent") }; char *RESnames[] = { diff --git a/src/spicelib/devices/res/resdefs.h b/src/spicelib/devices/res/resdefs.h index 0dfeff817..a8f0578a2 100644 --- a/src/spicelib/devices/res/resdefs.h +++ b/src/spicelib/devices/res/resdefs.h @@ -44,6 +44,7 @@ typedef struct sRESinstance { double REStc2; /* second 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 */ double *RESposPosptr; /* pointer to sparse matrix diagonal at * (positive,positive) */ double *RESnegNegptr; /* pointer to sparse matrix diagonal at @@ -110,6 +111,9 @@ typedef struct sRESmodel { /* model structure for a resistor */ double RESfNexp; /* Flicker noise exponent */ double RESres; /* Default model resistance */ double RESbv_max; /* Maximum resistor voltage */ + double RESlf; /* length exponent for noise calculation */ + double RESwf; /* width exponent for noise calculation */ + double RESef; /* frequncy exponent for noise calculation */ 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 */ @@ -122,6 +126,9 @@ typedef struct sRESmodel { /* model structure for a resistor */ unsigned RESfNexpGiven :1; /* flag to indicate af given */ unsigned RESresGiven :1; /* flag to indicate model resistance given */ unsigned RESbv_maxGiven :1; /* flags indicates maximum voltage is given */ + unsigned RESlfGiven :1; /* flags indicates lf is given */ + unsigned RESwfGiven :1; /* flags indicates wf is given */ + unsigned RESefGiven :1; /* flags indicates ef is given */ } RESmodel; /* device parameters */ @@ -158,6 +165,9 @@ typedef struct sRESmodel { /* model structure for a resistor */ #define RES_MOD_KF 110 #define RES_MOD_AF 111 #define RES_MOD_BV_MAX 112 +#define RES_MOD_LF 113 +#define RES_MOD_WF 114 +#define RES_MOD_EF 115 /* device questions */ #define RES_QUEST_SENS_REAL 201 diff --git a/src/spicelib/devices/res/resmask.c b/src/spicelib/devices/res/resmask.c index d611c4402..46c6ad262 100644 --- a/src/spicelib/devices/res/resmask.c +++ b/src/spicelib/devices/res/resmask.c @@ -66,6 +66,15 @@ RESmodAsk(CKTcircuit *ckt, GENmodel *inModel, int which, IFvalue *value) case RES_MOD_R: value->rValue = model->RESres; return(OK); + case RES_MOD_LF: + value->rValue = model->RESlf; + return(OK); + case RES_MOD_WF: + value->rValue = model->RESwf; + return(OK); + case RES_MOD_EF: + value->rValue = model->RESef; + return(OK); default: return(E_BADPARM); } diff --git a/src/spicelib/devices/res/resmpar.c b/src/spicelib/devices/res/resmpar.c index cf5bdb7e5..478805149 100644 --- a/src/spicelib/devices/res/resmpar.c +++ b/src/spicelib/devices/res/resmpar.c @@ -62,6 +62,18 @@ RESmParam(int param, IFvalue *value, GENmodel *inModel) model->RESbv_max = value->rValue; model->RESbv_maxGiven = TRUE; break; + case RES_MOD_LF: + model->RESlf = value->rValue; + model->RESlfGiven = TRUE; + break; + case RES_MOD_WF: + model->RESwf = value->rValue; + model->RESwfGiven = TRUE; + break; + case RES_MOD_EF: + model->RESef = value->rValue; + model->RESefGiven = TRUE; + break; case RES_MOD_R: if ( value->rValue > 1e-03 ) { model->RESres = value->rValue; diff --git a/src/spicelib/devices/res/resnoise.c b/src/spicelib/devices/res/resnoise.c index 039ae1f62..8c538f95e 100644 --- a/src/spicelib/devices/res/resnoise.c +++ b/src/spicelib/devices/res/resnoise.c @@ -135,7 +135,7 @@ RESnoise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, noizDens[RESFLNOIZ] *= inst->RESm * model->RESfNcoef * exp(model->RESfNexp * log(MAX(fabs(inst->REScurrent), - N_MINLOG))) / data->freq; + N_MINLOG))) / (inst->RESeffNoiseArea*pow(data->freq,model->RESef)); lnNdens[RESFLNOIZ] = log(MAX(noizDens[RESFLNOIZ],N_MINLOG)); noizDens[RESTOTNOIZ] = noizDens[RESTHNOIZ] + noizDens[RESFLNOIZ]; diff --git a/src/spicelib/devices/res/ressetup.c b/src/spicelib/devices/res/ressetup.c index 25e9cc202..44c75ea5f 100644 --- a/src/spicelib/devices/res/ressetup.c +++ b/src/spicelib/devices/res/ressetup.c @@ -36,6 +36,9 @@ RESsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit*ckt, int *state) if(!model->RESshortGiven) model->RESshort = 0.0; if(!model->RESfNcoefGiven) model->RESfNcoef = 0.0; if(!model->RESfNexpGiven) model->RESfNexp = 1.0; + if(!model->RESlfGiven) model->RESlf = 1.0; + if(!model->RESwfGiven) model->RESwf = 1.0; + if(!model->RESefGiven) model->RESef = 1.0; if(!model->RESbv_maxGiven) model->RESbv_max = 1e99; @@ -67,6 +70,12 @@ RESsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit*ckt, int *state) if(!here->RESbv_maxGiven) here->RESbv_max = model->RESbv_max; + if((here->RESwidthGiven)||(here->RESlengthGiven)) + here->RESeffNoiseArea = pow((here->RESlength-model->RESshort),model->RESlf) + *pow((here->RESwidth-model->RESnarrow),model->RESwf); + else + here->RESeffNoiseArea = 1.0; + /* macro to make elements with built in test for out of memory */ #define TSTALLOC(ptr,first,second) \ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\