angefangene vsrc baustelle
wip, versuch eines PWL vsrc rewrites
This commit is contained in:
parent
a8619e1756
commit
53a0963632
|
|
@ -165,22 +165,75 @@ VSRCaccept(CKTcircuit *ckt, GENmodel *inModel)
|
|||
break;
|
||||
|
||||
case PWL: {
|
||||
int i;
|
||||
if(ckt->CKTtime < *(here->VSRCcoeffs)) {
|
||||
double td = here->VSRCrdelay;
|
||||
double tp = here->VSRCrperiod;
|
||||
volatile double bp;
|
||||
|
||||
if (ckt->CKTtime < here->VSRCcoeffs [0] + td) {
|
||||
here->nxt = 0;
|
||||
here->rpt = 0;
|
||||
if(ckt->CKTbreak) {
|
||||
error = CKTsetBreak(ckt,*(here->VSRCcoeffs));
|
||||
error = CKTsetBreak(ckt, here->VSRCcoeffs [0] + td);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(i=0;i<(here->VSRCfunctionOrder/2)-1;i++) {
|
||||
if ( ckt->CKTbreak && AlmostEqualUlps(*(here->VSRCcoeffs+2*i), ckt->CKTtime, 3 ) ) {
|
||||
error = CKTsetBreak(ckt, *(here->VSRCcoeffs+2*i+2));
|
||||
if(error) return(error);
|
||||
goto bkptset;
|
||||
|
||||
/* check td + first >= 0 */
|
||||
|
||||
/*
|
||||
* Postition:
|
||||
* nxt = [0, order[
|
||||
* rpt = [0.. [
|
||||
* with
|
||||
* time == arr[nxt] + rpt*period + td
|
||||
*
|
||||
* (fixme, no thats inclusive see above)
|
||||
*
|
||||
* evtl ==order als Ende Kriterium, !!! must
|
||||
*/
|
||||
|
||||
/* (libc) Remainder Functions, `same sign ...' and magnitude ... */
|
||||
|
||||
#if 0
|
||||
if (repeat && (time > tstart))
|
||||
rest = tstart + fmod(time - tstart, period);
|
||||
else
|
||||
rest = time;
|
||||
#endif
|
||||
|
||||
if (!ckt->CKTbreak || here->nxt >= here->VSRCfunctionOrder)
|
||||
break;
|
||||
|
||||
bp = here->VSRCcoeffs[here->nxt] + td + (here->rpt * tp);
|
||||
|
||||
if (!AlmostEqualUlps(bp, ckt->CKTtime, 3))
|
||||
break;
|
||||
|
||||
for (;;) {
|
||||
volatile double t;
|
||||
|
||||
here->nxt += 2;
|
||||
if (here->nxt >= here->VSRCfunctionOrder) {
|
||||
if (!here->VSRCrGiven)
|
||||
break;
|
||||
here->nxt = here->VSRCrBreakpt;
|
||||
here->rpt++;
|
||||
}
|
||||
|
||||
t = here->VSRCcoeffs[here->nxt] + td + (here->rpt * tp);
|
||||
|
||||
/* CKTtime isn't exactly identical to bp, thus ... */
|
||||
if (t <= ckt->CKTtime || t <= bp)
|
||||
continue;
|
||||
|
||||
bp = t;
|
||||
error = CKTsetBreak(ckt, bp);
|
||||
if (error)
|
||||
return(error);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
/**** tansient noise routines:
|
||||
VNoi2 2 0 DC 0 TRNOISE(10n 0.5n 0 0n) : generate gaussian distributed noise
|
||||
|
|
@ -289,7 +342,6 @@ VSRCaccept(CKTcircuit *ckt, GENmodel *inModel)
|
|||
|
||||
} // switch
|
||||
} // if ... else
|
||||
bkptset: ;
|
||||
} // for
|
||||
} // for
|
||||
|
||||
|
|
|
|||
|
|
@ -52,9 +52,12 @@ typedef struct sVSRCinstance {
|
|||
|
||||
struct trnoise_state *VSRCtrnoise_state; /* transient noise */
|
||||
struct trrandom_state *VSRCtrrandom_state; /* transient random source */
|
||||
struct pwl_state *VSRC_state;
|
||||
|
||||
int nxt, rpt;
|
||||
double VSRCr; /* pwl repeat */
|
||||
double VSRCrdelay; /* pwl delay period */
|
||||
double VSRCrperiod;
|
||||
double *VSRCposIbrptr; /* pointer to sparse matrix element at
|
||||
* (positive node, branch equation) */
|
||||
double *VSRCnegIbrptr; /* pointer to sparse matrix element at
|
||||
|
|
@ -78,6 +81,15 @@ typedef struct sVSRCinstance {
|
|||
} VSRCinstance ;
|
||||
|
||||
|
||||
struct pwl_state
|
||||
{
|
||||
double *arr;
|
||||
int len;
|
||||
int position;
|
||||
int bpoint;
|
||||
};
|
||||
|
||||
|
||||
/* per model data */
|
||||
|
||||
typedef struct sVSRCmodel {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,55 @@ Modified: 2000 AlansFixes
|
|||
/* gtri - end - wbk - modify for supply ramping option */
|
||||
#endif
|
||||
|
||||
|
||||
static double
|
||||
pwl_state_get(struct pwl_state *this, double time)
|
||||
{
|
||||
for (;;) {
|
||||
|
||||
double t1 = this->arr[this->position + 0];
|
||||
double t2 = this->arr[this->position + 2];
|
||||
|
||||
double v1, v2;
|
||||
|
||||
if (time >= t2) {
|
||||
if (this->position+4 >= this->len)
|
||||
return this->arr[this->len-1];
|
||||
this->position += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (time < t1) {
|
||||
if (this->position == 0)
|
||||
return this->arr[1];
|
||||
this->position = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* invariant: t1 <= time < t2 ==> t1 != t2 */
|
||||
|
||||
v1 = this->arr[this->position + 1];
|
||||
v2 = this->arr[this->position + 3];
|
||||
|
||||
return v1 + ((v2-v1)/(t2-t1)) * (time - t1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pwl_state_init(struct pwl_state *this, VSRCinstance *here)
|
||||
{
|
||||
|
||||
this->len = here->VSRCfunctionOrder;
|
||||
this->arr = here->VSRCcoeffs;
|
||||
this->position = 0;
|
||||
this->bpoint = 0;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
int
|
||||
VSRCload(GENmodel *inModel, CKTcircuit *ckt)
|
||||
/* actually load the current value into the
|
||||
|
|
@ -289,45 +338,22 @@ VSRCload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
break;
|
||||
|
||||
case PWL: {
|
||||
int i = 0, num_repeat = 0, ii = 0;
|
||||
double foo, repeat_time = 0, end_time, breakpt_time, itime;
|
||||
|
||||
time -= here->VSRCrdelay;
|
||||
struct pwl_state *state;
|
||||
|
||||
if(time < *(here->VSRCcoeffs)) {
|
||||
foo = *(here->VSRCcoeffs + 1) ;
|
||||
value = foo;
|
||||
goto loadDone;
|
||||
if (!here->VSRC_state) {
|
||||
here->VSRC_state = TMALLOC(struct pwl_state, 1);
|
||||
pwl_state_init((struct pwl_state *) here->VSRC_state, here);
|
||||
}
|
||||
|
||||
do {
|
||||
for(i=ii ; i<(here->VSRCfunctionOrder/2)-1; i++ ) {
|
||||
itime = *(here->VSRCcoeffs+2*i);
|
||||
if ( AlmostEqualUlps(itime+repeat_time, time, 3 )) {
|
||||
foo = *(here->VSRCcoeffs+2*i+1);
|
||||
value = foo;
|
||||
goto loadDone;
|
||||
} else if ( (*(here->VSRCcoeffs+2*i)+repeat_time < time)
|
||||
&& (*(here->VSRCcoeffs+2*(i+1))+repeat_time > time) ) {
|
||||
foo = *(here->VSRCcoeffs+2*i+1) + (((time-(*(here->VSRCcoeffs+2*i)+repeat_time))/
|
||||
(*(here->VSRCcoeffs+2*(i+1)) - *(here->VSRCcoeffs+2*i))) *
|
||||
(*(here->VSRCcoeffs+2*i+3) - *(here->VSRCcoeffs+2*i+1)));
|
||||
value = foo;
|
||||
goto loadDone;
|
||||
}
|
||||
}
|
||||
foo = *(here->VSRCcoeffs+ here->VSRCfunctionOrder-1) ;
|
||||
value = foo;
|
||||
state = (struct pwl_state *) here -> VSRC_state;
|
||||
|
||||
if ( !here->VSRCrGiven ) goto loadDone;
|
||||
/* fixme repeat value ignored */
|
||||
value = pwl_state_get(state, time - here->VSRCrdelay);
|
||||
|
||||
end_time = *(here->VSRCcoeffs + here->VSRCfunctionOrder-2);
|
||||
breakpt_time = *(here->VSRCcoeffs + here->VSRCrBreakpt);
|
||||
repeat_time = end_time + (end_time - breakpt_time)*num_repeat++ - breakpt_time;
|
||||
ii = here->VSRCrBreakpt/2;
|
||||
} while ( here->VSRCrGiven );
|
||||
break;
|
||||
goto loadDone;
|
||||
}
|
||||
break;
|
||||
|
||||
/**** tansient noise routines:
|
||||
VNoi2 2 0 DC 0 TRNOISE(10n 0.5n 0 0n) : generate gaussian distributed noise
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ VSRCparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
|
|||
copy_coeffs(here, value);
|
||||
|
||||
for (i=0; i<(here->VSRCfunctionOrder/2)-1; i++) {
|
||||
/* fixme identical soll erlaubt werden */
|
||||
if (*(here->VSRCcoeffs+2*(i+1))<=*(here->VSRCcoeffs+2*i)) {
|
||||
fprintf(stderr, "Warning : voltage source %s",
|
||||
here->VSRCname);
|
||||
|
|
@ -129,6 +130,7 @@ VSRCparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
|
|||
}
|
||||
|
||||
end_time = *(here->VSRCcoeffs + here->VSRCfunctionOrder-2);
|
||||
/* actually ok, würde stationaer bedeuten ... und ist so gut wie no repeat */
|
||||
if ( here->VSRCr > end_time ) {
|
||||
fprintf(stderr, "ERROR: repeat start time value %g for pwl voltage source must be smaller than final time point given!\n", here->VSRCr );
|
||||
return ( E_PARMVAL );
|
||||
|
|
@ -139,8 +141,9 @@ VSRCparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
|
|||
return ( E_PARMVAL );
|
||||
}
|
||||
|
||||
break;
|
||||
here ->VSRCrperiod = end_time - here->VSRCcoeffs[here->VSRCrBreakpt];
|
||||
}
|
||||
break;
|
||||
|
||||
case VSRC_SFFM:
|
||||
if(value->v.numValue < 2)
|
||||
|
|
|
|||
Loading…
Reference in New Issue