XSPICE filesource: remove segfault with op before tran
This commit is contained in:
parent
9de9336581
commit
5ce51f148e
|
|
@ -11,6 +11,7 @@ Thomas Sailer
|
||||||
AUTHORS
|
AUTHORS
|
||||||
|
|
||||||
20 May 2011 Thomas Sailer
|
20 May 2011 Thomas Sailer
|
||||||
|
03 Sep 2012 Holger Vogt
|
||||||
|
|
||||||
|
|
||||||
MODIFICATIONS
|
MODIFICATIONS
|
||||||
|
|
@ -19,7 +20,8 @@ MODIFICATIONS
|
||||||
SUMMARY
|
SUMMARY
|
||||||
|
|
||||||
This file contains the model-specific routines used to
|
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
|
INTERFACES
|
||||||
|
|
@ -55,18 +57,38 @@ NON-STANDARD FEATURES
|
||||||
/*=== MACROS ===========================*/
|
/*=== MACROS ===========================*/
|
||||||
|
|
||||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||||
#define DIR_PATHSEP "\\"
|
#define DIR_PATHSEP "\\"
|
||||||
#else
|
#else
|
||||||
#define DIR_PATHSEP "/"
|
#define DIR_PATHSEP "/"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define strdup _strdup
|
||||||
|
#define snprintf _snprintf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
|
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
|
||||||
|
|
||||||
struct filesource_state {
|
struct filesource_state {
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
long pos;
|
long pos;
|
||||||
unsigned char atend;
|
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 ===*/
|
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
|
||||||
|
|
||||||
|
|
@ -76,19 +98,19 @@ struct filesource_state {
|
||||||
|
|
||||||
/*==============================================================================
|
/*==============================================================================
|
||||||
|
|
||||||
FUNCTION void cm_gain()
|
FUNCTION void cm_filesource()
|
||||||
|
|
||||||
AUTHORS
|
AUTHORS
|
||||||
|
|
||||||
2 Oct 1991 Jeffrey P. Murray
|
20 May 2011 Thomas Sailer
|
||||||
|
|
||||||
MODIFICATIONS
|
MODIFICATIONS
|
||||||
|
|
||||||
NONE
|
07 Sept 2012 Holger Vogt
|
||||||
|
|
||||||
SUMMARY
|
SUMMARY
|
||||||
|
|
||||||
This function implements the gain code model.
|
This function implements the filesource code model.
|
||||||
|
|
||||||
INTERFACES
|
INTERFACES
|
||||||
|
|
||||||
|
|
@ -117,121 +139,125 @@ NON-STANDARD FEATURES
|
||||||
|
|
||||||
void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc. */
|
void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc. */
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
int amplscalesize;
|
int amplscalesize;
|
||||||
int amploffssize;
|
int amploffssize;
|
||||||
double *timeinterval;
|
|
||||||
double *amplinterval;
|
|
||||||
struct filesource_state *state;
|
|
||||||
|
|
||||||
if(ANALYSIS == MIF_AC) {
|
Local_Data_t *loc; /* Pointer to local static data, not to be included
|
||||||
return;
|
in the state vector */
|
||||||
}
|
|
||||||
size = PORT_SIZE(out);
|
if(ANALYSIS == MIF_AC) {
|
||||||
if (INIT == 1) {
|
return;
|
||||||
/* Allocate storage for internal state */
|
}
|
||||||
cm_analog_alloc(0, 2 * sizeof(double));
|
size = PORT_SIZE(out);
|
||||||
cm_analog_alloc(1, size * (int) (2 * sizeof(double)));
|
if (INIT == 1) {
|
||||||
cm_analog_alloc(2, sizeof(struct filesource_state));
|
|
||||||
}
|
int i;
|
||||||
timeinterval = (double *)cm_analog_get_ptr(0, 0);
|
|
||||||
amplinterval = (double *)cm_analog_get_ptr(1, 0);
|
/*** allocate static storage for *loc ***/
|
||||||
state = (struct filesource_state *)cm_analog_get_ptr(2, 0);
|
STATIC_VAR (locdata) = calloc (1 , sizeof ( Local_Data_t ));
|
||||||
if (INIT == 1) {
|
loc = STATIC_VAR (locdata);
|
||||||
int i;
|
|
||||||
timeinterval[0] = timeinterval[1] = PARAM_NULL(timeoffset) ? 0.0 : PARAM(timeoffset);
|
/* Allocate storage for internal state */
|
||||||
for (i = 0; i < size; ++i)
|
loc->timeinterval = (double*)calloc(2, sizeof(double));
|
||||||
amplinterval[2 * i] = amplinterval[2 * i + 1] = PARAM_NULL(amploffset) ? 0.0 : PARAM(amploffset[i]);
|
loc->amplinterval = (double*)calloc(2 * size, sizeof(double));
|
||||||
state->fp = fopen(PARAM(file), "r");
|
loc->state = (struct filesource_state*)malloc(sizeof(struct filesource_state));
|
||||||
state->pos = 0;
|
|
||||||
state->atend = 0;
|
loc->timeinterval[0] = loc->timeinterval[1] = PARAM_NULL(timeoffset) ? 0.0 : PARAM(timeoffset);
|
||||||
if (!state->fp) {
|
for (i = 0; i < size; ++i)
|
||||||
char *lbuffer, *p;
|
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");
|
lbuffer = getenv("NGSPICE_INPUT_DIR");
|
||||||
if (lbuffer && *lbuffer) {
|
if (lbuffer && *lbuffer) {
|
||||||
p = (char*) malloc(strlen(lbuffer) + strlen(DIR_PATHSEP) + strlen(PARAM(file)) + 1);
|
p = (char*) malloc(strlen(lbuffer) + strlen(DIR_PATHSEP) + strlen(PARAM(file)) + 1);
|
||||||
sprintf(p, "%s%s%s", lbuffer, DIR_PATHSEP, PARAM(file));
|
sprintf(p, "%s%s%s", lbuffer, DIR_PATHSEP, PARAM(file));
|
||||||
state->fp = fopen(p, "r");
|
loc->state->fp = fopen(p, "r");
|
||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
if (!state->fp) {
|
if (!loc->state->fp) {
|
||||||
char msg[512];
|
char msg[512];
|
||||||
snprintf(msg, sizeof(msg), "cannot open file %s", PARAM(file));
|
snprintf(msg, sizeof(msg), "cannot open file %s", PARAM(file));
|
||||||
cm_message_send(msg);
|
cm_message_send(msg);
|
||||||
state->atend = 1;
|
loc->state->atend = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
amplscalesize = PARAM_NULL(amplscale) ? 0 : PARAM_SIZE(amplscale);
|
|
||||||
amploffssize = PARAM_NULL(amploffset) ? 0 : PARAM_SIZE(amploffset);
|
amplscalesize = PARAM_NULL(amplscale) ? 0 : PARAM_SIZE(amplscale);
|
||||||
while (TIME >= timeinterval[1] && !state->atend) {
|
amploffssize = PARAM_NULL(amploffset) ? 0 : PARAM_SIZE(amploffset);
|
||||||
char line[512];
|
loc = STATIC_VAR (locdata);
|
||||||
char *cp, *cpdel;
|
while (TIME >= loc->timeinterval[1] && !loc->state->atend) {
|
||||||
char *cp2;
|
char line[512];
|
||||||
double t;
|
char *cp, *cpdel;
|
||||||
int i;
|
char *cp2;
|
||||||
if (ftell(state->fp) != state->pos) {
|
double t;
|
||||||
clearerr(state->fp);
|
int i;
|
||||||
fseek(state->fp, state->pos, SEEK_SET);
|
if (ftell(loc->state->fp) != loc->state->pos) {
|
||||||
}
|
clearerr(loc->state->fp);
|
||||||
if (!fgets(line, sizeof(line), state->fp)) {
|
fseek(loc->state->fp, loc->state->pos, SEEK_SET);
|
||||||
state->atend = 1;
|
}
|
||||||
break;
|
if (!fgets(line, sizeof(line), loc->state->fp)) {
|
||||||
}
|
loc->state->atend = 1;
|
||||||
state->pos = ftell(state->fp);
|
break;
|
||||||
cpdel = cp = strdup(line);
|
}
|
||||||
while (*cp && isspace(*cp))
|
loc->state->pos = ftell(loc->state->fp);
|
||||||
++cp;
|
cpdel = cp = strdup(line);
|
||||||
if (*cp == '#' || *cp == ';') {
|
while (*cp && isspace(*cp))
|
||||||
free(cpdel);
|
++cp;
|
||||||
continue;
|
if (*cp == '#' || *cp == ';') {
|
||||||
}
|
free(cpdel);
|
||||||
t = strtod(cp, &cp2);
|
continue;
|
||||||
if (cp2 == cp) {
|
}
|
||||||
free(cpdel);
|
t = strtod(cp, &cp2);
|
||||||
continue;
|
if (cp2 == cp) {
|
||||||
}
|
free(cpdel);
|
||||||
cp = cp2;
|
continue;
|
||||||
if (!PARAM_NULL(timescale))
|
}
|
||||||
t *= PARAM(timescale);
|
cp = cp2;
|
||||||
if (!PARAM_NULL(timerelative) && PARAM(timerelative) == MIF_TRUE)
|
if (!PARAM_NULL(timescale))
|
||||||
t += timeinterval[1];
|
t *= PARAM(timescale);
|
||||||
else if (!PARAM_NULL(timeoffset))
|
if (!PARAM_NULL(timerelative) && PARAM(timerelative) == MIF_TRUE)
|
||||||
t += PARAM(timeoffset);
|
t += loc->timeinterval[1];
|
||||||
timeinterval[0] = timeinterval[1];
|
else if (!PARAM_NULL(timeoffset))
|
||||||
timeinterval[1] = t;
|
t += PARAM(timeoffset);
|
||||||
for (i = 0; i < size; ++i)
|
loc->timeinterval[0] = loc->timeinterval[1];
|
||||||
amplinterval[2 * i] = amplinterval[2 * i + 1];
|
loc->timeinterval[1] = t;
|
||||||
for (i = 0; i < size; ++i) {
|
for (i = 0; i < size; ++i)
|
||||||
while (*cp && (isspace(*cp) || *cp == ','))
|
loc->amplinterval[2 * i] = loc->amplinterval[2 * i + 1];
|
||||||
++cp;
|
for (i = 0; i < size; ++i) {
|
||||||
t = strtod(cp, &cp2);
|
while (*cp && (isspace(*cp) || *cp == ','))
|
||||||
if (cp2 == cp)
|
++cp;
|
||||||
break;
|
t = strtod(cp, &cp2);
|
||||||
cp = cp2;
|
if (cp2 == cp)
|
||||||
if (i < amplscalesize)
|
break;
|
||||||
t *= PARAM(amplscale[i]);
|
cp = cp2;
|
||||||
if (i < amploffssize)
|
if (i < amplscalesize)
|
||||||
t += PARAM(amploffset[i]);
|
t *= PARAM(amplscale[i]);
|
||||||
amplinterval[2 * i + 1] = t;
|
if (i < amploffssize)
|
||||||
}
|
t += PARAM(amploffset[i]);
|
||||||
free(cpdel);
|
loc->amplinterval[2 * i + 1] = t;
|
||||||
}
|
}
|
||||||
if (TIME < timeinterval[1] && timeinterval[0] < timeinterval[1] && 0.0 <= timeinterval[0]) {
|
free(cpdel);
|
||||||
if (!PARAM_NULL(amplstep) && PARAM(amplstep) == MIF_TRUE) {
|
}
|
||||||
int i;
|
if (TIME < loc->timeinterval[1] && loc->timeinterval[0] < loc->timeinterval[1] && 0.0 <= loc->timeinterval[0]) {
|
||||||
for (i = 0; i < size; ++i)
|
if (!PARAM_NULL(amplstep) && PARAM(amplstep) == MIF_TRUE) {
|
||||||
OUTPUT(out[i]) = amplinterval[2 * i];
|
int i;
|
||||||
} else {
|
for (i = 0; i < size; ++i)
|
||||||
double mul0 = (timeinterval[1] - TIME) / (timeinterval[1] - timeinterval[0]);
|
OUTPUT(out[i]) = loc->amplinterval[2 * i];
|
||||||
double mul1 = 1.0 - mul0;
|
} else {
|
||||||
int i;
|
double mul0 = (loc->timeinterval[1] - TIME) / (loc->timeinterval[1] - loc->timeinterval[0]);
|
||||||
for (i = 0; i < size; ++i)
|
double mul1 = 1.0 - mul0;
|
||||||
OUTPUT(out[i]) = mul0 * amplinterval[2 * i] + mul1 * amplinterval[2 * i + 1];
|
int i;
|
||||||
}
|
for (i = 0; i < size; ++i)
|
||||||
} else {
|
OUTPUT(out[i]) = mul0 * loc->amplinterval[2 * i] + mul1 * loc->amplinterval[2 * i + 1];
|
||||||
int i;
|
}
|
||||||
for (i = 0; i < size; ++i)
|
} else {
|
||||||
OUTPUT(out[i]) = amplinterval[2 * i + 1];
|
int i;
|
||||||
}
|
for (i = 0; i < size; ++i)
|
||||||
|
OUTPUT(out[i]) = loc->amplinterval[2 * i + 1];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -80,3 +80,10 @@ Limits: -
|
||||||
Vector: no
|
Vector: no
|
||||||
Vector_Bounds: -
|
Vector_Bounds: -
|
||||||
Null_Allowed: yes
|
Null_Allowed: yes
|
||||||
|
|
||||||
|
|
||||||
|
STATIC_VAR_TABLE:
|
||||||
|
|
||||||
|
Static_Var_Name: locdata
|
||||||
|
Description: "local static data"
|
||||||
|
Data_Type: pointer
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue