From b1e1c0343000d6c5d2fab1572f22a36fcc968d66 Mon Sep 17 00:00:00 2001 From: h_vogt Date: Sun, 12 Dec 2010 12:27:51 +0000 Subject: [PATCH] sichere Breakpoints bei TRNOISE --- ChangeLog | 4 ++ src/spicelib/devices/vsrc/vsrcacct.c | 67 +++++++++++++--------------- 2 files changed, 36 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4b2fa783a..a3ce7b6cc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-12-12 Holger Vogt + * vsrcacct.c: Patch von R. Larice für sichere Breakpoints + bei TRNOISE + 2010-12-11 Robert Larice * src/include/bool.h : Change bool from `unsigned char' to `int' diff --git a/src/spicelib/devices/vsrc/vsrcacct.c b/src/spicelib/devices/vsrc/vsrcacct.c index 7d6243398..18897d286 100644 --- a/src/spicelib/devices/vsrc/vsrcacct.c +++ b/src/spicelib/devices/vsrc/vsrcacct.c @@ -193,44 +193,41 @@ VNoi1 1 0 DC 0 TRNOISE(0n 0.5n 1 10n) : generate 1/f noise 0, time step, exponent < 2, rms value */ case TRNOISE: { - double NA, NT, TS, time, basetime = 0.; + double NA, NT, NALPHA, NAMP, TS; -#define NSAMETIME(a,b) (fabs((a)-(b))<= NTIMETOL * TS) -#define NTIMETOL 1e-7 + NA = here->VSRCcoeffs[0]; // input is rms value + NT = here->VSRCcoeffs[1]; // time step - NA = here->VSRCcoeffs[0]; // input is rms value - NT = here->VSRCcoeffs[1]; // time step - if (NT == 0.) // no further breakpoint if value not given - break; -// TS = NT > ckt->CKTstep ? NT : ckt->CKTstep; - TS = NT; - time = ckt->CKTtime; + NALPHA = here->VSRCfunctionOrder > 2 + ? here->VSRCcoeffs[2] : 0.0; + NAMP = here->VSRCfunctionOrder > 3 + && here->VSRCcoeffs[3] != 0.0 + && here->VSRCcoeffs[2] != 0.0 + ? here->VSRCcoeffs[3] : 0.0; - if(time >= TS) { - /* repeating signal - figure out where we are - in period */ - basetime = TS * floor(time*1.000000000001/TS); -// basetime = TS * floor(time/TS); -// basetime = TS * here->VSRCncount; - time -= basetime; - } - if(ckt->CKTbreak && NSAMETIME(time,0)) { - /* set next breakpoint */ -// error = CKTsetBreak(ckt, TS * ((double)here->VSRCncount + 1.)); - error = CKTsetBreak(ckt, basetime + TS); - if(error) return(error); - } - /* else if (ckt->CKTbreak && NSAMETIME(time,TS)) { - // set next breakpoint - error = CKTsetBreak(ckt, basetime + TS + TS); - if(error) return(error); - } */ - if (ckt->CKTtime == 0.) { -// printf("VSRC: free fft tables\n"); - fftFree(); - } - } - break; + if ((NT == 0.) || ((NA == 0.) && (NAMP == 0.))) // no further breakpoint if value not given + break; + TS = NT; + + if(ckt->CKTbreak) { + + int n = (int) floor(ckt->CKTtime / TS + 0.5); + volatile double nearest = n * TS; + + if(AlmostEqualUlps(nearest, ckt->CKTtime, 3)) { + /* carefull calculate `next' + * make sure it is really identical + * with the next calculated `nearest' value + */ + volatile double next = (n+1) * TS; + error = CKTsetBreak(ckt, next); + if(error) + return(error); + } + } + } + break; + } } bkptset: ;