Exemplo n.º 1
0
void cm_analog_alloc(
    int tag,            /* The user-specified tag for this block of memory */
    int bytes)          /* The number of bytes to allocate */
{
    MIFinstance *here;
    CKTcircuit  *ckt;

    Mif_State_t *state;

    int         doubles_needed;
    int         i;


    /* Get the address of the ckt and instance structs from g_mif_info */
    here = g_mif_info.instance;
    ckt  = g_mif_info.ckt;

    /* Scan states in instance struct and see if tag has already been used */
    for(i = 0; i < here->num_state; i++) {
        if(tag == here->state[i].tag) {
            g_mif_info.errmsg = "ERROR - cm_analog_alloc() - Tag already used in previous call\n";
            return;
        }
    }

    /* Compute number of doubles needed and allocate space in ckt->CKTstates[i] */
    doubles_needed = bytes / (int) sizeof(double) + 1;

    /* Allocate space in instance struct for this state descriptor */
    if(here->num_state == 0) {
        here->num_state = 1;
        here->state = TMALLOC(Mif_State_t, 1);
    }
    else {
        here->num_state++;
        here->state = TREALLOC(Mif_State_t, here->state, here->num_state);
    }

    /* Fill in the members of the state descriptor struct */
    state = &(here->state[here->num_state - 1]);
    state->tag = tag;
    state->index = ckt->CKTnumStates;
    state->doubles = doubles_needed;
    state->bytes = bytes;


    /* Add the states to the ckt->CKTstates vectors */
    ckt->CKTnumStates += doubles_needed;
    for(i=0;i<=ckt->CKTmaxOrder+1;i++) {
        if(ckt->CKTnumStates == doubles_needed)
            ckt->CKTstates[i] = TMALLOC(double, ckt->CKTnumStates);
        else
            ckt->CKTstates[i] = TREALLOC(double, ckt->CKTstates[i], ckt->CKTnumStates);
    }
Exemplo n.º 2
0
int
SWnoise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, Ndata *data, double *OnDens)
{
    NOISEAN *job = (NOISEAN *) ckt->CKTcurJob;

    SWmodel *firstModel = (SWmodel *) genmodel;
    SWmodel *model;
    SWinstance *inst;
    char name[N_MXVLNTH];
    double tempOutNoise;
    double tempInNoise;
    double noizDens;
    double lnNdens;
    int current_state;


    for (model=firstModel; model != NULL; model=model->SWnextModel) {
        for (inst=model->SWinstances; inst != NULL; inst=inst->SWnextInstance) {

            switch (operation) {

            case N_OPEN:

                /* see if we have to to produce a summary report */
                /* if so, name the noise generator */

                if (job->NStpsSm != 0) {
                    switch (mode) {

                    case N_DENS:
                        (void)sprintf(name,"onoise_%s",inst->SWname);


                        data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
                        if (!data->namelist) return(E_NOMEM);
                        SPfrontEnd->IFnewUid (ckt,
                                              &(data->namelist[data->numPlots++]),
                                              NULL, name, UID_OTHER, NULL);
                        /* we've added one more plot */


                        break;

                    case INT_NOIZ:
                        (void)sprintf(name,"onoise_total_%s",inst->SWname);


                        data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
                        if (!data->namelist) return(E_NOMEM);
                        SPfrontEnd->IFnewUid (ckt,
                                              &(data->namelist[data->numPlots++]),
                                              NULL, name, UID_OTHER, NULL);
                        /* we've added one more plot */


                        (void)sprintf(name,"inoise_total_%s",inst->SWname);


                        data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
                        if (!data->namelist) return(E_NOMEM);
                        SPfrontEnd->IFnewUid (ckt,
                                              &(data->namelist[data->numPlots++]),
                                              NULL, name, UID_OTHER, NULL);
                        /* we've added one more plot */


                        break;
                    }
                }
                break;

            case N_CALC:
                switch (mode) {

                case N_DENS:
                    current_state = (int)*(ckt->CKTstate0 + inst->SWstate);
                    NevalSrc(&noizDens,&lnNdens,ckt,THERMNOISE,
                             inst->SWposNode,inst->SWnegNode,
                             current_state?(model->SWonConduct):(model->SWoffConduct));

                    *OnDens += noizDens;

                    if (data->delFreq == 0.0) {

                        /* if we haven't done any previous integration, we need to */
                        /* initialize our "history" variables                      */

                        inst->SWnVar[LNLSTDENS] = lnNdens;

                        /* clear out our integration variable if it's the first pass */

                        if (data->freq == job->NstartFreq) {
                            inst->SWnVar[OUTNOIZ] = 0.0;
                        }
                    } else {   /* data->delFreq != 0.0 (we have to integrate) */
                        tempOutNoise = Nintegrate(noizDens, lnNdens,
                                                  inst->SWnVar[LNLSTDENS], data);
                        tempInNoise = Nintegrate(noizDens *
                                                 data->GainSqInv ,lnNdens + data->lnGainInv,
                                                 inst->SWnVar[LNLSTDENS] + data->lnGainInv,
                                                 data);
                        inst->SWnVar[OUTNOIZ] += tempOutNoise;
                        inst->SWnVar[INNOIZ] += tempInNoise;
                        data->outNoiz += tempOutNoise;
                        data->inNoise += tempInNoise;
                        inst->SWnVar[LNLSTDENS] = lnNdens;
                    }
                    if (data->prtSummary) {
                        data->outpVector[data->outNumber++] = noizDens;
                    }
                    break;

                case INT_NOIZ:        /* already calculated, just output */
                    if (job->NStpsSm != 0) {
                        data->outpVector[data->outNumber++] = inst->SWnVar[OUTNOIZ];
                        data->outpVector[data->outNumber++] = inst->SWnVar[INNOIZ];
                    }    /* if */
                    break;
                }    /* switch (mode) */
                break;

            case N_CLOSE:
                return (OK);         /* do nothing, the main calling routine will close */
                break;               /* the plots */
            }    /* switch (operation) */
        }    /* for inst */
    }    /* for model */

    return(OK);
}
Exemplo n.º 3
0
static int
pack_vector(int vector)
{
    int i, j, k, l;
    int t;
    int loc;
    int ok;
    Value_t *from;
    Value_t *to;
    int newmax;

    i = order[vector];
    t = tally[i];
    assert(t);

    from = froms[i];
    to = tos[i];

    j = lowzero - from[0];
    for (k = 1; k < t; ++k)
	if (lowzero - from[k] > j)
	    j = lowzero - from[k];
    for (;; ++j)
    {
	if (j == 0)
	    continue;
	ok = 1;
	for (k = 0; ok && k < t; k++)
	{
	    loc = j + from[k];
	    if (loc >= maxtable - 1)
	    {
		if (loc >= MAXTABLE - 1)
		    fatal("maximum table size exceeded");

		newmax = maxtable;
		do
		{
		    newmax += 200;
		}
		while (newmax <= loc);

		table = TREALLOC(Value_t, table, newmax);
		NO_SPACE(table);

		check = TREALLOC(Value_t, check, newmax);
		NO_SPACE(check);

		for (l = maxtable; l < newmax; ++l)
		{
		    table[l] = 0;
		    check[l] = -1;
		}
		maxtable = newmax;
	    }

	    if (check[loc] != -1)
		ok = 0;
	}
	for (k = 0; ok && k < vector; k++)
	{
	    if (pos[k] == j)
		ok = 0;
	}
	if (ok)
	{
	    for (k = 0; k < t; k++)
	    {
		loc = j + from[k];
		table[loc] = to[k];
		check[loc] = from[k];
		if (loc > high)
		    high = loc;
	    }

	    while (check[lowzero] != -1)
		++lowzero;

	    return (j);
	}
    }
}
Exemplo n.º 4
0
int
BSIM3v32noise (int mode, int operation, GENmodel *inModel, CKTcircuit *ckt,
            Ndata *data, double *OnDens)
{
NOISEAN *job = (NOISEAN *) ckt->CKTcurJob;

BSIM3v32model *model = (BSIM3v32model *)inModel;
BSIM3v32instance *here;
struct bsim3v32SizeDependParam *pParam;
char name[N_MXVLNTH];
double tempOnoise;
double tempInoise;
double noizDens[BSIM3v32NSRCS];
double lnNdens[BSIM3v32NSRCS];

double vgs, vds, Slimit;
double T1, T10, T11;
double Ssi, Swi;

double m;

int i;

    /* define the names of the noise sources */
    static char *BSIM3v32nNames[BSIM3v32NSRCS] =
    {   /* Note that we have to keep the order */
        ".rd",              /* noise due to rd */
                            /* consistent with the index definitions */
        ".rs",              /* noise due to rs */
                            /* in BSIM3v32defs.h */
        ".id",              /* noise due to id */
        ".1overf",          /* flicker (1/f) noise */
        ""                  /* total transistor noise */
    };

    for (; model != NULL; model = model->BSIM3v32nextModel)
    {    for (here = model->BSIM3v32instances; here != NULL;
              here = here->BSIM3v32nextInstance)
         {    pParam = here->pParam;
              switch (operation)
              {  case N_OPEN:
                     /* see if we have to to produce a summary report */
                     /* if so, name all the noise generators */

                      if (job->NStpsSm != 0)
                      {   switch (mode)
                          {  case N_DENS:
                                  for (i = 0; i < BSIM3v32NSRCS; i++)
                                  {    (void) sprintf(name, "onoise.%s%s",
                                                      here->BSIM3v32name,
                                                      BSIM3v32nNames[i]);
                                       data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
                                       if (!data->namelist)
                                           return(E_NOMEM);
                                       SPfrontEnd->IFnewUid (ckt,
                                          &(data->namelist[data->numPlots++]),
                                          NULL, name, UID_OTHER,
                                          NULL);
                                       /* we've added one more plot */
                                  }
                                  break;
                             case INT_NOIZ:
                                  for (i = 0; i < BSIM3v32NSRCS; i++)
                                  {    (void) sprintf(name, "onoise_total.%s%s",
                                                      here->BSIM3v32name,
                                                      BSIM3v32nNames[i]);
                                       data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
                                       if (!data->namelist)
                                           return(E_NOMEM);
                                       SPfrontEnd->IFnewUid (ckt,
                                          &(data->namelist[data->numPlots++]),
                                          NULL, name, UID_OTHER,
                                          NULL);
                                       /* we've added one more plot */

                                       (void) sprintf(name, "inoise_total.%s%s",
                                                      here->BSIM3v32name,
                                                      BSIM3v32nNames[i]);
                                       data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
                                       if (!data->namelist)
                                           return(E_NOMEM);
                                       SPfrontEnd->IFnewUid (ckt,
                                          &(data->namelist[data->numPlots++]),
                                          NULL, name, UID_OTHER,
                                          NULL);
                                       /* we've added one more plot */
                                  }
                                  break;
                          }
                      }
                      break;
                 case N_CALC:
                      m = here->BSIM3v32m;
                      switch (mode)
                      {  case N_DENS:
                              NevalSrc(&noizDens[BSIM3v32RDNOIZ],
                                       &lnNdens[BSIM3v32RDNOIZ], ckt, THERMNOISE,
                                       here->BSIM3v32dNodePrime, here->BSIM3v32dNode,
                                       here->BSIM3v32drainConductance * m);

                              NevalSrc(&noizDens[BSIM3v32RSNOIZ],
                                       &lnNdens[BSIM3v32RSNOIZ], ckt, THERMNOISE,
                                       here->BSIM3v32sNodePrime, here->BSIM3v32sNode,
                                       here->BSIM3v32sourceConductance * m);

                              switch( model->BSIM3v32noiMod )
                              {  case 1:
                                 case 3:
                                      NevalSrc(&noizDens[BSIM3v32IDNOIZ],
                                               &lnNdens[BSIM3v32IDNOIZ], ckt,
                                               THERMNOISE, here->BSIM3v32dNodePrime,
                                               here->BSIM3v32sNodePrime,
                                               (2.0 / 3.0 * fabs(here->BSIM3v32gm
                                               + here->BSIM3v32gds
                                               + here->BSIM3v32gmbs)) * m);
                                      break;
                                 case 2:
                                 case 4:
                                            /* Added revision dependent code */
                                            if (model->BSIM3v32intVersion == BSIM3v32V324)
                                      {
                                        NevalSrc(&noizDens[BSIM3v32IDNOIZ],
                                               &lnNdens[BSIM3v32IDNOIZ], ckt,
                                               THERMNOISE, here->BSIM3v32dNodePrime,
                                               here->BSIM3v32sNodePrime,
                                               (m * here->BSIM3v32ueff
                                               * fabs(here->BSIM3v32qinv)
                                               / (pParam->BSIM3v32leff * pParam->BSIM3v32leff
                                                + here->BSIM3v32ueff * fabs(here->BSIM3v32qinv)
                                                * here->BSIM3v32rds)));    /* bugfix */
                                      }
                                            else
                                      {        /* for all versions lower then 3.2.4 */
                                        NevalSrc(&noizDens[BSIM3v32IDNOIZ],
                                               &lnNdens[BSIM3v32IDNOIZ], ckt,
                                               THERMNOISE, here->BSIM3v32dNodePrime,
                                               here->BSIM3v32sNodePrime,
                                               (m * here->BSIM3v32ueff
                                               * fabs(here->BSIM3v32qinv
                                               / (pParam->BSIM3v32leff
                                               * pParam->BSIM3v32leff))));
                                      }
                                      break;
                              }
                              NevalSrc(&noizDens[BSIM3v32FLNOIZ], NULL,
                                       ckt, N_GAIN, here->BSIM3v32dNodePrime,
                                       here->BSIM3v32sNodePrime, (double) 0.0);

                              switch( model->BSIM3v32noiMod )
                              {  case 1:
                                 case 4:
                                      noizDens[BSIM3v32FLNOIZ] *= m * model->BSIM3v32kf
                                            * exp(model->BSIM3v32af
                                            * log(MAX(fabs(here->BSIM3v32cd),
                                            N_MINLOG)))
                                            / (pow(data->freq, model->BSIM3v32ef)
                                            * pParam->BSIM3v32leff
                                            * pParam->BSIM3v32leff
                                            * model->BSIM3v32cox);
                                      break;
                                 case 2:
                                 case 3:
                                      vgs = *(ckt->CKTstates[0] + here->BSIM3v32vgs);
                                            vds = *(ckt->CKTstates[0] + here->BSIM3v32vds);
                                      if (vds < 0.0)
                                      {   vds = -vds;
                                          vgs = vgs + vds;
                                      }
                                            /* Added revision dependent code */
                                            if (model->BSIM3v32intVersion == BSIM3v32V324)
                                      {
                                        Ssi = StrongInversionNoiseEvalNew(vds, model,
                                                      here, data->freq, ckt->CKTtemp);
                                        T10 = model->BSIM3v32oxideTrapDensityA
                                            * 8.62e-5 * ckt->CKTtemp;
                                        T11 = pParam->BSIM3v32weff
                                            * pParam->BSIM3v32leff
                                            * pow(data->freq, model->BSIM3v32ef)
                                            * 4.0e36;
                                        Swi = T10 / T11 * here->BSIM3v32cd
                                            * here->BSIM3v32cd;
                                        T1 = Swi + Ssi;
                                        if (T1 > 0.0)
                                            noizDens[BSIM3v32FLNOIZ] *= m * (Ssi * Swi) / T1;
                                        else
                                            noizDens[BSIM3v32FLNOIZ] *= 0.0;
                                      }
                                            else
                                      {        /* for all versions lower then 3.2.4 */
                                        if (vgs >= here->BSIM3v32von + 0.1)
                                          {
                                            Ssi = StrongInversionNoiseEvalOld(vgs, vds, model,
                                                        here, data->freq, ckt->CKTtemp);
                                            noizDens[BSIM3v32FLNOIZ] *= m * Ssi;
                                          }
                                        else
                                          {
                                            pParam = here->pParam;
                                            T10 = model->BSIM3v32oxideTrapDensityA
                                                  * 8.62e-5 * ckt->CKTtemp;
                                            T11 = pParam->BSIM3v32weff
                                                  * pParam-> BSIM3v32leff
                                                  * pow (data->freq, model->BSIM3v32ef)
                                                  * 4.0e36;
                                            Swi = T10 / T11 * here->BSIM3v32cd * here->BSIM3v32cd;

                                            Slimit = StrongInversionNoiseEvalOld(
                                                 here->BSIM3v32von + 0.1, vds, model,
                                                 here, data->freq, ckt->CKTtemp);
                                            T1 = Swi + Slimit;
                                            if (T1 > 0.0)
                                                        noizDens[BSIM3v32FLNOIZ] *= m * (Slimit * Swi) / T1;
                                            else
                                                        noizDens[BSIM3v32FLNOIZ] *= 0.0;
                                          }
                                        }
                                        break;
                              }

                              lnNdens[BSIM3v32FLNOIZ] =
                                             log(MAX(noizDens[BSIM3v32FLNOIZ], N_MINLOG));

                              noizDens[BSIM3v32TOTNOIZ] = noizDens[BSIM3v32RDNOIZ]
                                                     + noizDens[BSIM3v32RSNOIZ]
                                                     + noizDens[BSIM3v32IDNOIZ]
                                                     + noizDens[BSIM3v32FLNOIZ];
                              lnNdens[BSIM3v32TOTNOIZ] =
                                     log(MAX(noizDens[BSIM3v32TOTNOIZ], N_MINLOG));

                              *OnDens += noizDens[BSIM3v32TOTNOIZ];

                              if (data->delFreq == 0.0)
                              {   /* if we haven't done any previous
                                     integration, we need to initialize our
                                     "history" variables.
                                    */

                                  for (i = 0; i < BSIM3v32NSRCS; i++)
                                  {    here->BSIM3v32nVar[LNLSTDENS][i] =
                                             lnNdens[i];
                                  }

                                  /* clear out our integration variables
                                     if it's the first pass
                                   */
                                  if (data->freq ==
                                      job->NstartFreq)
                                  {   for (i = 0; i < BSIM3v32NSRCS; i++)
                                      {    here->BSIM3v32nVar[OUTNOIZ][i] = 0.0;
                                           here->BSIM3v32nVar[INNOIZ][i] = 0.0;
                                      }
                                  }
                              }
                              else
                              {   /* data->delFreq != 0.0,
                                     we have to integrate.
                                   */
                                  for (i = 0; i < BSIM3v32NSRCS; i++)
                                  {    if (i != BSIM3v32TOTNOIZ)
                                       {   tempOnoise = Nintegrate(noizDens[i],
                                                lnNdens[i],
                                                here->BSIM3v32nVar[LNLSTDENS][i],
                                                data);
                                           tempInoise = Nintegrate(noizDens[i]
                                                * data->GainSqInv, lnNdens[i]
                                                + data->lnGainInv,
                                                here->BSIM3v32nVar[LNLSTDENS][i]
                                                + data->lnGainInv, data);
                                           here->BSIM3v32nVar[LNLSTDENS][i] =
                                                lnNdens[i];
                                           data->outNoiz += tempOnoise;
                                           data->inNoise += tempInoise;
                                           if (job->NStpsSm != 0)
                                           {   here->BSIM3v32nVar[OUTNOIZ][i]
                                                     += tempOnoise;
                                               here->BSIM3v32nVar[OUTNOIZ][BSIM3v32TOTNOIZ]
                                                     += tempOnoise;
                                               here->BSIM3v32nVar[INNOIZ][i]
                                                     += tempInoise;
                                               here->BSIM3v32nVar[INNOIZ][BSIM3v32TOTNOIZ]
                                                     += tempInoise;
                                           }
                                       }
                                  }
                              }
                              if (data->prtSummary)
                              {   for (i = 0; i < BSIM3v32NSRCS; i++)
                                  {    /* print a summary report */
                                       data->outpVector[data->outNumber++]
                                             = noizDens[i];
                                  }
                              }
                              break;
                         case INT_NOIZ:
                              /* already calculated, just output */
                              if (job->NStpsSm != 0)
                              {   for (i = 0; i < BSIM3v32NSRCS; i++)
                                  {    data->outpVector[data->outNumber++]
                                             = here->BSIM3v32nVar[OUTNOIZ][i];
                                       data->outpVector[data->outNumber++]
                                             = here->BSIM3v32nVar[INNOIZ][i];
                                  }
                              }
                              break;
                      }
                      break;
                 case N_CLOSE:
                      /* do nothing, the main calling routine will close */
                      return (OK);
                      break;   /* the plots */
              }       /* switch (operation) */
         }    /* for here */
    }    /* for model */

    return(OK);
}
Exemplo n.º 5
0
int
BSIM4v7noise (
int mode, int operation,
GENmodel *inModel,
CKTcircuit *ckt,
Ndata *data,
double *OnDens)
{
NOISEAN *job = (NOISEAN *) ckt->CKTcurJob;

BSIM4v7model *model = (BSIM4v7model *)inModel;
BSIM4v7instance *here;
struct bsim4SizeDependParam *pParam;
char name[N_MXVLNTH];
double tempOnoise;
double tempInoise;
double noizDens[BSIM4v7NSRCS];
double lnNdens[BSIM4v7NSRCS];

double T0, T1, T2, T3, T4, T5, T6, T7, T8, T10, T11;
double Vds, Ssi, Swi;
double tmp=0.0, gdpr, gspr, npart_theta=0.0, npart_beta=0.0, igsquare, bodymode;

/* tnoiMod=2 (v4.7) */
double eta, Leff, Lvsat, gamma, delta, epsilon, GammaGd0=0.0;
double npart_c, sigrat=0.0, C0, omega, ctnoi=0.0;

int i;

double m;

    /* define the names of the noise sources */
    static char *BSIM4v7nNames[BSIM4v7NSRCS] =
    {   /* Note that we have to keep the order */
        ".rd",              /* noise due to rd */
        ".rs",              /* noise due to rs */
        ".rg",              /* noise due to rgeltd */
        ".rbps",            /* noise due to rbps */
        ".rbpd",            /* noise due to rbpd */
        ".rbpb",            /* noise due to rbpb */
        ".rbsb",            /* noise due to rbsb */
        ".rbdb",            /* noise due to rbdb */
        ".id",              /* noise due to id (for tnoiMod2: uncorrelated portion only) */
        ".1overf",          /* flicker (1/f) noise */
        ".igs",             /* shot noise due to IGS */
        ".igd",             /* shot noise due to IGD */
        ".igb",             /* shot noise due to IGB */
        ".corl",            /* contribution of correlated drain and induced gate noise */
        ""                  /* total transistor noise */
    };

    for (; model != NULL; model = model->BSIM4v7nextModel)
    {
         if(model->BSIM4v7tnoiMod != 2) {
             noizDens[BSIM4v7CORLNOIZ] = 0.0;
             lnNdens[BSIM4v7CORLNOIZ] = N_MINLOG;
         }
         for (here = model->BSIM4v7instances; here != NULL;
              here = here->BSIM4v7nextInstance)
         {    pParam = here->pParam;
              switch (operation)
              {  case N_OPEN:
                     /* see if we have to to produce a summary report */
                     /* if so, name all the noise generators */

                      if (job->NStpsSm != 0)
                      {   switch (mode)
                          {  case N_DENS:
                                  for (i = 0; i < BSIM4v7NSRCS; i++)
                                  {    (void) sprintf(name, "onoise.%s%s",
                                                      here->BSIM4v7name,
                                                      BSIM4v7nNames[i]);
                                       data->namelist = TREALLOC(IFuid,
                                             data->namelist,
                                             data->numPlots + 1);
                                       if (!data->namelist)
                                           return(E_NOMEM);
                                       SPfrontEnd->IFnewUid (ckt,
                                          &(data->namelist[data->numPlots++]),
                                          NULL, name, UID_OTHER, NULL);
                                       /* we've added one more plot */
                                  }
                                  break;
                             case INT_NOIZ:
                                  for (i = 0; i < BSIM4v7NSRCS; i++)
                                  {    (void) sprintf(name, "onoise_total.%s%s",
                                                      here->BSIM4v7name,
                                                      BSIM4v7nNames[i]);
                                       data->namelist = TREALLOC(IFuid,
                                             data->namelist,
                                             data->numPlots + 1);
                                       if (!data->namelist)
                                           return(E_NOMEM);
                                       SPfrontEnd->IFnewUid (ckt,
                                          &(data->namelist[data->numPlots++]),
                                          NULL, name, UID_OTHER, NULL);
                                       /* we've added one more plot */

                                       (void) sprintf(name, "inoise_total.%s%s",
                                                      here->BSIM4v7name,
                                                      BSIM4v7nNames[i]);
                                       data->namelist = TREALLOC(IFuid,
                                             data->namelist,
                                             data->numPlots + 1);
                                       if (!data->namelist)
                                           return(E_NOMEM);
                                       SPfrontEnd->IFnewUid (ckt,
                                          &(data->namelist[data->numPlots++]),
                                          NULL, name, UID_OTHER, NULL);
                                       /* we've added one more plot */
                                  }
                                  break;
                          }
                      }
                      break;
                 case N_CALC:
                      m = here->BSIM4v7m;
                      switch (mode)
                      {  case N_DENS:
                              if (model->BSIM4v7tnoiMod == 0)
                              {   if (model->BSIM4v7rdsMod == 0)
                                  {   gspr = here->BSIM4v7sourceConductance;
                                      gdpr = here->BSIM4v7drainConductance;
                                      if (here->BSIM4v7grdsw > 0.0)
                                          tmp = 1.0 / here->BSIM4v7grdsw; /* tmp used below */
                                      else
                                          tmp = 0.0;
                                  }
                                  else
                                  {   gspr = here->BSIM4v7gstot;
                                      gdpr = here->BSIM4v7gdtot;
                                      tmp = 0.0;
                                  }
                              }
                              else if(model->BSIM4v7tnoiMod == 1)
                              {   T5 = here->BSIM4v7Vgsteff / here->BSIM4v7EsatL;
                                  T5 *= T5;
                                  npart_beta = model->BSIM4v7rnoia * (1.0 + T5
                                             * model->BSIM4v7tnoia * pParam->BSIM4v7leff);
                                  npart_theta = model->BSIM4v7rnoib * (1.0 + T5
                                              * model->BSIM4v7tnoib * pParam->BSIM4v7leff);
                                  if(npart_theta > 0.9)
                                     npart_theta = 0.9;
                                  if(npart_theta > 0.9 * npart_beta)
                                     npart_theta = 0.9 * npart_beta; //4.6.2

                                  if (model->BSIM4v7rdsMod == 0)
                                  {   gspr = here->BSIM4v7sourceConductance;
                                      gdpr = here->BSIM4v7drainConductance;
                                  }
                                  else
                                  {   gspr = here->BSIM4v7gstot;
                                      gdpr = here->BSIM4v7gdtot;
                                  }

                                  if ((*(ckt->CKTstates[0] + here->BSIM4v7vds)) >= 0.0)
                                      gspr = gspr * (1.0 + npart_theta * npart_theta * gspr
                                           / here->BSIM4v7IdovVds);
                                  else
                                      gdpr = gdpr * (1.0 + npart_theta * npart_theta * gdpr
                                           / here->BSIM4v7IdovVds);
                              }
                              else
                              {   /* tnoiMod=2 (v4.7) */

                                  if (model->BSIM4v7rdsMod == 0)
                                  {   gspr = here->BSIM4v7sourceConductance;
                                      gdpr = here->BSIM4v7drainConductance;
                                  }
                                  else
                                  {   gspr = here->BSIM4v7gstot;
                                      gdpr = here->BSIM4v7gdtot;
                                  }

                              }

                              NevalSrc(&noizDens[BSIM4v7RDNOIZ],
                                       &lnNdens[BSIM4v7RDNOIZ], ckt, THERMNOISE,
                                       here->BSIM4v7dNodePrime, here->BSIM4v7dNode,
                                       gdpr * m);

                              NevalSrc(&noizDens[BSIM4v7RSNOIZ],
                                       &lnNdens[BSIM4v7RSNOIZ], ckt, THERMNOISE,
                                       here->BSIM4v7sNodePrime, here->BSIM4v7sNode,
                                       gspr * m);


                              if (here->BSIM4v7rgateMod == 1)
                              {   NevalSrc(&noizDens[BSIM4v7RGNOIZ],
                                       &lnNdens[BSIM4v7RGNOIZ], ckt, THERMNOISE,
                                       here->BSIM4v7gNodePrime, here->BSIM4v7gNodeExt,
                                       here->BSIM4v7grgeltd * m);
                              }
                              else if (here->BSIM4v7rgateMod == 2)
                              {
                                T0 = 1.0 + here->BSIM4v7grgeltd/here->BSIM4v7gcrg;
                                T1 = T0 * T0;
                                  NevalSrc(&noizDens[BSIM4v7RGNOIZ],
                                       &lnNdens[BSIM4v7RGNOIZ], ckt, THERMNOISE,
                                       here->BSIM4v7gNodePrime, here->BSIM4v7gNodeExt,
                                       here->BSIM4v7grgeltd * m / T1);
                              }
                              else if (here->BSIM4v7rgateMod == 3)
                              {   NevalSrc(&noizDens[BSIM4v7RGNOIZ],
                                       &lnNdens[BSIM4v7RGNOIZ], ckt, THERMNOISE,
                                       here->BSIM4v7gNodeMid, here->BSIM4v7gNodeExt,
                                       here->BSIM4v7grgeltd * m);
                              }
                              else
                              {    noizDens[BSIM4v7RGNOIZ] = 0.0;
                                   lnNdens[BSIM4v7RGNOIZ] =
                                          log(MAX(noizDens[BSIM4v7RGNOIZ], N_MINLOG));
                              }

                                    bodymode = 5;
                                    if (here->BSIM4v7rbodyMod == 2)
                                    {        if( ( !model->BSIM4v7rbps0Given) ||
                                      ( !model->BSIM4v7rbpd0Given) )
                                             bodymode = 1;
                                           else
                                     if( (!model->BSIM4v7rbsbx0Given && !model->BSIM4v7rbsby0Given) ||
                                          (!model->BSIM4v7rbdbx0Given && !model->BSIM4v7rbdby0Given) )
                                             bodymode = 3;
                                }

                              if (here->BSIM4v7rbodyMod)
                              {
                                if(bodymode == 5)
                                  {
                                    NevalSrc(&noizDens[BSIM4v7RBPSNOIZ],
                                             &lnNdens[BSIM4v7RBPSNOIZ], ckt, THERMNOISE,
                                             here->BSIM4v7bNodePrime, here->BSIM4v7sbNode,
                                             here->BSIM4v7grbps * m);
                                    NevalSrc(&noizDens[BSIM4v7RBPDNOIZ],
                                             &lnNdens[BSIM4v7RBPDNOIZ], ckt, THERMNOISE,
                                             here->BSIM4v7bNodePrime, here->BSIM4v7dbNode,
                                             here->BSIM4v7grbpd * m);
                                    NevalSrc(&noizDens[BSIM4v7RBPBNOIZ],
                                             &lnNdens[BSIM4v7RBPBNOIZ], ckt, THERMNOISE,
                                             here->BSIM4v7bNodePrime, here->BSIM4v7bNode,
                                             here->BSIM4v7grbpb * m);
                                    NevalSrc(&noizDens[BSIM4v7RBSBNOIZ],
                                             &lnNdens[BSIM4v7RBSBNOIZ], ckt, THERMNOISE,
                                             here->BSIM4v7bNode, here->BSIM4v7sbNode,
                                             here->BSIM4v7grbsb * m);
                                    NevalSrc(&noizDens[BSIM4v7RBDBNOIZ],
                                             &lnNdens[BSIM4v7RBDBNOIZ], ckt, THERMNOISE,
                                             here->BSIM4v7bNode, here->BSIM4v7dbNode,
                                             here->BSIM4v7grbdb * m);
                                  }
                                if(bodymode == 3)
                                  {
                                    NevalSrc(&noizDens[BSIM4v7RBPSNOIZ],
                                             &lnNdens[BSIM4v7RBPSNOIZ], ckt, THERMNOISE,
                                             here->BSIM4v7bNodePrime, here->BSIM4v7sbNode,
                                             here->BSIM4v7grbps * m);
                                    NevalSrc(&noizDens[BSIM4v7RBPDNOIZ],
                                             &lnNdens[BSIM4v7RBPDNOIZ], ckt, THERMNOISE,
                                             here->BSIM4v7bNodePrime, here->BSIM4v7dbNode,
                                             here->BSIM4v7grbpd * m);
                                    NevalSrc(&noizDens[BSIM4v7RBPBNOIZ],
                                             &lnNdens[BSIM4v7RBPBNOIZ], ckt, THERMNOISE,
                                             here->BSIM4v7bNodePrime, here->BSIM4v7bNode,
                                             here->BSIM4v7grbpb * m);
                                     noizDens[BSIM4v7RBSBNOIZ] = noizDens[BSIM4v7RBDBNOIZ] = 0.0;
                                     lnNdens[BSIM4v7RBSBNOIZ] =
                                       log(MAX(noizDens[BSIM4v7RBSBNOIZ], N_MINLOG));
                                     lnNdens[BSIM4v7RBDBNOIZ] =
                                       log(MAX(noizDens[BSIM4v7RBDBNOIZ], N_MINLOG));
                                  }
                                if(bodymode == 1)
                                  {
                                    NevalSrc(&noizDens[BSIM4v7RBPBNOIZ],
                                             &lnNdens[BSIM4v7RBPBNOIZ], ckt, THERMNOISE,
                                             here->BSIM4v7bNodePrime, here->BSIM4v7bNode,
                                             here->BSIM4v7grbpb * m);
                                    noizDens[BSIM4v7RBPSNOIZ] = noizDens[BSIM4v7RBPDNOIZ] = 0.0;
                                    noizDens[BSIM4v7RBSBNOIZ] = noizDens[BSIM4v7RBDBNOIZ] = 0.0;
                                    lnNdens[BSIM4v7RBPSNOIZ] =
                                      log(MAX(noizDens[BSIM4v7RBPSNOIZ], N_MINLOG));
                                    lnNdens[BSIM4v7RBPDNOIZ] =
                                      log(MAX(noizDens[BSIM4v7RBPDNOIZ], N_MINLOG));
                                    lnNdens[BSIM4v7RBSBNOIZ] =
                                      log(MAX(noizDens[BSIM4v7RBSBNOIZ], N_MINLOG));
                                    lnNdens[BSIM4v7RBDBNOIZ] =
                                      log(MAX(noizDens[BSIM4v7RBDBNOIZ], N_MINLOG));
                                  }
                              }
                              else
                              {   noizDens[BSIM4v7RBPSNOIZ] = noizDens[BSIM4v7RBPDNOIZ] = 0.0;
                                  noizDens[BSIM4v7RBPBNOIZ] = 0.0;
                                  noizDens[BSIM4v7RBSBNOIZ] = noizDens[BSIM4v7RBDBNOIZ] = 0.0;
                                  lnNdens[BSIM4v7RBPSNOIZ] =
                                          log(MAX(noizDens[BSIM4v7RBPSNOIZ], N_MINLOG));
                                  lnNdens[BSIM4v7RBPDNOIZ] =
                                          log(MAX(noizDens[BSIM4v7RBPDNOIZ], N_MINLOG));
                                  lnNdens[BSIM4v7RBPBNOIZ] =
                                          log(MAX(noizDens[BSIM4v7RBPBNOIZ], N_MINLOG));
                                  lnNdens[BSIM4v7RBSBNOIZ] =
                                          log(MAX(noizDens[BSIM4v7RBSBNOIZ], N_MINLOG));
                                  lnNdens[BSIM4v7RBDBNOIZ] =
                                          log(MAX(noizDens[BSIM4v7RBDBNOIZ], N_MINLOG));
                              }

                              if(model->BSIM4v7tnoiMod == 2)
                              {
                                  eta = 1.0 - here->BSIM4v7Vdseff * here->BSIM4v7AbovVgst2Vtm;
                                  T0 = 1.0 - eta;
                                  T1 = 1.0 + eta;
                                  T2 = T1 + 2.0 * here->BSIM4v7Abulk * model->BSIM4v7vtm / here->BSIM4v7Vgsteff;
                                  Leff = pParam->BSIM4v7leff;
                                  Lvsat = Leff * (1.0 + here->BSIM4v7Vdseff / here->BSIM4v7EsatL);
                                  T6 = Leff / Lvsat;

                                  T5 = here->BSIM4v7Vgsteff / here->BSIM4v7EsatL;
                                  T5 = T5 * T5;
                                  gamma = T6 * (0.5 * T1 + T0 * T0 / (6.0 * T2));
                                  T3 = T2 * T2;
                                  T4 = T0 * T0;
                                  T5 = T3 * T3;
                                  delta = (T1 / T3 - (5.0 * T1 + T2) * T4 / (15.0 * T5) + T4 * T4 / (9.0 * T5 * T2)) / (6.0 * T6 * T6 * T6);
                                  T7 = T0 / T2;
                                  epsilon = (T7 - T7 * T7 * T7 / 3.0) / (6.0 * T6);

                                  T8 = here->BSIM4v7Vgsteff / here->BSIM4v7EsatL;
                                  T8 *= T8;
                                  npart_c = model->BSIM4v7rnoic * (1.0 + T8
                                          * model->BSIM4v7tnoic * Leff);
                                  ctnoi = epsilon / sqrt(gamma * delta)
                                      * (2.5316 * npart_c);

                                  npart_beta = model->BSIM4v7rnoia * (1.0 + T8
                                      * model->BSIM4v7tnoia * Leff);
                                  npart_theta = model->BSIM4v7rnoib * (1.0 + T8
                                      * model->BSIM4v7tnoib * Leff);
                                  gamma = gamma * (3.0 * npart_beta * npart_beta);
                                  delta = delta * (3.75 * npart_theta * npart_theta);

                                  GammaGd0 = gamma * here->BSIM4v7noiGd0;
                                  C0 = here->BSIM4v7Coxeff * pParam->BSIM4v7weffCV * here->BSIM4v7nf * pParam->BSIM4v7leffCV;
                                  T0 = C0 / here->BSIM4v7noiGd0;
                                  sigrat = T0 * sqrt(delta / gamma);
                              }
                              switch(model->BSIM4v7tnoiMod)
                              {  case 0:
                                      T0 = here->BSIM4v7ueff * fabs(here->BSIM4v7qinv);
                                      T1 = T0 * tmp + pParam->BSIM4v7leff
                                         * pParam->BSIM4v7leff;
                                      NevalSrc(&noizDens[BSIM4v7IDNOIZ],
                                               &lnNdens[BSIM4v7IDNOIZ], ckt,
                                               THERMNOISE, here->BSIM4v7dNodePrime,
                                               here->BSIM4v7sNodePrime,
                                               (T0 / T1) * model->BSIM4v7ntnoi * m);
                                      break;
                                 case 1:
                                      T0 = here->BSIM4v7gm + here->BSIM4v7gmbs + here->BSIM4v7gds;
                                      T0 *= T0;
                                      igsquare = npart_theta * npart_theta * T0 / here->BSIM4v7IdovVds;
                                      T1 = npart_beta * (here->BSIM4v7gm
                                         + here->BSIM4v7gmbs) + here->BSIM4v7gds;
                                      T2 = T1 * T1 / here->BSIM4v7IdovVds;
                                      NevalSrc(&noizDens[BSIM4v7IDNOIZ],
                                               &lnNdens[BSIM4v7IDNOIZ], ckt,
                                               THERMNOISE, here->BSIM4v7dNodePrime,
                                               here->BSIM4v7sNodePrime, (T2 - igsquare) * m);
                                      break;
                                  case 2:
                                      T2 = GammaGd0;
                                      T3 = ctnoi * ctnoi;
                                      T4 = 1.0 - T3;
                                      NevalSrc(&noizDens[BSIM4v7IDNOIZ],
                                               &lnNdens[BSIM4v7IDNOIZ], ckt,
                                               THERMNOISE, here->BSIM4v7dNodePrime,
                                               here->BSIM4v7sNodePrime, T2 * T4 * m);

                                     /* Evaluate output noise due to two correlated noise sources */
                                     omega = 2.0 * M_PI * data->freq;
                                     T5 = omega * sigrat;
                                     T6 = T5 * T5;
                                     T7 = T6 / (1.0 + T6);

                                     if (here->BSIM4v7mode >= 0)  {
                                         NevalSrc2(&noizDens[BSIM4v7CORLNOIZ],
                                               &lnNdens[BSIM4v7CORLNOIZ], ckt,
                                               THERMNOISE, here->BSIM4v7dNodePrime,
                                               here->BSIM4v7sNodePrime, T2 * T3 * m,
                                               here->BSIM4v7gNodePrime,
                                               here->BSIM4v7sNodePrime,
                                               T2 * T7 * m, 0.5 * M_PI);
                                     }
                                     else
                                     {
                                         NevalSrc2(&noizDens[BSIM4v7CORLNOIZ],
                                               &lnNdens[BSIM4v7CORLNOIZ], ckt,
                                               THERMNOISE, here->BSIM4v7sNodePrime,
                                               here->BSIM4v7dNodePrime, T2 * T3 * m,
                                               here->BSIM4v7gNodePrime,
                                               here->BSIM4v7dNodePrime,
                                               T2 * T7 * m, 0.5 * M_PI);
                                     }
                                     break;
                              }

                              NevalSrc(&noizDens[BSIM4v7FLNOIZ], (double*) NULL,
                                       ckt, N_GAIN, here->BSIM4v7dNodePrime,
                                       here->BSIM4v7sNodePrime, (double) 0.0);

                              switch(model->BSIM4v7fnoiMod)
                              {  case 0:
                                      noizDens[BSIM4v7FLNOIZ] *= m * model->BSIM4v7kf
                                            * exp(model->BSIM4v7af
                                            * log(MAX(fabs(here->BSIM4v7cd),
                                            N_MINLOG)))
                                            / (pow(data->freq, model->BSIM4v7ef)
                                            * pParam->BSIM4v7leff
                                            * pParam->BSIM4v7leff
                                            * model->BSIM4v7coxe);
                                      break;
                                 case 1:
                                      Vds = *(ckt->CKTstates[0] + here->BSIM4v7vds);
                                      if (Vds < 0.0)
                                          Vds = -Vds;

                                      Ssi = Eval1ovFNoise(Vds, model, here,
                                          data->freq, ckt->CKTtemp);
                                      T10 = model->BSIM4v7oxideTrapDensityA
                                          * CONSTboltz * ckt->CKTtemp;
                                      T11 = pParam->BSIM4v7weff * here->BSIM4v7nf * pParam->BSIM4v7leff
                                          * pow(data->freq, model->BSIM4v7ef) * 1.0e10
                                          * here->BSIM4v7nstar * here->BSIM4v7nstar;
                                      Swi = T10 / T11 * here->BSIM4v7cd
                                          * here->BSIM4v7cd;
                                      T1 = Swi + Ssi;
                                      if (T1 > 0.0)
                                          noizDens[BSIM4v7FLNOIZ] *= m * (Ssi * Swi) / T1;
                                      else
                                          noizDens[BSIM4v7FLNOIZ] *= 0.0;
                                      break;
                              }

                              lnNdens[BSIM4v7FLNOIZ] =
                                     log(MAX(noizDens[BSIM4v7FLNOIZ], N_MINLOG));


                        if(here->BSIM4v7mode >= 0) {  /* bugfix  */
                              NevalSrc(&noizDens[BSIM4v7IGSNOIZ],
                                   &lnNdens[BSIM4v7IGSNOIZ], ckt, SHOTNOISE,
                                   here->BSIM4v7gNodePrime, here->BSIM4v7sNodePrime,
                                   m * (here->BSIM4v7Igs + here->BSIM4v7Igcs));
                              NevalSrc(&noizDens[BSIM4v7IGDNOIZ],
                                   &lnNdens[BSIM4v7IGDNOIZ], ckt, SHOTNOISE,
                                   here->BSIM4v7gNodePrime, here->BSIM4v7dNodePrime,
                                   m * (here->BSIM4v7Igd + here->BSIM4v7Igcd));
                        } else {
                              NevalSrc(&noizDens[BSIM4v7IGSNOIZ],
                                   &lnNdens[BSIM4v7IGSNOIZ], ckt, SHOTNOISE,
                                   here->BSIM4v7gNodePrime, here->BSIM4v7sNodePrime,
                                   m * (here->BSIM4v7Igs + here->BSIM4v7Igcd));
                              NevalSrc(&noizDens[BSIM4v7IGDNOIZ],
                                   &lnNdens[BSIM4v7IGDNOIZ], ckt, SHOTNOISE,
                                   here->BSIM4v7gNodePrime, here->BSIM4v7dNodePrime,
                                   m * (here->BSIM4v7Igd + here->BSIM4v7Igcs));
                        }
                              NevalSrc(&noizDens[BSIM4v7IGBNOIZ],
                                   &lnNdens[BSIM4v7IGBNOIZ], ckt, SHOTNOISE,
                                   here->BSIM4v7gNodePrime, here->BSIM4v7bNodePrime,
                                   m * here->BSIM4v7Igb);


                              noizDens[BSIM4v7TOTNOIZ] = noizDens[BSIM4v7RDNOIZ]
                                     + noizDens[BSIM4v7RSNOIZ] + noizDens[BSIM4v7RGNOIZ]
                                     + noizDens[BSIM4v7RBPSNOIZ] + noizDens[BSIM4v7RBPDNOIZ]
                                     + noizDens[BSIM4v7RBPBNOIZ]
                                     + noizDens[BSIM4v7RBSBNOIZ] + noizDens[BSIM4v7RBDBNOIZ]
                                     + noizDens[BSIM4v7IDNOIZ] + noizDens[BSIM4v7FLNOIZ]
                                     + noizDens[BSIM4v7IGSNOIZ] + noizDens[BSIM4v7IGDNOIZ]
                                     + noizDens[BSIM4v7IGBNOIZ] + noizDens[BSIM4v7CORLNOIZ];
                              lnNdens[BSIM4v7TOTNOIZ] =
                                     log(MAX(noizDens[BSIM4v7TOTNOIZ], N_MINLOG));

                              *OnDens += noizDens[BSIM4v7TOTNOIZ];

                              if (data->delFreq == 0.0)
                              {   /* if we haven't done any previous
                                     integration, we need to initialize our
                                     "history" variables.
                                    */

                                  for (i = 0; i < BSIM4v7NSRCS; i++)
                                  {    here->BSIM4v7nVar[LNLSTDENS][i] =
                                             lnNdens[i];
                                  }

                                  /* clear out our integration variables
                                     if it's the first pass
                                   */
                                  if (data->freq ==
                                      job->NstartFreq)
                                  {   for (i = 0; i < BSIM4v7NSRCS; i++)
                                      {    here->BSIM4v7nVar[OUTNOIZ][i] = 0.0;
                                           here->BSIM4v7nVar[INNOIZ][i] = 0.0;
                                      }
                                  }
                              }
                              else
                              {   /* data->delFreq != 0.0,
                                     we have to integrate.
                                   */
                                  for (i = 0; i < BSIM4v7NSRCS; i++)
                                  {    if (i != BSIM4v7TOTNOIZ)
                                       {   tempOnoise = Nintegrate(noizDens[i],
                                                lnNdens[i],
                                                here->BSIM4v7nVar[LNLSTDENS][i],
                                                data);
                                           tempInoise = Nintegrate(noizDens[i]
                                                * data->GainSqInv, lnNdens[i]
                                                + data->lnGainInv,
                                                here->BSIM4v7nVar[LNLSTDENS][i]
                                                + data->lnGainInv, data);
                                           here->BSIM4v7nVar[LNLSTDENS][i] =
                                                lnNdens[i];
                                           data->outNoiz += tempOnoise;
                                           data->inNoise += tempInoise;
                                           if (job->NStpsSm != 0)
                                           {   here->BSIM4v7nVar[OUTNOIZ][i]
                                                     += tempOnoise;
                                               here->BSIM4v7nVar[OUTNOIZ][BSIM4v7TOTNOIZ]
                                                     += tempOnoise;
                                               here->BSIM4v7nVar[INNOIZ][i]
                                                     += tempInoise;
                                               here->BSIM4v7nVar[INNOIZ][BSIM4v7TOTNOIZ]
                                                     += tempInoise;
                                           }
                                       }
                                  }
                              }
                              if (data->prtSummary)
                              {   for (i = 0; i < BSIM4v7NSRCS; i++)
                                  {    /* print a summary report */
                                       data->outpVector[data->outNumber++]
                                             = noizDens[i];
                                  }
                              }
                              break;
                         case INT_NOIZ:
                              /* already calculated, just output */
                              if (job->NStpsSm != 0)
                              {   for (i = 0; i < BSIM4v7NSRCS; i++)
                                  {    data->outpVector[data->outNumber++]
                                             = here->BSIM4v7nVar[OUTNOIZ][i];
                                       data->outpVector[data->outNumber++]
                                             = here->BSIM4v7nVar[INNOIZ][i];
                                  }
                              }
                              break;
                      }
                      break;
                 case N_CLOSE:
                      /* do nothing, the main calling routine will close */
                      return (OK);
                      break;   /* the plots */
              }       /* switch (operation) */
         }    /* for here */
    }    /* for model */

    return(OK);
}
Exemplo n.º 6
0
int HSMHV2noise (
     int mode, int operation,
     GENmodel *inModel,
     CKTcircuit *ckt,
     Ndata *data,
     double *OnDens)
{
  HSMHV2model *model = (HSMHV2model *)inModel;
  HSMHV2instance *here;
  char name[N_MXVLNTH];
  double tempOnoise=0.0 ;
  double tempInoise=0.0 ;
  double noizDens[HSMHV2NSRCS] ;
  double lnNdens[HSMHV2NSRCS] ;
  int i;
  double G =0.0 ;
  double TTEMP = 0.0 ;

  /* define the names of the noise sources */
  static char * HSMHV2nNames[HSMHV2NSRCS] = {
    /* Note that we have to keep the order
       consistent with the index definitions 
       in hsmhvdefs.h */
    ".rd",              /* noise due to rd */
    ".rs",              /* noise due to rs */
    ".id",              /* noise due to id */
    ".1ovf",            /* flicker (1/f) noise */
    ".ign",             /* induced gate noise component at the drain node */
    ""                  /* total transistor noise */
  };
  
  for ( ;model != NULL; model = model->HSMHV2nextModel ) {
    for ( here = model->HSMHV2instances; here != NULL;
	  here = here->HSMHV2nextInstance ) {
      switch (operation) {
      case N_OPEN:
	/* see if we have to to produce a summary report */
	/* if so, name all the noise generators */
	  
	if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) {
	  switch (mode) {
	  case N_DENS:
	    for ( i = 0; i < HSMHV2NSRCS; i++ ) { 
	      (void) sprintf(name, "onoise.%s%s", 
			     (char *)here->HSMHV2name, HSMHV2nNames[i]);
	      data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
	      if (!data->namelist)
		return(E_NOMEM);
	      SPfrontEnd->IFnewUid
		(ckt, &(data->namelist[data->numPlots++]),
		 NULL, name, UID_OTHER, NULL);
	    }
	    break;
	  case INT_NOIZ:
	    for ( i = 0; i < HSMHV2NSRCS; i++ ) {
	      (void) sprintf(name, "onoise_total.%s%s", 
			     (char *)here->HSMHV2name, HSMHV2nNames[i]);
	      data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
	      if (!data->namelist)
		return(E_NOMEM);
	      SPfrontEnd->IFnewUid
		(ckt, &(data->namelist[data->numPlots++]),
		 NULL, name, UID_OTHER, NULL);
	      
	      (void) sprintf(name, "inoise_total.%s%s", 
			     (char *)here->HSMHV2name, HSMHV2nNames[i]);
	      data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
	      if (!data->namelist)
		return(E_NOMEM);
	      SPfrontEnd->IFnewUid
		(ckt, &(data->namelist[data->numPlots++]),
		 NULL, name, UID_OTHER, NULL);
	    }
	    break;
	  }
	}
	break;
      case N_CALC:
	switch (mode) {
	case N_DENS:

         /* temperature */
         TTEMP = ckt->CKTtemp;
         if ( here->HSMHV2_dtemp_Given ) { TTEMP = TTEMP + here->HSMHV2_dtemp ; }
         TTEMP = TTEMP + *(ckt->CKTstate0 + here->HSMHV2deltemp) ;

         /* rs/rd thermal noise */
	  if ( model->HSMHV2_corsrd == 1 || model->HSMHV2_corsrd == 3 ||  model->HSMHV2_cordrift == 1 ) {
	    NevalSrc(&noizDens[HSMHV2RDNOIZ], NULL,
		     ckt, N_GAIN,
		     here->HSMHV2dNodePrime, here->HSMHV2dNode,
		     0.0);
	    noizDens[HSMHV2RDNOIZ] *= 4 * C_KB * TTEMP * here->HSMHV2drainConductance ;
            lnNdens[HSMHV2RDNOIZ] = log( MAX(noizDens[HSMHV2RDNOIZ],N_MINLOG) );
	    
	    NevalSrc(&noizDens[HSMHV2RSNOIZ], NULL,
		     ckt, N_GAIN,
		     here->HSMHV2sNodePrime, here->HSMHV2sNode,
		     0.0);
	    noizDens[HSMHV2RSNOIZ] *= 4 * C_KB * TTEMP * here->HSMHV2sourceConductance ;
            lnNdens[HSMHV2RSNOIZ] = log( MAX(noizDens[HSMHV2RSNOIZ],N_MINLOG) );
	  } else {
	    noizDens[HSMHV2RDNOIZ] = 0e0 ;
	    lnNdens[HSMHV2RDNOIZ] = N_MINLOG ;
	    noizDens[HSMHV2RSNOIZ] = 0e0 ;
	    lnNdens[HSMHV2RSNOIZ] = N_MINLOG ;
	  }

	  /* channel thermal noise */
	  NevalSrc(&noizDens[HSMHV2IDNOIZ], NULL,
		   ckt, N_GAIN,
		   here->HSMHV2dNodePrime, here->HSMHV2sNodePrime,
		   0.0);
	  switch( model->HSMHV2_noise ) {
	  case 1:
	    /* HiSIMHV model */
	    G = here->HSMHV2_noithrml ;
	    noizDens[HSMHV2IDNOIZ] *= 4 * C_KB * TTEMP * G ;
	    lnNdens[HSMHV2IDNOIZ] = log( MAX(noizDens[HSMHV2IDNOIZ],N_MINLOG) );
	    break;
	  }

	  /* flicker noise */
	  NevalSrc(&noizDens[HSMHV2FLNOIZ], NULL,
		   ckt, N_GAIN,
		   here->HSMHV2dNodePrime, here->HSMHV2sNodePrime, 
		   0.0);
	  switch ( model->HSMHV2_noise ) {
	  case 1:
	    /* HiSIM model */
	    noizDens[HSMHV2FLNOIZ] *= here->HSMHV2_noiflick / pow(data->freq, model->HSMHV2_falph) ; 
	    lnNdens[HSMHV2FLNOIZ] = log(MAX(noizDens[HSMHV2FLNOIZ], N_MINLOG));
	    break;
	  }	  

	  /* induced gate noise */
	  NevalSrc(&noizDens[HSMHV2IGNOIZ], NULL,
		   ckt, N_GAIN, 
		   here->HSMHV2dNodePrime, here->HSMHV2sNodePrime, 
		   0.0);
	  switch ( model->HSMHV2_noise ) {
	  case 1:
	    /* HiSIM model */
	    noizDens[HSMHV2IGNOIZ] *= here->HSMHV2_noiigate * here->HSMHV2_noicross * here->HSMHV2_noicross * data->freq * data->freq;
	    lnNdens[HSMHV2IGNOIZ] = log(MAX(noizDens[HSMHV2IGNOIZ], N_MINLOG));
	    break;
	  }

	  /* total */
	  noizDens[HSMHV2TOTNOIZ] = noizDens[HSMHV2RDNOIZ] + noizDens[HSMHV2RSNOIZ]
	    + noizDens[HSMHV2IDNOIZ] + noizDens[HSMHV2FLNOIZ] + noizDens[HSMHV2IGNOIZ];
	  lnNdens[HSMHV2TOTNOIZ] = log(MAX(noizDens[HSMHV2TOTNOIZ], N_MINLOG));
	  
	  *OnDens += noizDens[HSMHV2TOTNOIZ];
	  
	  if ( data->delFreq == 0.0 ) {
	    /* if we haven't done any previous 
	       integration, we need to initialize our
	       "history" variables.
	    */
	    
	    for ( i = 0; i < HSMHV2NSRCS; i++ ) 
	      here->HSMHV2nVar[LNLSTDENS][i] = lnNdens[i];
	    
	    /* clear out our integration variables
	       if it's the first pass
	    */
	    if (data->freq == ((NOISEAN*) ckt->CKTcurJob)->NstartFreq) {
	      for (i = 0; i < HSMHV2NSRCS; i++) {
		here->HSMHV2nVar[OUTNOIZ][i] = 0.0;
		here->HSMHV2nVar[INNOIZ][i] = 0.0;
	      }
	    }
	  }
	  else {
	    /* data->delFreq != 0.0,
	       we have to integrate.
	    */
	    for ( i = 0; i < HSMHV2NSRCS; i++ ) {
	      if ( i != HSMHV2TOTNOIZ ) {
		tempOnoise = 
		  Nintegrate(noizDens[i], lnNdens[i],
			     here->HSMHV2nVar[LNLSTDENS][i], data);
		tempInoise = 
		  Nintegrate(noizDens[i] * data->GainSqInv, 
			     lnNdens[i] + data->lnGainInv,
			     here->HSMHV2nVar[LNLSTDENS][i] + data->lnGainInv,
			     data);
		here->HSMHV2nVar[LNLSTDENS][i] = lnNdens[i];
		data->outNoiz += tempOnoise;
		data->inNoise += tempInoise;
		if ( ((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0 ) {
		  here->HSMHV2nVar[OUTNOIZ][i] += tempOnoise;
		  here->HSMHV2nVar[OUTNOIZ][HSMHV2TOTNOIZ] += tempOnoise;
		  here->HSMHV2nVar[INNOIZ][i] += tempInoise;
		  here->HSMHV2nVar[INNOIZ][HSMHV2TOTNOIZ] += tempInoise;
		}
	      }
	    }
	  }
	  if ( data->prtSummary ) {
	    for (i = 0; i < HSMHV2NSRCS; i++) {
	      /* print a summary report */
	      data->outpVector[data->outNumber++] = noizDens[i];
	    }
	  }
	  break;
	case INT_NOIZ:
	  /* already calculated, just output */
	  if ( ((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0 ) {
	    for ( i = 0; i < HSMHV2NSRCS; i++ ) {
	      data->outpVector[data->outNumber++] = here->HSMHV2nVar[OUTNOIZ][i];
	      data->outpVector[data->outNumber++] = here->HSMHV2nVar[INNOIZ][i];
	    }
	  }
	  break;
	}
	break;
      case N_CLOSE:
	/* do nothing, the main calling routine will close */
	return (OK);
	break;   /* the plots */
      }       /* switch (operation) */
    }    /* for here */
  }    /* for model */
  
  return(OK);
}
Exemplo n.º 7
0
int
VBICnoise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, Ndata *data, double *OnDens)
{
    NOISEAN *job = (NOISEAN *) ckt->CKTcurJob;

    VBICmodel *firstModel = (VBICmodel *) genmodel;
    VBICmodel *model;
    VBICinstance *inst;
    char name[N_MXVLNTH];
    double tempOnoise;
    double tempInoise;
    double noizDens[VBICNSRCS];
    double lnNdens[VBICNSRCS];
    int i;

    /* define the names of the noise sources */

    static char *VBICnNames[VBICNSRCS] = {
        /* Note that we have to keep the order consistent with the
          strchr definitions in VBICdefs.h */
        "_rc",              /* noise due to rc */
        "_rci",             /* noise due to rci */
        "_rb",              /* noise due to rb */
        "_rbi",             /* noise due to rbi */
        "_re",              /* noise due to re */
        "_rbp",             /* noise due to rbp */
        "_rs",              /* noise due to rs */
        "_ic",              /* noise due to ic */
        "_ib",              /* noise due to ib */
        "_ibep",            /* noise due to ibep */
        "_iccp",            /* noise due to iccp */
        "_1overfbe",        /* flicker (1/f) noise ibe */
        "_1overfbep",       /* flicker (1/f) noise ibep */
        ""                  /* total transistor noise */
    };

    for (model=firstModel; model != NULL; model=model->VBICnextModel) {
        for (inst=model->VBICinstances; inst != NULL;
                inst=inst->VBICnextInstance) {

            switch (operation) {

            case N_OPEN:

                /* see if we have to to produce a summary report */
                /* if so, name all the noise generators */

                if (job->NStpsSm != 0) {
                    switch (mode) {

                    case N_DENS:
                        for (i=0; i < VBICNSRCS; i++) {
                            (void)sprintf(name,"onoise_%s%s",
                                inst->VBICname,VBICnNames[i]);


                        data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
                        if (!data->namelist) return(E_NOMEM);
                        SPfrontEnd->IFnewUid (ckt,
                            &(data->namelist[data->numPlots++]),
                            NULL, name, UID_OTHER, NULL);
                                /* we've added one more plot */
                        }
                        break;

                    case INT_NOIZ:
                        for (i=0; i < VBICNSRCS; i++) {
                            (void)sprintf(name,"onoise_total_%s%s",
                                inst->VBICname,VBICnNames[i]);

                        data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
                        if (!data->namelist) return(E_NOMEM);
                        SPfrontEnd->IFnewUid (ckt,
                            &(data->namelist[data->numPlots++]),
                            NULL, name, UID_OTHER, NULL);
                                /* we've added one more plot */

                            (void)sprintf(name,"inoise_total_%s%s",
                                inst->VBICname,VBICnNames[i]);

data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
if (!data->namelist) return(E_NOMEM);
                SPfrontEnd->IFnewUid (ckt,
                        &(data->namelist[data->numPlots++]),
                        NULL, name, UID_OTHER, NULL);
                                /* we've added one more plot */
                        }
                        break;
                    }
                }
                break;

            case N_CALC:
                switch (mode) {

                case N_DENS:
                    NevalSrc(&noizDens[VBICRCNOIZ],&lnNdens[VBICRCNOIZ],
                                 ckt,THERMNOISE,inst->VBICcollCXNode,inst->VBICcollNode,
                                 *(ckt->CKTstate0 + inst->VBICircx_Vrcx));

                    NevalSrc(&noizDens[VBICRCINOIZ],&lnNdens[VBICRCINOIZ],
                                 ckt,THERMNOISE,inst->VBICcollCXNode,inst->VBICcollCINode,
                                 *(ckt->CKTstate0 + inst->VBICirci_Vrci));

                    NevalSrc(&noizDens[VBICRBNOIZ],&lnNdens[VBICRBNOIZ],
                                 ckt,THERMNOISE,inst->VBICbaseBXNode,inst->VBICbaseNode,
                                 *(ckt->CKTstate0 + inst->VBICirbx_Vrbx));

                    NevalSrc(&noizDens[VBICRBINOIZ],&lnNdens[VBICRBINOIZ],
                                 ckt,THERMNOISE,inst->VBICbaseBXNode,inst->VBICbaseBINode,
                                 *(ckt->CKTstate0 + inst->VBICirbi_Vrbi));

                    NevalSrc(&noizDens[VBICRENOIZ],&lnNdens[VBICRENOIZ],
                                 ckt,THERMNOISE,inst->VBICemitEINode,inst->VBICemitNode,
                                 *(ckt->CKTstate0 + inst->VBICire_Vre));

                    NevalSrc(&noizDens[VBICRBPNOIZ],&lnNdens[VBICRBPNOIZ],
                                 ckt,THERMNOISE,inst->VBICemitEINode,inst->VBICemitNode,
                                 *(ckt->CKTstate0 + inst->VBICirbp_Vrbp));

                    NevalSrc(&noizDens[VBICRSNOIZ],&lnNdens[VBICRSNOIZ],
                                 ckt,THERMNOISE,inst->VBICsubsSINode,inst->VBICsubsNode,
                                 *(ckt->CKTstate0 + inst->VBICirs_Vrs));


                    NevalSrc(&noizDens[VBICICNOIZ],&lnNdens[VBICICNOIZ],
                                 ckt,SHOTNOISE,inst->VBICcollCINode, inst->VBICemitEINode,
                                 *(ckt->CKTstate0 + inst->VBICitzf));

                    NevalSrc(&noizDens[VBICIBNOIZ],&lnNdens[VBICIBNOIZ],
                                 ckt,SHOTNOISE,inst->VBICbaseBINode, inst->VBICemitEINode,
                                 *(ckt->CKTstate0 + inst->VBICibe));

                    NevalSrc(&noizDens[VBICIBEPNOIZ],&lnNdens[VBICIBEPNOIZ],
                                 ckt,SHOTNOISE,inst->VBICbaseBXNode, inst->VBICbaseBPNode,
                                 *(ckt->CKTstate0 + inst->VBICibep));

                    NevalSrc(&noizDens[VBICICCPNOIZ],&lnNdens[VBICICCPNOIZ],
                                 ckt,SHOTNOISE,inst->VBICbaseBXNode, inst->VBICsubsSINode,
                                 *(ckt->CKTstate0 + inst->VBICiccp));


                    NevalSrc(&noizDens[VBICFLBENOIZ], NULL, ckt,
                                 N_GAIN,inst->VBICbaseBINode, inst->VBICemitEINode,
                                 (double)0.0);
                    noizDens[VBICFLBENOIZ] *= inst->VBICm * model->VBICfNcoef * 
                                 exp(model->VBICfNexpA *
                                 log(MAX(fabs(*(ckt->CKTstate0 + inst->VBICibe)/inst->VBICm),N_MINLOG))) /
                                 pow(data->freq, model->VBICfNexpB);
                    lnNdens[VBICFLBENOIZ] = 
                                 log(MAX(noizDens[VBICFLBENOIZ],N_MINLOG));

                    NevalSrc(&noizDens[VBICFLBEPNOIZ], NULL, ckt,
                                 N_GAIN,inst->VBICbaseBXNode, inst->VBICbaseBPNode,
                                 (double)0.0);
                    noizDens[VBICFLBEPNOIZ] *= inst->VBICm * model->VBICfNcoef * 
                                 exp(model->VBICfNexpA *
                                 log(MAX(fabs(*(ckt->CKTstate0 + inst->VBICibep)/inst->VBICm),N_MINLOG))) /
                                 pow(data->freq, model->VBICfNexpB);
                    lnNdens[VBICFLBEPNOIZ] = 
                                 log(MAX(noizDens[VBICFLBEPNOIZ],N_MINLOG));


                    noizDens[VBICTOTNOIZ] = noizDens[VBICRCNOIZ] +
                                            noizDens[VBICRCINOIZ] +
                                            noizDens[VBICRBNOIZ] +
                                            noizDens[VBICRBINOIZ] +
                                            noizDens[VBICRENOIZ] +
                                            noizDens[VBICRBPNOIZ] +
                                            noizDens[VBICICNOIZ] +
                                            noizDens[VBICIBNOIZ] +
                                            noizDens[VBICIBEPNOIZ] +
                                            noizDens[VBICFLBENOIZ] +
                                            noizDens[VBICFLBEPNOIZ];

                    lnNdens[VBICTOTNOIZ] = 
                                 log(noizDens[VBICTOTNOIZ]);

                    *OnDens += noizDens[VBICTOTNOIZ];

                    if (data->delFreq == 0.0) { 

                        /* if we haven't done any previous integration, we need to */
                        /* initialize our "history" variables                      */

                        for (i=0; i < VBICNSRCS; i++) {
                            inst->VBICnVar[LNLSTDENS][i] = lnNdens[i];
                        }

                        /* clear out our integration variables if it's the first pass */

                        if (data->freq == job->NstartFreq) {
                            for (i=0; i < VBICNSRCS; i++) {
                                inst->VBICnVar[OUTNOIZ][i] = 0.0;
                                inst->VBICnVar[INNOIZ][i] = 0.0;
                            }
                        }
                    } else {   /* data->delFreq != 0.0 (we have to integrate) */

/* In order to get the best curve fit, we have to integrate each component separately */

                        for (i=0; i < VBICNSRCS; i++) {
                            if (i != VBICTOTNOIZ) {
                                tempOnoise = Nintegrate(noizDens[i], lnNdens[i],
                                      inst->VBICnVar[LNLSTDENS][i], data);
                                tempInoise = Nintegrate(noizDens[i] * data->GainSqInv ,
                                      lnNdens[i] + data->lnGainInv,
                                      inst->VBICnVar[LNLSTDENS][i] + data->lnGainInv,
                                      data);
                                inst->VBICnVar[LNLSTDENS][i] = lnNdens[i];
                                data->outNoiz += tempOnoise;
                                data->inNoise += tempInoise;
                                if (job->NStpsSm != 0) {
                                    inst->VBICnVar[OUTNOIZ][i] += tempOnoise;
                                    inst->VBICnVar[OUTNOIZ][VBICTOTNOIZ] += tempOnoise;
                                    inst->VBICnVar[INNOIZ][i] += tempInoise;
                                    inst->VBICnVar[INNOIZ][VBICTOTNOIZ] += tempInoise;
                                }
                            }
                        }
                    }
                    if (data->prtSummary) {
                        for (i=0; i < VBICNSRCS; i++) {     /* print a summary report */
                            data->outpVector[data->outNumber++] = noizDens[i];
                        }
                    }
                    break;

                case INT_NOIZ:        /* already calculated, just output */
                    if (job->NStpsSm != 0) {
                        for (i=0; i < VBICNSRCS; i++) {
                            data->outpVector[data->outNumber++] = inst->VBICnVar[OUTNOIZ][i];
                            data->outpVector[data->outNumber++] = inst->VBICnVar[INNOIZ][i];
                        }
                    }    /* if */
                    break;
                }    /* switch (mode) */
                break;

            case N_CLOSE:
                return (OK);         /* do nothing, the main calling routine will close */
                break;               /* the plots */
            }    /* switch (operation) */
        }    /* for inst */
    }    /* for model */

return(OK);
}
Exemplo n.º 8
0
int
CKTnoise (CKTcircuit *ckt, int mode, int operation, Ndata *data)
{
    NOISEAN *job = (NOISEAN *) ckt->CKTcurJob;

    double outNdens;
    int i;
    IFvalue outData;    /* output variable (points to list of outputs)*/
    IFvalue refVal; /* reference variable (always 0)*/
    int error;

    outNdens = 0.0;

    /* let each device decide how many and what type of noise sources it has */

    for (i=0; i < DEVmaxnum; i++) {
	if ( DEVices[i] && DEVices[i]->DEVnoise && ckt->CKThead[i] ) {
	    error = DEVices[i]->DEVnoise (mode, operation, ckt->CKThead[i],
		ckt,data, &outNdens);
            if (error) return (error);
        }
    }

    switch (operation) {

    case N_OPEN:

	/* take care of the noise for the circuit as a whole */

	switch (mode) {

	case N_DENS:

	    data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);

	    SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]),
                                  NULL, "onoise_spectrum", UID_OTHER, NULL);

	    data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);

	    SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]),
                                  NULL, "inoise_spectrum", UID_OTHER, NULL);

	    /* we've added two more plots */

	    data->outpVector =
		TMALLOC(double, data->numPlots);
            break;

	case INT_NOIZ:

	    data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
	    SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]),
                                  NULL, "onoise_total", UID_OTHER, NULL);

	    data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
	    SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]),
                                  NULL, "inoise_total", UID_OTHER, NULL);
	    /* we've added two more plots */

	    data->outpVector =
		TMALLOC(double, data->numPlots);
	    break;

        default:
	    return (E_INTERN);
        }

	break;

    case N_CALC:

	switch (mode) {

	case N_DENS:
            if ((job->NStpsSm == 0)
		|| data->prtSummary)
	    {
		data->outpVector[data->outNumber++] = outNdens;
		data->outpVector[data->outNumber++] =
		    (outNdens * data->GainSqInv);

		refVal.rValue = data->freq; /* the reference is the freq */
		outData.v.numValue = data->outNumber; /* vector number */
		outData.v.vec.rVec = data->outpVector; /* vector of outputs */
		SPfrontEnd->OUTpData (data->NplotPtr, &refVal, &outData);
            }
            break;

	case INT_NOIZ:
	    data->outpVector[data->outNumber++] =  data->outNoiz; 
	    data->outpVector[data->outNumber++] =  data->inNoise;
	    outData.v.vec.rVec = data->outpVector; /* vector of outputs */
	    outData.v.numValue = data->outNumber; /* vector number */
	    SPfrontEnd->OUTpData (data->NplotPtr, &refVal, &outData);
	    break;

	default:
	    return (E_INTERN);
        }
        break;

    case N_CLOSE:
	SPfrontEnd->OUTendPlot (data->NplotPtr);
	FREE(data->namelist);
	FREE(data->outpVector);
        break;

    default:
	return (E_INTERN);
    }
    return (OK);
}
Exemplo n.º 9
0
int
BSIM4v5noise (
int mode, int operation,
GENmodel *inModel,
CKTcircuit *ckt,
Ndata *data,
double *OnDens)
{
NOISEAN *job = (NOISEAN *) ckt->CKTcurJob;

BSIM4v5model *model = (BSIM4v5model *)inModel;
BSIM4v5instance *here;
struct bsim4v5SizeDependParam *pParam;
char name[N_MXVLNTH];
double tempOnoise;
double tempInoise;
double noizDens[BSIM4v5NSRCS];
double lnNdens[BSIM4v5NSRCS];

double T0, T1, T2, T5, T10, T11;
double Vds, Ssi, Swi;
double tmp=0.0, gdpr, gspr, npart_theta=0.0, npart_beta=0.0, igsquare, bodymode;

double m;

int i;

    /* define the names of the noise sources */
    static char *BSIM4v5nNames[BSIM4v5NSRCS] =
    {   /* Note that we have to keep the order */
        ".rd",              /* noise due to rd */
        ".rs",              /* noise due to rs */
        ".rg",              /* noise due to rgeltd */
        ".rbps",            /* noise due to rbps */
        ".rbpd",            /* noise due to rbpd */
        ".rbpb",            /* noise due to rbpb */
        ".rbsb",            /* noise due to rbsb */
        ".rbdb",            /* noise due to rbdb */
        ".id",              /* noise due to id */
        ".1overf",          /* flicker (1/f) noise */
        ".igs",             /* shot noise due to IGS */
        ".igd",             /* shot noise due to IGD */
        ".igb",             /* shot noise due to IGB */
        ""                  /* total transistor noise */
    };

    for (; model != NULL; model = model->BSIM4v5nextModel)
    {    for (here = model->BSIM4v5instances; here != NULL;
              here = here->BSIM4v5nextInstance)
         {    pParam = here->pParam;
              switch (operation)
              {  case N_OPEN:
                     /* see if we have to to produce a summary report */
                     /* if so, name all the noise generators */

                      if (job->NStpsSm != 0)
                      {   switch (mode)
                          {  case N_DENS:
                                  for (i = 0; i < BSIM4v5NSRCS; i++)
                                  {    (void) sprintf(name, "onoise.%s%s",
                                                      here->BSIM4v5name,
                                                      BSIM4v5nNames[i]);
                                       data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
                                       if (!data->namelist)
                                           return(E_NOMEM);
                                       SPfrontEnd->IFnewUid (ckt,
                                          &(data->namelist[data->numPlots++]),
                                          NULL, name, UID_OTHER,
                                          NULL);
                                       /* we've added one more plot */
                                  }
                                  break;
                             case INT_NOIZ:
                                  for (i = 0; i < BSIM4v5NSRCS; i++)
                                  {    (void) sprintf(name, "onoise_total.%s%s",
                                                      here->BSIM4v5name,
                                                      BSIM4v5nNames[i]);
                                       data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
                                       if (!data->namelist)
                                           return(E_NOMEM);
                                       SPfrontEnd->IFnewUid (ckt,
                                          &(data->namelist[data->numPlots++]),
                                          NULL, name, UID_OTHER,
                                          NULL);
                                       /* we've added one more plot */

                                       (void) sprintf(name, "inoise_total.%s%s",
                                                      here->BSIM4v5name,
                                                      BSIM4v5nNames[i]);
                                       data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
                                       if (!data->namelist)
                                           return(E_NOMEM);
                                       SPfrontEnd->IFnewUid (ckt,
                                          &(data->namelist[data->numPlots++]),
                                          NULL, name, UID_OTHER,
                                          NULL);
                                       /* we've added one more plot */
                                  }
                                  break;
                          }
                      }
                      break;
                 case N_CALC:
                      m = here->BSIM4v5m;
                      switch (mode)
                      {  case N_DENS:
                              if (model->BSIM4v5tnoiMod == 0)
                              {   if (model->BSIM4v5rdsMod == 0)
                                  {   gspr = here->BSIM4v5sourceConductance;
                                      gdpr = here->BSIM4v5drainConductance;
                                      if (here->BSIM4v5grdsw > 0.0)
                                          tmp = 1.0 / here->BSIM4v5grdsw; /* tmp used below */ 
                                      else
                                          tmp = 0.0;
                                  }
                                  else
                                  {   gspr = here->BSIM4v5gstot;
                                      gdpr = here->BSIM4v5gdtot;
                                      tmp = 0.0;
                                  }
                              }
                              else
                              {   T5 = here->BSIM4v5Vgsteff / here->BSIM4v5EsatL;
                                  T5 *= T5;
                                  npart_beta = model->BSIM4v5rnoia * (1.0 + T5
                                             * model->BSIM4v5tnoia * pParam->BSIM4v5leff);
                                  npart_theta = model->BSIM4v5rnoib * (1.0 + T5
                                              * model->BSIM4v5tnoib * pParam->BSIM4v5leff);

                                  if (model->BSIM4v5rdsMod == 0)
                                  {   gspr = here->BSIM4v5sourceConductance;
                                      gdpr = here->BSIM4v5drainConductance;
                                  }
                                  else
                                  {   gspr = here->BSIM4v5gstot;
                                      gdpr = here->BSIM4v5gdtot;
                                  }

                                  if ((*(ckt->CKTstates[0] + here->BSIM4v5vds)) >= 0.0)
                                      gspr = gspr / (1.0 + npart_theta * npart_theta * gspr
                                            / here->BSIM4v5IdovVds);  /* bugfix */
                                  else
                                      gdpr = gdpr / (1.0 + npart_theta * npart_theta * gdpr
                                           / here->BSIM4v5IdovVds);
                              } 

                              NevalSrc(&noizDens[BSIM4v5RDNOIZ],
                                       &lnNdens[BSIM4v5RDNOIZ], ckt, THERMNOISE,
                                       here->BSIM4v5dNodePrime, here->BSIM4v5dNode,
                                       gdpr * m);

                              NevalSrc(&noizDens[BSIM4v5RSNOIZ],
                                       &lnNdens[BSIM4v5RSNOIZ], ckt, THERMNOISE,
                                       here->BSIM4v5sNodePrime, here->BSIM4v5sNode,
                                       gspr * m);


                              if ((here->BSIM4v5rgateMod == 1) || (here->BSIM4v5rgateMod == 2))
                              {   NevalSrc(&noizDens[BSIM4v5RGNOIZ],
                                       &lnNdens[BSIM4v5RGNOIZ], ckt, THERMNOISE,
                                       here->BSIM4v5gNodePrime, here->BSIM4v5gNodeExt,
                                       here->BSIM4v5grgeltd * m);
                              }
                              else if (here->BSIM4v5rgateMod == 3)
                              {   NevalSrc(&noizDens[BSIM4v5RGNOIZ],
                                       &lnNdens[BSIM4v5RGNOIZ], ckt, THERMNOISE,
                                       here->BSIM4v5gNodeMid, here->BSIM4v5gNodeExt,
                                       here->BSIM4v5grgeltd * m);
                              }
                              else
                              {    noizDens[BSIM4v5RGNOIZ] = 0.0;
                                   lnNdens[BSIM4v5RGNOIZ] =
                                          log(MAX(noizDens[BSIM4v5RGNOIZ], N_MINLOG));
                              }

                                    bodymode = 5;
                                    if (here->BSIM4v5rbodyMod == 2)
                                    {        if( ( !model->BSIM4v5rbps0Given) || 
                                      ( !model->BSIM4v5rbpd0Given) )
                                             bodymode = 1;
                                           else 
                                     if( (!model->BSIM4v5rbsbx0Given && !model->BSIM4v5rbsby0Given) ||
                                          (!model->BSIM4v5rbdbx0Given && !model->BSIM4v5rbdby0Given) )
                                             bodymode = 3;
                                }

                              if (here->BSIM4v5rbodyMod)
                              { 
                                if(bodymode == 5)
                                  {
                                    NevalSrc(&noizDens[BSIM4v5RBPSNOIZ],
                                             &lnNdens[BSIM4v5RBPSNOIZ], ckt, THERMNOISE,
                                             here->BSIM4v5bNodePrime, here->BSIM4v5sbNode,
                                             here->BSIM4v5grbps * m);
                                    NevalSrc(&noizDens[BSIM4v5RBPDNOIZ],
                                             &lnNdens[BSIM4v5RBPDNOIZ], ckt, THERMNOISE,
                                             here->BSIM4v5bNodePrime, here->BSIM4v5dbNode,
                                             here->BSIM4v5grbpd * m);
                                    NevalSrc(&noizDens[BSIM4v5RBPBNOIZ],
                                             &lnNdens[BSIM4v5RBPBNOIZ], ckt, THERMNOISE,
                                             here->BSIM4v5bNodePrime, here->BSIM4v5bNode,
                                             here->BSIM4v5grbpb * m);
                                    NevalSrc(&noizDens[BSIM4v5RBSBNOIZ],
                                             &lnNdens[BSIM4v5RBSBNOIZ], ckt, THERMNOISE,
                                             here->BSIM4v5bNode, here->BSIM4v5sbNode,
                                             here->BSIM4v5grbsb * m);
                                    NevalSrc(&noizDens[BSIM4v5RBDBNOIZ],
                                             &lnNdens[BSIM4v5RBDBNOIZ], ckt, THERMNOISE,
                                             here->BSIM4v5bNode, here->BSIM4v5dbNode,
                                             here->BSIM4v5grbdb * m);
                                  }
                                if(bodymode == 3)
                                  {
                                    NevalSrc(&noizDens[BSIM4v5RBPSNOIZ],
                                             &lnNdens[BSIM4v5RBPSNOIZ], ckt, THERMNOISE,
                                             here->BSIM4v5bNodePrime, here->BSIM4v5sbNode,
                                             here->BSIM4v5grbps * m);
                                    NevalSrc(&noizDens[BSIM4v5RBPDNOIZ],
                                             &lnNdens[BSIM4v5RBPDNOIZ], ckt, THERMNOISE,
                                             here->BSIM4v5bNodePrime, here->BSIM4v5dbNode,
                                             here->BSIM4v5grbpd * m);
                                    NevalSrc(&noizDens[BSIM4v5RBPBNOIZ],
                                             &lnNdens[BSIM4v5RBPBNOIZ], ckt, THERMNOISE,
                                             here->BSIM4v5bNodePrime, here->BSIM4v5bNode,
                                             here->BSIM4v5grbpb * m);
                                     noizDens[BSIM4v5RBSBNOIZ] = noizDens[BSIM4v5RBDBNOIZ] = 0.0;
                                     lnNdens[BSIM4v5RBSBNOIZ] =
                                       log(MAX(noizDens[BSIM4v5RBSBNOIZ], N_MINLOG));
                                     lnNdens[BSIM4v5RBDBNOIZ] =
                                       log(MAX(noizDens[BSIM4v5RBDBNOIZ], N_MINLOG));                                     
                                  }
                                if(bodymode == 1)
                                  {
                                    NevalSrc(&noizDens[BSIM4v5RBPBNOIZ],
                                             &lnNdens[BSIM4v5RBPBNOIZ], ckt, THERMNOISE,
                                             here->BSIM4v5bNodePrime, here->BSIM4v5bNode,
                                             here->BSIM4v5grbpb * m);                                    
                                    noizDens[BSIM4v5RBPSNOIZ] = noizDens[BSIM4v5RBPDNOIZ] = 0.0;                                    
                                    noizDens[BSIM4v5RBSBNOIZ] = noizDens[BSIM4v5RBDBNOIZ] = 0.0;
                                    lnNdens[BSIM4v5RBPSNOIZ] =
                                      log(MAX(noizDens[BSIM4v5RBPSNOIZ], N_MINLOG));
                                    lnNdens[BSIM4v5RBPDNOIZ] =
                                      log(MAX(noizDens[BSIM4v5RBPDNOIZ], N_MINLOG));
                                    lnNdens[BSIM4v5RBSBNOIZ] =
                                      log(MAX(noizDens[BSIM4v5RBSBNOIZ], N_MINLOG));
                                    lnNdens[BSIM4v5RBDBNOIZ] =
                                      log(MAX(noizDens[BSIM4v5RBDBNOIZ], N_MINLOG));
                                  }
                              }
                              else
                              {   noizDens[BSIM4v5RBPSNOIZ] = noizDens[BSIM4v5RBPDNOIZ] = 0.0;   
                                  noizDens[BSIM4v5RBPBNOIZ] = 0.0;
                                  noizDens[BSIM4v5RBSBNOIZ] = noizDens[BSIM4v5RBDBNOIZ] = 0.0;
                                  lnNdens[BSIM4v5RBPSNOIZ] =
                                          log(MAX(noizDens[BSIM4v5RBPSNOIZ], N_MINLOG));
                                  lnNdens[BSIM4v5RBPDNOIZ] =
                                          log(MAX(noizDens[BSIM4v5RBPDNOIZ], N_MINLOG));
                                  lnNdens[BSIM4v5RBPBNOIZ] =
                                          log(MAX(noizDens[BSIM4v5RBPBNOIZ], N_MINLOG));
                                  lnNdens[BSIM4v5RBSBNOIZ] =
                                          log(MAX(noizDens[BSIM4v5RBSBNOIZ], N_MINLOG));
                                  lnNdens[BSIM4v5RBDBNOIZ] =
                                          log(MAX(noizDens[BSIM4v5RBDBNOIZ], N_MINLOG));
                              }


                              switch(model->BSIM4v5tnoiMod)
                              {  case 0:
                                      T0 = here->BSIM4v5ueff * fabs(here->BSIM4v5qinv);
                                      T1 = T0 * tmp + pParam->BSIM4v5leff
                                         * pParam->BSIM4v5leff;
                                      NevalSrc(&noizDens[BSIM4v5IDNOIZ],
                                               &lnNdens[BSIM4v5IDNOIZ], ckt,
                                               THERMNOISE, here->BSIM4v5dNodePrime,
                                               here->BSIM4v5sNodePrime,
                                               m * (T0 / T1) * model->BSIM4v5ntnoi);
                                      break;
                                 case 1:
                                      T0 = here->BSIM4v5gm + here->BSIM4v5gmbs + here->BSIM4v5gds;
                                      T0 *= T0;
                                      igsquare = npart_theta * npart_theta * T0 / here->BSIM4v5IdovVds;
                                      T1 = npart_beta * (here->BSIM4v5gm
                                         + here->BSIM4v5gmbs) + here->BSIM4v5gds;
                                      T2 = T1 * T1 / here->BSIM4v5IdovVds;
                                      NevalSrc(&noizDens[BSIM4v5IDNOIZ],
                                               &lnNdens[BSIM4v5IDNOIZ], ckt,
                                               THERMNOISE, here->BSIM4v5dNodePrime,
                                               here->BSIM4v5sNodePrime, m * (T2 - igsquare));
                                      break;
                              }

                              NevalSrc(&noizDens[BSIM4v5FLNOIZ], NULL,
                                       ckt, N_GAIN, here->BSIM4v5dNodePrime,
                                       here->BSIM4v5sNodePrime, (double) 0.0);

                              switch(model->BSIM4v5fnoiMod)
                              {  case 0:
                                      noizDens[BSIM4v5FLNOIZ] *= m * model->BSIM4v5kf
                                            * exp(model->BSIM4v5af
                                            * log(MAX(fabs(here->BSIM4v5cd),
                                            N_MINLOG)))
                                            / (pow(data->freq, model->BSIM4v5ef)
                                            * pParam->BSIM4v5leff
                                            * pParam->BSIM4v5leff
                                            * model->BSIM4v5coxe);
                                      break;
                                 case 1:
                                      Vds = *(ckt->CKTstates[0] + here->BSIM4v5vds);
                                      if (Vds < 0.0)
                                          Vds = -Vds;

                                      Ssi = BSIM4v5Eval1ovFNoise(Vds, model, here,
                                          data->freq, ckt->CKTtemp);
                                      T10 = model->BSIM4v5oxideTrapDensityA
                                          * CONSTboltz * ckt->CKTtemp;
                                      T11 = pParam->BSIM4v5weff * here->BSIM4v5nf * pParam->BSIM4v5leff
                                          * pow(data->freq, model->BSIM4v5ef) * 1.0e10
                                          * here->BSIM4v5nstar * here->BSIM4v5nstar;
                                      Swi = T10 / T11 * here->BSIM4v5cd
                                          * here->BSIM4v5cd;
                                      T1 = Swi + Ssi;
                                      if (T1 > 0.0)
                                          noizDens[BSIM4v5FLNOIZ] *= m * (Ssi * Swi) / T1;
                                      else
                                          noizDens[BSIM4v5FLNOIZ] *= 0.0;
                                      break;
                              }

                              lnNdens[BSIM4v5FLNOIZ] =
                                     log(MAX(noizDens[BSIM4v5FLNOIZ], N_MINLOG));


                               if(here->BSIM4v5mode >= 0) {  /* bugfix  */
                              NevalSrc(&noizDens[BSIM4v5IGSNOIZ],
                                   &lnNdens[BSIM4v5IGSNOIZ], ckt, SHOTNOISE,
                                   here->BSIM4v5gNodePrime, here->BSIM4v5sNodePrime,
                                   m * (here->BSIM4v5Igs + here->BSIM4v5Igcs));
                              NevalSrc(&noizDens[BSIM4v5IGDNOIZ],
                                   &lnNdens[BSIM4v5IGDNOIZ], ckt, SHOTNOISE,
                                   here->BSIM4v5gNodePrime, here->BSIM4v5dNodePrime,
                                   m * (here->BSIM4v5Igd + here->BSIM4v5Igcd));
                        } else {
                              NevalSrc(&noizDens[BSIM4v5IGSNOIZ],
                                   &lnNdens[BSIM4v5IGSNOIZ], ckt, SHOTNOISE,
                                   here->BSIM4v5gNodePrime, here->BSIM4v5sNodePrime,
                                   m * (here->BSIM4v5Igs + here->BSIM4v5Igcd));
                              NevalSrc(&noizDens[BSIM4v5IGDNOIZ],
                                   &lnNdens[BSIM4v5IGDNOIZ], ckt, SHOTNOISE,
                                   here->BSIM4v5gNodePrime, here->BSIM4v5dNodePrime,
                                   m * (here->BSIM4v5Igd + here->BSIM4v5Igcs));
                        }
                              NevalSrc(&noizDens[BSIM4v5IGBNOIZ],
                                   &lnNdens[BSIM4v5IGBNOIZ], ckt, SHOTNOISE,
                                   here->BSIM4v5gNodePrime, here->BSIM4v5bNodePrime,
                                   m * here->BSIM4v5Igb);


                              noizDens[BSIM4v5TOTNOIZ] = noizDens[BSIM4v5RDNOIZ]
                                     + noizDens[BSIM4v5RSNOIZ] + noizDens[BSIM4v5RGNOIZ]
                                     + noizDens[BSIM4v5RBPSNOIZ] + noizDens[BSIM4v5RBPDNOIZ]
                                     + noizDens[BSIM4v5RBPBNOIZ]
                                     + noizDens[BSIM4v5RBSBNOIZ] + noizDens[BSIM4v5RBDBNOIZ]
                                     + noizDens[BSIM4v5IDNOIZ] + noizDens[BSIM4v5FLNOIZ]
                                     + noizDens[BSIM4v5IGSNOIZ] + noizDens[BSIM4v5IGDNOIZ]
                                     + noizDens[BSIM4v5IGBNOIZ];
                              lnNdens[BSIM4v5TOTNOIZ] = 
                                     log(MAX(noizDens[BSIM4v5TOTNOIZ], N_MINLOG));

                              *OnDens += noizDens[BSIM4v5TOTNOIZ];

                              if (data->delFreq == 0.0)
                              {   /* if we haven't done any previous 
                                     integration, we need to initialize our
                                     "history" variables.
                                    */

                                  for (i = 0; i < BSIM4v5NSRCS; i++)
                                  {    here->BSIM4v5nVar[LNLSTDENS][i] =
                                             lnNdens[i];
                                  }

                                  /* clear out our integration variables
                                     if it's the first pass
                                   */
                                  if (data->freq ==
                                      job->NstartFreq)
                                  {   for (i = 0; i < BSIM4v5NSRCS; i++)
                                      {    here->BSIM4v5nVar[OUTNOIZ][i] = 0.0;
                                           here->BSIM4v5nVar[INNOIZ][i] = 0.0;
                                      }
                                  }
                              }
                              else
                              {   /* data->delFreq != 0.0,
                                     we have to integrate.
                                   */
                                  for (i = 0; i < BSIM4v5NSRCS; i++)
                                  {    if (i != BSIM4v5TOTNOIZ)
                                       {   tempOnoise = Nintegrate(noizDens[i],
                                                lnNdens[i],
                                                here->BSIM4v5nVar[LNLSTDENS][i],
                                                data);
                                           tempInoise = Nintegrate(noizDens[i]
                                                * data->GainSqInv, lnNdens[i]
                                                + data->lnGainInv,
                                                here->BSIM4v5nVar[LNLSTDENS][i]
                                                + data->lnGainInv, data);
                                           here->BSIM4v5nVar[LNLSTDENS][i] =
                                                lnNdens[i];
                                           data->outNoiz += tempOnoise;
                                           data->inNoise += tempInoise;
                                           if (job->NStpsSm != 0)
                                           {   here->BSIM4v5nVar[OUTNOIZ][i]
                                                     += tempOnoise;
                                               here->BSIM4v5nVar[OUTNOIZ][BSIM4v5TOTNOIZ]
                                                     += tempOnoise;
                                               here->BSIM4v5nVar[INNOIZ][i]
                                                     += tempInoise;
                                               here->BSIM4v5nVar[INNOIZ][BSIM4v5TOTNOIZ]
                                                     += tempInoise;
                                           }
                                       }
                                  }
                              }
                              if (data->prtSummary)
                              {   for (i = 0; i < BSIM4v5NSRCS; i++)
                                  {    /* print a summary report */
                                       data->outpVector[data->outNumber++]
                                             = noizDens[i];
                                  }
                              }
                              break;
                         case INT_NOIZ:
                              /* already calculated, just output */
                              if (job->NStpsSm != 0)
                              {   for (i = 0; i < BSIM4v5NSRCS; i++)
                                  {    data->outpVector[data->outNumber++]
                                             = here->BSIM4v5nVar[OUTNOIZ][i];
                                       data->outpVector[data->outNumber++]
                                             = here->BSIM4v5nVar[INNOIZ][i];
                                  }
                              }
                              break;
                      }
                      break;
                 case N_CLOSE:
                      /* do nothing, the main calling routine will close */
                      return (OK);
                      break;   /* the plots */
              }       /* switch (operation) */
         }    /* for here */
    }    /* for model */

    return(OK);
}
Exemplo n.º 10
0
int
JFETnoise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, Ndata *data,
           double *OnDens)
{
    NOISEAN *job = (NOISEAN *) ckt->CKTcurJob;

    JFETmodel *firstModel = (JFETmodel *) genmodel;
    JFETmodel *model;
    JFETinstance *inst;
    char name[N_MXVLNTH];
    double tempOnoise;
    double tempInoise;
    double noizDens[JFETNSRCS];
    double lnNdens[JFETNSRCS];
    int i;
    double vgs, vds, vgst, alpha, beta;

    /* define the names of the noise sources */

    static char *JFETnNames[JFETNSRCS] = {       /* Note that we have to keep the order */
        "_rd",              /* noise due to rd */        /* consistent with thestrchr definitions */
        "_rs",              /* noise due to rs */        /* in JFETdefs.h */
        "_id",              /* noise due to id */
        "_1overf",          /* flicker (1/f) noise */
        ""                  /* total transistor noise */
    };

    for (model=firstModel; model != NULL; model=model->JFETnextModel) {
        for (inst=model->JFETinstances; inst != NULL; inst=inst->JFETnextInstance) {

            switch (operation) {

            case N_OPEN:

                /* see if we have to to produce a summary report */
                /* if so, name all the noise generators */

                if (job->NStpsSm != 0) {
                    switch (mode) {

                    case N_DENS:
                        for (i=0; i < JFETNSRCS; i++) {
                            (void)sprintf(name,"onoise_%s%s",inst->JFETname,JFETnNames[i]);

                            data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
                            if (!data->namelist) return(E_NOMEM);
                                            SPfrontEnd->IFnewUid (ckt,
                                                    &(data->namelist[data->numPlots++]),
                                                    NULL, name, UID_OTHER, NULL);
                                                            /* we've added one more plot */

                        }
                        break;

                    case INT_NOIZ:
                        for (i=0; i < JFETNSRCS; i++) {
                            (void)sprintf(name,"onoise_total_%s%s",inst->JFETname,JFETnNames[i]);

                            data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
                            if (!data->namelist) return(E_NOMEM);
                                            SPfrontEnd->IFnewUid (ckt,
                                                    &(data->namelist[data->numPlots++]),
                                                    NULL, name, UID_OTHER, NULL);
                                                            /* we've added one more plot */

                            (void)sprintf(name,"inoise_total_%s%s",inst->JFETname,JFETnNames[i]);

                            data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
                            if (!data->namelist) return(E_NOMEM);
                                            SPfrontEnd->IFnewUid (ckt,
                                                    &(data->namelist[data->numPlots++]),
                                                    NULL, name, UID_OTHER, NULL);
                                                            /* we've added one more plot */

                        }
                        break;
                    }
                }
                break;

            case N_CALC:
                switch (mode) {

                case N_DENS:
                    NevalSrc(&noizDens[JFETRDNOIZ],&lnNdens[JFETRDNOIZ],
                                 ckt,THERMNOISE,inst->JFETdrainPrimeNode,inst->JFETdrainNode,
                                 model->JFETdrainConduct * inst->JFETarea * inst->JFETm);

                    NevalSrc(&noizDens[JFETRSNOIZ],&lnNdens[JFETRSNOIZ],
                                 ckt,THERMNOISE,inst->JFETsourcePrimeNode,
                                 inst->JFETsourceNode,model->JFETsourceConduct
                                 * inst->JFETarea * inst->JFETm);

                    if (model->JFETnlev < 3) {
                        NevalSrc(&noizDens[JFETIDNOIZ],&lnNdens[JFETIDNOIZ],
                                     ckt,THERMNOISE,inst->JFETdrainPrimeNode,
                                     inst->JFETsourcePrimeNode,
                                     (2.0/3.0 * inst->JFETm * fabs(*(ckt->CKTstate0 + inst->JFETgm))));
                    } else {
                        vgs = *(ckt->CKTstate0 + inst->JFETvgs);
                        vds = vgs - *(ckt->CKTstate0 + inst->JFETvgd);
                        vgst = vgs - inst->JFETtThreshold;
                        if (vgst >= vds)
                            alpha = 1 - vds/vgst; /* linear region */
                        else
                            alpha = 0;        /* saturation region */
                        beta = inst->JFETtBeta * inst->JFETarea * inst->JFETm;

                        NevalSrc(&noizDens[JFETIDNOIZ],&lnNdens[JFETIDNOIZ],
                                     ckt,THERMNOISE,inst->JFETdrainPrimeNode,
                                     inst->JFETsourcePrimeNode,
                                     (2.0/3.0 * beta*vgst*(1+alpha+alpha*alpha)/(1+alpha)*model->JFETgdsnoi));
                    }

                    NevalSrc(&noizDens[JFETFLNOIZ], NULL, ckt,
                                 N_GAIN,inst->JFETdrainPrimeNode,
                                 inst->JFETsourcePrimeNode, (double)0.0);
                    noizDens[JFETFLNOIZ] *= inst->JFETm * model->JFETfNcoef *
                                 exp(model->JFETfNexp *
                                 log(MAX(fabs(*(ckt->CKTstate0 + inst->JFETcd)),N_MINLOG))) /
                                 data->freq;
                    lnNdens[JFETFLNOIZ] =
                                 log(MAX(noizDens[JFETFLNOIZ],N_MINLOG));

                    noizDens[JFETTOTNOIZ] = noizDens[JFETRDNOIZ] +
                                                     noizDens[JFETRSNOIZ] +
                                                     noizDens[JFETIDNOIZ] +
                                                     noizDens[JFETFLNOIZ];
                    lnNdens[JFETTOTNOIZ] =
                                 log(MAX(noizDens[JFETTOTNOIZ], N_MINLOG));

                    *OnDens += noizDens[JFETTOTNOIZ];

                    if (data->delFreq == 0.0) {

                        /* if we haven't done any previous integration, we need to */
                        /* initialize our "history" variables                      */

                        for (i=0; i < JFETNSRCS; i++) {
                            inst->JFETnVar[LNLSTDENS][i] = lnNdens[i];
                        }

                        /* clear out our integration variables if it's the first pass */

                        if (data->freq == job->NstartFreq) {
                            for (i=0; i < JFETNSRCS; i++) {
                                inst->JFETnVar[OUTNOIZ][i] = 0.0;
                                inst->JFETnVar[INNOIZ][i] = 0.0;
                            }
                        }
                    } else {   /* data->delFreq != 0.0 (we have to integrate) */
                        for (i=0; i < JFETNSRCS; i++) {
                            if (i != JFETTOTNOIZ) {
                                tempOnoise = Nintegrate(noizDens[i], lnNdens[i],
                                      inst->JFETnVar[LNLSTDENS][i], data);
                                tempInoise = Nintegrate(noizDens[i] * data->GainSqInv ,
                                      lnNdens[i] + data->lnGainInv,
                                      inst->JFETnVar[LNLSTDENS][i] + data->lnGainInv,
                                      data);
                                inst->JFETnVar[LNLSTDENS][i] = lnNdens[i];
                                data->outNoiz += tempOnoise;
                                data->inNoise += tempInoise;
                                if (job->NStpsSm != 0) {
                                    inst->JFETnVar[OUTNOIZ][i] += tempOnoise;
                                    inst->JFETnVar[OUTNOIZ][JFETTOTNOIZ] += tempOnoise;
                                    inst->JFETnVar[INNOIZ][i] += tempInoise;
                                    inst->JFETnVar[INNOIZ][JFETTOTNOIZ] += tempInoise;
                                }
                            }
                        }
                    }
                    if (data->prtSummary) {
                        for (i=0; i < JFETNSRCS; i++) {     /* print a summary report */
                            data->outpVector[data->outNumber++] = noizDens[i];
                        }
                    }
                    break;

                case INT_NOIZ:        /* already calculated, just output */
                    if (job->NStpsSm != 0) {
                        for (i=0; i < JFETNSRCS; i++) {
                            data->outpVector[data->outNumber++] = inst->JFETnVar[OUTNOIZ][i];
                            data->outpVector[data->outNumber++] = inst->JFETnVar[INNOIZ][i];
                        }
                    }    /* if */
                    break;
                }    /* switch (mode) */
                break;

            case N_CLOSE:
                return (OK);         /* do nothing, the main calling routine will close */
                break;               /* the plots */
            }    /* switch (operation) */
        }    /* for inst */
    }    /* for model */

    return(OK);
}