Add instance parameters td anr to the ISRC pwl source,
like has been available with voltage source VSRC.
This commit is contained in:
parent
a0af7065a8
commit
2a246632bb
|
|
@ -39,6 +39,8 @@ IFparm ISRCpTable[] = { /* parameters */
|
|||
OP ("v", ISRC_VOLTS, IF_REAL, "Voltage across the supply"),
|
||||
OP ("p", ISRC_POWER, IF_REAL, "Power supplied by the source"),
|
||||
OP ("current", ISRC_CURRENT, IF_REAL, "Current in DC or Transient mode"),
|
||||
IP ("r", ISRC_R, IF_REAL, "pwl repeat value"),
|
||||
IP ("td", ISRC_TD, IF_REAL, "pwl delay value"),
|
||||
IP ("distof1", ISRC_D_F1, IF_REALVEC,"f1 input for distortion"),
|
||||
IP ("distof2", ISRC_D_F2, IF_REALVEC,"f2 input for distortion")
|
||||
};
|
||||
|
|
|
|||
|
|
@ -183,6 +183,60 @@ ISRCaccept(CKTcircuit *ckt, GENmodel *inModel)
|
|||
}
|
||||
break;
|
||||
|
||||
case PWL: {
|
||||
if (ckt->CKTtime >= here->ISRCbreak_time) {
|
||||
double time, atime, end, period;
|
||||
int i;
|
||||
|
||||
time = ckt->CKTtime - here->ISRCrdelay;
|
||||
end =
|
||||
here->ISRCcoeffs[here->ISRCfunctionOrder - 2];
|
||||
if (time > end) {
|
||||
if (here->ISRCrGiven) {
|
||||
/* Repeating. */
|
||||
|
||||
period = end -
|
||||
here->ISRCcoeffs[here->ISRCrBreakpt];
|
||||
time -=
|
||||
here->ISRCcoeffs[here->ISRCrBreakpt];
|
||||
time -= period * floor(time / period);
|
||||
time +=
|
||||
here->ISRCcoeffs[here->ISRCrBreakpt];
|
||||
}
|
||||
else {
|
||||
here->ISRCbreak_time = ckt->CKTfinalTime;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* A request for a breakpoint very close
|
||||
* to the current time will be ignored.
|
||||
* Adjust so the next corner will be
|
||||
* selected.
|
||||
*/
|
||||
|
||||
atime = time + ckt->CKTminBreak;
|
||||
|
||||
for (i = 0;
|
||||
i < here->ISRCfunctionOrder;
|
||||
i += 2) {
|
||||
if (here->ISRCcoeffs[i] > atime) {
|
||||
here->ISRCbreak_time =
|
||||
ckt->CKTtime +
|
||||
here->ISRCcoeffs[i] - time;
|
||||
error = CKTsetBreak(ckt,
|
||||
here->ISRCbreak_time);
|
||||
if (error)
|
||||
return error;
|
||||
here->ISRCbreak_time -= ckt->CKTminBreak;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
case PWL: {
|
||||
int i;
|
||||
if(ckt->CKTtime < *(here->ISRCcoeffs)) {
|
||||
|
|
@ -200,7 +254,7 @@ ISRCaccept(CKTcircuit *ckt, GENmodel *inModel)
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
*/
|
||||
/**** tansient noise routines:
|
||||
INoi2 2 0 DC 0 TRNOISE(10n 0.5n 0 0n) : generate gaussian distributed noise
|
||||
rms value, time step, 0 0
|
||||
|
|
@ -320,7 +374,7 @@ ISRCaccept(CKTcircuit *ckt, GENmodel *inModel)
|
|||
|
||||
} // switch
|
||||
} // if ... else
|
||||
bkptset: ;
|
||||
// bkptset: ;
|
||||
} // for
|
||||
} // for
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ typedef struct sISRCinstance {
|
|||
|
||||
int ISRCfunctionType; /* code number of function type for source */
|
||||
int ISRCfunctionOrder; /* order of the function for the source */
|
||||
int ISRCrBreakpt; /* pwl repeat breakpoint index */
|
||||
double ISRCbreak_time; /* time of most-recent breakpoint */
|
||||
double *ISRCcoeffs; /* pointer to array of coefficients */
|
||||
|
||||
double ISRCdcValue; /* DC and TRANSIENT value of source */
|
||||
|
|
@ -51,6 +53,9 @@ typedef struct sISRCinstance {
|
|||
struct trnoise_state *ISRCtrnoise_state; /* transient noise */
|
||||
struct trrandom_state *ISRCtrrandom_state; /* transient random source */
|
||||
|
||||
double ISRCr; /* pwl repeat */
|
||||
double ISRCrdelay; /* pwl delay period */
|
||||
|
||||
/* needed for outputting results */
|
||||
double ISRCcurrent; /* current value */
|
||||
|
||||
|
|
@ -64,6 +69,7 @@ typedef struct sISRCinstance {
|
|||
unsigned ISRCdGiven :1 ; /* flag to indicate source is a distortion input */
|
||||
unsigned ISRCdF1given :1 ; /* flag to indicate source is an f1 distortion input */
|
||||
unsigned ISRCdF2given :1 ; /* flag to indicate source is an f2 distortion input */
|
||||
unsigned ISRCrGiven : 1; /* flag to indicate repeating pwl */
|
||||
} ISRCinstance ;
|
||||
|
||||
|
||||
|
|
@ -123,11 +129,10 @@ enum {
|
|||
ISRC_D_F2,
|
||||
ISRC_VOLTS,
|
||||
ISRC_AM,
|
||||
ISRC_R,
|
||||
ISRC_TD,
|
||||
ISRC_CURRENT,
|
||||
};
|
||||
|
||||
enum {
|
||||
ISRC_TRNOISE = 25,
|
||||
ISRC_TRNOISE,
|
||||
ISRC_TRRANDOM,
|
||||
ISRC_EXTERNAL,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ ISRCload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
{
|
||||
ISRCmodel *model = (ISRCmodel *) inModel;
|
||||
ISRCinstance *here;
|
||||
double value;
|
||||
double value = 0.0;
|
||||
double time;
|
||||
double m;
|
||||
|
||||
|
|
@ -300,6 +300,51 @@ ISRCload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
break;
|
||||
|
||||
case PWL: {
|
||||
int i;
|
||||
double end_time, itime;
|
||||
|
||||
time -= here->ISRCrdelay;
|
||||
if (time <= here->ISRCcoeffs[0]) {
|
||||
value = here->ISRCcoeffs[1];
|
||||
break;
|
||||
}
|
||||
|
||||
end_time =
|
||||
here->ISRCcoeffs[here->ISRCfunctionOrder - 2];
|
||||
if (time > end_time) {
|
||||
double period;
|
||||
|
||||
if (here->ISRCrGiven) {
|
||||
/* Repeating. */
|
||||
|
||||
period = end_time -
|
||||
here->ISRCcoeffs[here->ISRCrBreakpt];
|
||||
time -= here->ISRCcoeffs[here->ISRCrBreakpt];
|
||||
time -= period * floor(time / period);
|
||||
time += here->ISRCcoeffs[here->ISRCrBreakpt];
|
||||
}
|
||||
else {
|
||||
value =
|
||||
here->ISRCcoeffs[here->ISRCfunctionOrder - 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 2; i < here->ISRCfunctionOrder; i += 2) {
|
||||
itime = here->ISRCcoeffs[i];
|
||||
if (itime >= time) {
|
||||
time -= here->ISRCcoeffs[i - 2];
|
||||
time /= here->ISRCcoeffs[i] -
|
||||
here->ISRCcoeffs[i - 2];
|
||||
value = here->ISRCcoeffs[i - 1];
|
||||
value += time *
|
||||
(here->ISRCcoeffs[i + 1] -
|
||||
here->ISRCcoeffs[i - 1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
/*
|
||||
int i;
|
||||
if(time < *(here->ISRCcoeffs)) {
|
||||
value = *(here->ISRCcoeffs + 1) ;
|
||||
|
|
@ -323,6 +368,7 @@ ISRCload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
}
|
||||
value = *(here->ISRCcoeffs+ here->ISRCfunctionOrder-1) ;
|
||||
break;
|
||||
*/
|
||||
}
|
||||
|
||||
/**** tansient noise routines:
|
||||
|
|
@ -396,7 +442,7 @@ INoi1 1 0 DC 0 TRNOISE(0n 0.5n 1 10n) : generate 1/f noise
|
|||
|
||||
} // switch
|
||||
} // else (line 48)
|
||||
loadDone:
|
||||
// loadDone:
|
||||
|
||||
/* gtri - begin - wbk - modify for supply ramping option */
|
||||
#ifdef XSPICE_EXP
|
||||
|
|
|
|||
|
|
@ -123,6 +123,50 @@ ISRCparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
|
|||
|
||||
break;
|
||||
|
||||
case ISRC_TD:
|
||||
here->ISRCrdelay = value->rValue;
|
||||
break;
|
||||
|
||||
case ISRC_R: {
|
||||
double end_time;
|
||||
/* Parameter r of pwl may now be parameterized:
|
||||
if r == -1, no repetition done.
|
||||
if r == 0, repeat forever.
|
||||
if r == xx, repeat from time xx to last time point given. */
|
||||
if (value->rValue < -0.5) {
|
||||
here->ISRCrGiven = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* buggy input? r is not a repetition coefficient */
|
||||
if (!here->ISRCcoeffs || here->ISRCfunctionOrder < 2) {
|
||||
here->ISRCrGiven = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
here->ISRCr = value->rValue;
|
||||
here->ISRCrGiven = TRUE;
|
||||
|
||||
for (i = 0; i < here->ISRCfunctionOrder; i += 2) {
|
||||
here->ISRCrBreakpt = i;
|
||||
if (here->ISRCr == *(here->ISRCcoeffs + i))
|
||||
break;
|
||||
}
|
||||
|
||||
end_time = *(here->ISRCcoeffs + here->ISRCfunctionOrder - 2);
|
||||
if (here->ISRCr >= end_time) {
|
||||
fprintf(stderr, "ERROR: repeat start time value %g for pwl voltage source must be smaller than final time point given!\n", here->ISRCr);
|
||||
return (E_PARMVAL);
|
||||
}
|
||||
|
||||
if (here->ISRCr != *(here->ISRCcoeffs + here->ISRCrBreakpt)) {
|
||||
fprintf(stderr, "ERROR: repeat start time value %g for pwl voltage source does not match any time point given!\n", here->ISRCr);
|
||||
return (E_PARMVAL);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ISRC_SFFM:
|
||||
if(value->v.numValue < 2)
|
||||
return(E_BADPARM);
|
||||
|
|
|
|||
Loading…
Reference in New Issue