Add instance parameters td anr to the ISRC pwl source,

like has been available with voltage source VSRC.
This commit is contained in:
Holger Vogt 2026-04-29 13:34:22 +02:00
parent a0af7065a8
commit 2a246632bb
5 changed files with 159 additions and 8 deletions

View File

@ -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")
};

View File

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

View File

@ -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,
};

View File

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

View File

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