Browse Source

XSPICE filesource: remove segfault with op before tran

h_vogt 14 years ago
parent
commit
5ce51f148e
  1. 268
      src/xspice/icm/analog/file_source/cfunc.mod
  2. 7
      src/xspice/icm/analog/file_source/ifspec.ifs

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

@ -11,6 +11,7 @@ Thomas Sailer
AUTHORS
20 May 2011 Thomas Sailer
03 Sep 2012 Holger Vogt
MODIFICATIONS
@ -19,7 +20,8 @@ MODIFICATIONS
SUMMARY
This file contains the model-specific routines used to
functionally describe the gain code model.
functionally describe the file source code model used
to read an array of analog values per time step from a file.
INTERFACES
@ -55,18 +57,38 @@ NON-STANDARD FEATURES
/*=== MACROS ===========================*/
#if defined(__MINGW32__) || defined(_MSC_VER)
#define DIR_PATHSEP "\\"
#define DIR_PATHSEP "\\"
#else
#define DIR_PATHSEP "/"
#define DIR_PATHSEP "/"
#endif
#if defined(_MSC_VER)
#define strdup _strdup
#define snprintf _snprintf
#endif
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
struct filesource_state {
FILE *fp;
long pos;
unsigned char atend;
FILE *fp;
long pos;
unsigned char atend;
};
typedef struct {
double *amplinterval; /* the storage array for the
amplitude offsets */
double *timeinterval; /* the storage array for the
time offset */
struct filesource_state *state; /* the storage array for the
filesource status. */
} Local_Data_t;
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
@ -76,19 +98,19 @@ struct filesource_state {
/*==============================================================================
FUNCTION void cm_gain()
FUNCTION void cm_filesource()
AUTHORS
2 Oct 1991 Jeffrey P. Murray
20 May 2011 Thomas Sailer
MODIFICATIONS
NONE
07 Sept 2012 Holger Vogt
SUMMARY
This function implements the gain code model.
This function implements the filesource code model.
INTERFACES
@ -117,121 +139,125 @@ NON-STANDARD FEATURES
void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc. */
{
int size;
int amplscalesize;
int amploffssize;
double *timeinterval;
double *amplinterval;
struct filesource_state *state;
if(ANALYSIS == MIF_AC) {
return;
}
size = PORT_SIZE(out);
if (INIT == 1) {
/* Allocate storage for internal state */
cm_analog_alloc(0, 2 * sizeof(double));
cm_analog_alloc(1, size * (int) (2 * sizeof(double)));
cm_analog_alloc(2, sizeof(struct filesource_state));
}
timeinterval = (double *)cm_analog_get_ptr(0, 0);
amplinterval = (double *)cm_analog_get_ptr(1, 0);
state = (struct filesource_state *)cm_analog_get_ptr(2, 0);
if (INIT == 1) {
int i;
timeinterval[0] = timeinterval[1] = PARAM_NULL(timeoffset) ? 0.0 : PARAM(timeoffset);
for (i = 0; i < size; ++i)
amplinterval[2 * i] = amplinterval[2 * i + 1] = PARAM_NULL(amploffset) ? 0.0 : PARAM(amploffset[i]);
state->fp = fopen(PARAM(file), "r");
state->pos = 0;
state->atend = 0;
if (!state->fp) {
char *lbuffer, *p;
int size;
int amplscalesize;
int amploffssize;
Local_Data_t *loc; /* Pointer to local static data, not to be included
in the state vector */
if(ANALYSIS == MIF_AC) {
return;
}
size = PORT_SIZE(out);
if (INIT == 1) {
int i;
/*** allocate static storage for *loc ***/
STATIC_VAR (locdata) = calloc (1 , sizeof ( Local_Data_t ));
loc = STATIC_VAR (locdata);
/* Allocate storage for internal state */
loc->timeinterval = (double*)calloc(2, sizeof(double));
loc->amplinterval = (double*)calloc(2 * size, sizeof(double));
loc->state = (struct filesource_state*)malloc(sizeof(struct filesource_state));
loc->timeinterval[0] = loc->timeinterval[1] = PARAM_NULL(timeoffset) ? 0.0 : PARAM(timeoffset);
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(PARAM(file), "r");
loc->state->pos = 0;
loc->state->atend = 0;
if (!loc->state->fp) {
char *lbuffer, *p;
lbuffer = getenv("NGSPICE_INPUT_DIR");
if (lbuffer && *lbuffer) {
p = (char*) malloc(strlen(lbuffer) + strlen(DIR_PATHSEP) + strlen(PARAM(file)) + 1);
sprintf(p, "%s%s%s", lbuffer, DIR_PATHSEP, PARAM(file));
state->fp = fopen(p, "r");
loc->state->fp = fopen(p, "r");
free(p);
}
if (!state->fp) {
char msg[512];
snprintf(msg, sizeof(msg), "cannot open file %s", PARAM(file));
cm_message_send(msg);
state->atend = 1;
}
}
}
amplscalesize = PARAM_NULL(amplscale) ? 0 : PARAM_SIZE(amplscale);
amploffssize = PARAM_NULL(amploffset) ? 0 : PARAM_SIZE(amploffset);
while (TIME >= timeinterval[1] && !state->atend) {
char line[512];
char *cp, *cpdel;
char *cp2;
double t;
int i;
if (ftell(state->fp) != state->pos) {
clearerr(state->fp);
fseek(state->fp, state->pos, SEEK_SET);
}
if (!fgets(line, sizeof(line), state->fp)) {
state->atend = 1;
break;
}
state->pos = ftell(state->fp);
cpdel = cp = strdup(line);
while (*cp && isspace(*cp))
++cp;
if (*cp == '#' || *cp == ';') {
free(cpdel);
continue;
}
t = strtod(cp, &cp2);
if (cp2 == cp) {
free(cpdel);
continue;
}
cp = cp2;
if (!PARAM_NULL(timescale))
t *= PARAM(timescale);
if (!PARAM_NULL(timerelative) && PARAM(timerelative) == MIF_TRUE)
t += timeinterval[1];
else if (!PARAM_NULL(timeoffset))
t += PARAM(timeoffset);
timeinterval[0] = timeinterval[1];
timeinterval[1] = t;
for (i = 0; i < size; ++i)
amplinterval[2 * i] = amplinterval[2 * i + 1];
for (i = 0; i < size; ++i) {
while (*cp && (isspace(*cp) || *cp == ','))
++cp;
t = strtod(cp, &cp2);
if (cp2 == cp)
break;
cp = cp2;
if (i < amplscalesize)
t *= PARAM(amplscale[i]);
if (i < amploffssize)
t += PARAM(amploffset[i]);
amplinterval[2 * i + 1] = t;
}
free(cpdel);
}
if (TIME < timeinterval[1] && timeinterval[0] < timeinterval[1] && 0.0 <= timeinterval[0]) {
if (!PARAM_NULL(amplstep) && PARAM(amplstep) == MIF_TRUE) {
int i;
for (i = 0; i < size; ++i)
OUTPUT(out[i]) = amplinterval[2 * i];
} else {
double mul0 = (timeinterval[1] - TIME) / (timeinterval[1] - timeinterval[0]);
double mul1 = 1.0 - mul0;
int i;
for (i = 0; i < size; ++i)
OUTPUT(out[i]) = mul0 * amplinterval[2 * i] + mul1 * amplinterval[2 * i + 1];
}
} else {
int i;
for (i = 0; i < size; ++i)
OUTPUT(out[i]) = amplinterval[2 * i + 1];
}
if (!loc->state->fp) {
char msg[512];
snprintf(msg, sizeof(msg), "cannot open file %s", PARAM(file));
cm_message_send(msg);
loc->state->atend = 1;
}
}
}
amplscalesize = PARAM_NULL(amplscale) ? 0 : PARAM_SIZE(amplscale);
amploffssize = PARAM_NULL(amploffset) ? 0 : PARAM_SIZE(amploffset);
loc = STATIC_VAR (locdata);
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);
while (*cp && isspace(*cp))
++cp;
if (*cp == '#' || *cp == ';') {
free(cpdel);
continue;
}
t = strtod(cp, &cp2);
if (cp2 == cp) {
free(cpdel);
continue;
}
cp = cp2;
if (!PARAM_NULL(timescale))
t *= PARAM(timescale);
if (!PARAM_NULL(timerelative) && PARAM(timerelative) == MIF_TRUE)
t += loc->timeinterval[1];
else if (!PARAM_NULL(timeoffset))
t += PARAM(timeoffset);
loc->timeinterval[0] = loc->timeinterval[1];
loc->timeinterval[1] = t;
for (i = 0; i < size; ++i)
loc->amplinterval[2 * i] = loc->amplinterval[2 * i + 1];
for (i = 0; i < size; ++i) {
while (*cp && (isspace(*cp) || *cp == ','))
++cp;
t = strtod(cp, &cp2);
if (cp2 == cp)
break;
cp = cp2;
if (i < amplscalesize)
t *= PARAM(amplscale[i]);
if (i < amploffssize)
t += PARAM(amploffset[i]);
loc->amplinterval[2 * i + 1] = t;
}
free(cpdel);
}
if (TIME < loc->timeinterval[1] && loc->timeinterval[0] < loc->timeinterval[1] && 0.0 <= loc->timeinterval[0]) {
if (!PARAM_NULL(amplstep) && PARAM(amplstep) == MIF_TRUE) {
int i;
for (i = 0; i < size; ++i)
OUTPUT(out[i]) = loc->amplinterval[2 * i];
} else {
double mul0 = (loc->timeinterval[1] - TIME) / (loc->timeinterval[1] - loc->timeinterval[0]);
double mul1 = 1.0 - mul0;
int i;
for (i = 0; i < size; ++i)
OUTPUT(out[i]) = mul0 * loc->amplinterval[2 * i] + mul1 * loc->amplinterval[2 * i + 1];
}
} else {
int i;
for (i = 0; i < size; ++i)
OUTPUT(out[i]) = loc->amplinterval[2 * i + 1];
}
}

7
src/xspice/icm/analog/file_source/ifspec.ifs

@ -80,3 +80,10 @@ Limits: -
Vector: no
Vector_Bounds: -
Null_Allowed: yes
STATIC_VAR_TABLE:
Static_Var_Name: locdata
Description: "local static data"
Data_Type: pointer
Loading…
Cancel
Save