Browse Source

xspice, analog/file_source, bug fix

The source code did not consider the possibility
  of more than one "tran" analysis invocations.

see "Bewildering problem with filesource block while sweeping"
https://sourceforge.net/p/ngspice/discussion/133842/thread/52949e23/
pre-master-46
mhx 9 years ago
committed by rlar
parent
commit
5f0f54761a
  1. 30
      src/xspice/icm/analog/file_source/cfunc.mod

30
src/xspice/icm/analog/file_source/cfunc.mod

@ -12,6 +12,7 @@ AUTHORS
20 May 2011 Thomas Sailer
03 Sep 2012 Holger Vogt
27 Feb 2017 Marcel Hendrix
MODIFICATIONS
@ -71,7 +72,6 @@ NON-STANDARD FEATURES
struct filesource_state {
FILE *fp;
long pos;
unsigned char atend;
};
@ -107,6 +107,7 @@ AUTHORS
MODIFICATIONS
07 Sept 2012 Holger Vogt
27 Feb 2017 Marcel Hendrix
SUMMARY
@ -139,7 +140,7 @@ NON-STANDARD FEATURES
void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc. */
{
int size;
int size = PORT_SIZE(out);
int amplscalesize;
int amploffssize;
@ -149,7 +150,6 @@ void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc.
if(ANALYSIS == MIF_AC) {
return;
}
size = PORT_SIZE(out);
if (INIT == 1) {
int i;
@ -167,7 +167,6 @@ void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc.
for (i = 0; i < size; ++i)
loc->amplinterval[2 * i] = loc->amplinterval[2 * i + 1] = PARAM_NULL(amploffset) ? 0.0 : PARAM(amploffset[i]);
loc->state->fp = fopen_with_path(PARAM(file), "r");
loc->state->pos = 0;
loc->state->atend = 0;
if (!loc->state->fp) {
char *lbuffer, *p;
@ -188,22 +187,31 @@ void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc.
amplscalesize = PARAM_NULL(amplscale) ? 0 : PARAM_SIZE(amplscale);
amploffssize = PARAM_NULL(amploffset) ? 0 : PARAM_SIZE(amploffset);
loc = STATIC_VAR (locdata);
/* The file pointer is at the same position it was for the last simulator TIME ...
* If TIME steps backward, for example due to a second invocation of a 'tran' analysis
* then we need to rewind the file to start from the beginning.
*/
if (TIME < loc->timeinterval[0]) {
rewind(loc->state->fp);
loc->timeinterval[0] = loc->timeinterval[1] = PARAM_NULL(timeoffset) ? 0.0 : PARAM(timeoffset);
}
while (TIME >= loc->timeinterval[1] && !loc->state->atend) {
char line[512];
char *cp, *cpdel;
char *cp2;
double t;
int i;
if (ftell(loc->state->fp) != loc->state->pos) {
clearerr(loc->state->fp);
fseek(loc->state->fp, loc->state->pos, SEEK_SET);
}
if (!fgets(line, sizeof(line), loc->state->fp)) {
loc->state->atend = 1;
break;
}
loc->state->pos = ftell(loc->state->fp);
cpdel = cp = strdup(line);
/* read the time channel; update the time difference */
while (*cp && isspace_c(*cp))
++cp;
if (*cp == '#' || *cp == ';') {
@ -224,6 +232,8 @@ void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc.
t += PARAM(timeoffset);
loc->timeinterval[0] = loc->timeinterval[1];
loc->timeinterval[1] = t;
/* read the channels; update the amplitude difference of each channel */
for (i = 0; i < size; ++i)
loc->amplinterval[2 * i] = loc->amplinterval[2 * i + 1];
for (i = 0; i < size; ++i) {
@ -241,7 +251,7 @@ void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc.
}
free(cpdel);
}
if (TIME < loc->timeinterval[1] && loc->timeinterval[0] < loc->timeinterval[1] && 0.0 <= loc->timeinterval[0]) {
if (!loc->state->atend && loc->timeinterval[0] <= TIME && TIME <= loc->timeinterval[1]) {
if (!PARAM_NULL(amplstep) && PARAM(amplstep) == MIF_TRUE) {
int i;
for (i = 0; i < size; ++i)

Loading…
Cancel
Save