diff --git a/src/xspice/icm/digital/d_source/cfunc.mod b/src/xspice/icm/digital/d_source/cfunc.mod index 9042b2d36..a9c866c2a 100644 --- a/src/xspice/icm/digital/d_source/cfunc.mod +++ b/src/xspice/icm/digital/d_source/cfunc.mod @@ -79,23 +79,24 @@ NON-STANDARD FEATURES /*=== LOCAL VARIABLES & TYPEDEFS =======*/ typedef struct { - int index, /* current index into source tables */ - width, /* width of table...equal to size of out port */ + int width, /* width of table...equal to size of out port */ depth; /* depth of table...equal to size of "timepoints" array, and to the total number of vectors retrieved from the source.in file. */ + double *all_timepoints; /* the storage array for the timepoints, as read from file. This will have size equal to "depth" */ - char **all_bits; /* the storage array for the + char **all_data; /* the storage array for the output bit representations; as read from file. This will have size equal - to width*depth, one char will hold a + to width*depth, one short will hold a 12-state bit description. */ -} Source_Table_Info_t; + +} Local_Data_t; /* Type definition for each possible token returned. */ @@ -596,7 +597,7 @@ MODIFICATIONS SUMMARY - Retrieves a char per bit value from the array "all_bits". + Retrieves a char per bit value from the array "all_data". INTERFACES @@ -623,17 +624,17 @@ NON-STANDARD FEATURES /************************************************ * The following routine retrieves a bit * -* from all_bits and stores them in out * +* from all_data and stores them in out * * * * Created 8/19/12 H. Vogt * ************************************************/ -static void cm_get_source_value(int row, int bit_number, char **all_bits, Digital_t *out) +static void cm_get_source_value(int row, int bit_number, char **all_data, Digital_t *out) { char val; - val = all_bits[row][bit_number]; + val = all_data[row][bit_number]; cm_source_retrieve(val,out); @@ -669,7 +670,7 @@ INTERFACES RETURNED VALUE - Returns output bits stored in "all_bits" array, + Returns output bits stored in "all_data" array, time values in "all_timepoints" array, return != 0 code if error. @@ -695,8 +696,7 @@ NON-STANDARD FEATURES * Created 7/15/91 J.P.Murray * **************************************************/ -static int cm_read_source(FILE *source,char **all_bits,double *all_timepoints, - Source_Table_Info_t *info) +static int cm_read_source(FILE *source, Local_Data_t *loc) { size_t n; /* loop index */ int i, /* indexing variable */ @@ -744,7 +744,7 @@ static int cm_read_source(FILE *source,char **all_bits,double *all_timepoints, num_tokens = j; /* If this number is incorrect, return with an error */ - if ( (info->width + 2) != num_tokens) { + if ( (loc->width + 2) != num_tokens) { return 2; } @@ -752,13 +752,13 @@ static int cm_read_source(FILE *source,char **all_bits,double *all_timepoints, s = base_address; /* set storage space for bits in a row and set them to 0*/ - all_bits[i] = (char*)malloc(sizeof(char) * info->width); - for (n = 0; n < (unsigned int)info->width; n++) - all_bits[i][n] = 0; + loc->all_data[i] = (char*)malloc(sizeof(char) * loc->width); + for (n = 0; n < (unsigned int)loc->width; n++) + loc->all_data[i][n] = 0; /** Retrieve each token, analyze, and **/ /** store the timepoint and bit information **/ - for (j=0; j<(info->width + 1); j++) { + for (j=0; j<(loc->width + 1); j++) { token = CNVget_token(&s, &type); @@ -767,7 +767,7 @@ static int cm_read_source(FILE *source,char **all_bits,double *all_timepoints, /* convert to a floating point number... */ cnv_get_spice_value(token,&number); - all_timepoints[i] = number; + loc->all_timepoints[i] = number; /* provided this is not the first timepoint @@ -777,7 +777,7 @@ static int cm_read_source(FILE *source,char **all_bits,double *all_timepoints, /* if current timepoint value is not greater than the previous value, then return with an error message... */ - if ( all_timepoints[i] <= all_timepoints[i-1] ) { + if ( loc->all_timepoints[i] <= loc->all_timepoints[i-1] ) { return 3; } } @@ -805,8 +805,8 @@ static int cm_read_source(FILE *source,char **all_bits,double *all_timepoints, if (12 == bit_value) { return 4; } - else { /* need to store this value in the all_bits[] array */ - all_bits[i][j-1] = bit_value; + else { /* need to store this value in the all_data[] array */ + loc->all_data[i][j-1] = bit_value; } } if (token) @@ -882,6 +882,7 @@ void cm_d_source(ARGS) int i, /* generic loop counter index */ err; /* integer for storage of error status */ +/**** the state variables, memory allocation with cm_event_alloc *****/ char *bits, /* the storage array for the output bit representations... this will have size equal to width, @@ -889,28 +890,24 @@ void cm_d_source(ARGS) bit description. */ *bits_old; /* the storage array for old bit values */ + int *row_index, /* current index into source tables */ + *row_index_old; /* previous index into source tables */ + double *timepoint, /* the storage array for the timepoints, a single point */ *timepoint_old; /* the storage for the old timepoint */ +/*********************************************************************/ volatile double /* enforce 64 bit precision, (equality comparison) */ test_double; /* test variable for doubles */ - - FILE *source; /* pointer to the source.in input vector file */ - Source_Table_Info_t *info, /* storage location for source - index and depth info. */ - *info_old; /* storage location for old info */ - - Digital_t out; /* storage for each output bit */ - char temp[MAX_STRING_SIZE], /* holding string variable for testing input from source.in */ *s; /* main string variable */ @@ -918,9 +915,11 @@ void cm_d_source(ARGS) char *loading_error = "\nERROR **\n D_SOURCE: source.in file was not read successfully. \n"; + Local_Data_t *loc; /* Pointer to local static data, not to be included + in the state vector (save memory!) */ - - /**** Setup required state variables ****/ + /**** Setup required local and state variables ****/ + /* local data will be setup once during INIT and never change again */ if(INIT) { /* initial pass */ @@ -958,52 +957,44 @@ void cm_d_source(ARGS) } } + /*** allocate static storage for *loc ***/ + STATIC_VAR (locdata) = calloc (1 , sizeof ( Local_Data_t )); + loc = STATIC_VAR (locdata); - /*** allocate storage for *index, *bits & *timepoints ***/ + /*** allocate storage for *index, *bits & *timepoint ***/ - cm_event_alloc(0,sizeof(Source_Table_Info_t)); + cm_event_alloc(0, sizeof(int)); cm_event_alloc(1, PORT_SIZE(out) * (int) sizeof(char)); cm_event_alloc(2, (int) sizeof(double)); /**** Get all pointers again (to avoid realloc problems) ****/ - info = info_old = (Source_Table_Info_t *) cm_event_get_ptr(0,0); + row_index = row_index_old = (int *) cm_event_get_ptr(0,0); bits = bits_old = (char *) cm_event_get_ptr(1,0); timepoint = timepoint_old = (double *) cm_event_get_ptr(2,0); /* Initialize info values... */ - info->index = 0; - info->depth = i; + *row_index = 0; + loc->depth = i; /* Retrieve width of the source */ - info->width = PORT_SIZE(out); - - - /*** allocate storage for **all_bits, & *all_timepoints ***/ - info->all_timepoints = (double*)malloc(i * sizeof(double)); - info->all_bits = (char**)malloc(i * sizeof(char*)); - - - /* Initialize *bits & *timepoints to zero */ - for (i=0; iwidth; i++) - bits[i] = 0; - for (i=0; idepth; i++) - info->all_timepoints[i] = 0.0; - - + loc->width = PORT_SIZE(out); + /*** allocate storage for **all_data, & *all_timepoints ***/ + loc->all_timepoints = (double*)calloc(i, sizeof(double)); + loc->all_data = (char**)calloc(i, sizeof(char*)); /* Send file pointer and the two array storage pointers */ /* to "cm_read_source()". This will return after */ /* reading the contents of source.in, and if no */ - /* errors have occurred, the "*all_bits" and "*all_timepoints" */ + /* errors have occurred, the "*all_data" and "*all_timepoints" */ /* vectors will be loaded and the width and depth */ /* values supplied. */ if (source) { rewind(source); - err = cm_read_source(source,info->all_bits,info->all_timepoints,info); + err = cm_read_source(source, loc); } else { err=1; } @@ -1011,9 +1002,6 @@ void cm_d_source(ARGS) if (err) { /* problem occurred in load...send error msg. */ cm_message_send(loading_error); - /* Reset *bits & *timepoints to zero */ - for (i=0; iwidth; i++) bits[i] = 0; - for (i=0; idepth; i++) info->all_timepoints[i] = 0; switch (err) { case 2: @@ -1037,13 +1025,13 @@ void cm_d_source(ARGS) else { /*** Retrieve previous values ***/ /** Retrieve info... **/ - info = (Source_Table_Info_t *) cm_event_get_ptr(0,0); - info_old = (Source_Table_Info_t *) cm_event_get_ptr(0,1); + row_index = (int *) cm_event_get_ptr(0,0); + row_index_old = (int *) cm_event_get_ptr(0,1); + + loc = STATIC_VAR (locdata); /* Set old values to new... */ - info->index = info_old->index; - info->depth = info_old->depth; - info->width = info_old->width; + *row_index = *row_index_old; /** Retrieve bits... **/ bits = (char *) cm_event_get_ptr(1,0); @@ -1063,31 +1051,31 @@ void cm_d_source(ARGS) if ( 0.0 == TIME ) { - test_double = info->all_timepoints[info->index]; - if ( 0.0 == test_double && info->depth > 0 ) { /* Set DC value */ + test_double = loc->all_timepoints[*row_index]; + if ( 0.0 == test_double && loc->depth > 0 ) { /* Set DC value */ /* reset current breakpoint */ - test_double = info->all_timepoints[info->index]; + test_double = loc->all_timepoints[*row_index]; cm_event_queue( test_double ); /* Output new values... */ - for (i=0; iwidth; i++) { + for (i=0; iwidth; i++) { /* retrieve output value */ - cm_get_source_value(info->index, i, info->all_bits, &out); + cm_get_source_value(*row_index, i, loc->all_data, &out); OUTPUT_STATE(out[i]) = out.state; OUTPUT_STRENGTH(out[i]) = out.strength; } /* increment breakpoint */ - (info->index)++; + (*row_index)++; /* set next breakpoint as long as depth has not been exceeded */ - if ( info->index < info->depth ) { - test_double = info->all_timepoints[info->index] - 1.0e-10; + if ( *row_index < loc->depth ) { + test_double = loc->all_timepoints[*row_index] - 1.0e-10; cm_event_queue( test_double ); } @@ -1096,11 +1084,11 @@ void cm_d_source(ARGS) /* set next breakpoint as long as depth has not been exceeded */ - if ( info->index < info->depth ) { - test_double = info->all_timepoints[info->index] - 1.0e-10; + if ( *row_index < loc->depth ) { + test_double = loc->all_timepoints[*row_index] - 1.0e-10; cm_event_queue( test_double ); } - for(i=0; iwidth; i++) { + for(i=0; iwidth; i++) { OUTPUT_STATE(out[i]) = UNKNOWN; OUTPUT_STRENGTH(out[i]) = UNDETERMINED; } @@ -1112,17 +1100,17 @@ void cm_d_source(ARGS) *** routine based on the last breakpoint's relationship *** *** to the current time value. ***/ - test_double = info->all_timepoints[info->index] - 1.0e-10; + test_double = loc->all_timepoints[*row_index] - 1.0e-10; if ( TIME < test_double ) { /* Breakpoint has not occurred */ /** Output hasn't changed...do nothing this time. **/ - for (i=0; iwidth; i++) { + for (i=0; iwidth; i++) { OUTPUT_CHANGED(out[i]) = FALSE; } - if ( info->index < info->depth ) { - test_double = info->all_timepoints[info->index] - 1.0e-10; + if ( *row_index < loc->depth ) { + test_double = loc->all_timepoints[*row_index] - 1.0e-10; cm_event_queue( test_double ); } @@ -1132,14 +1120,14 @@ void cm_d_source(ARGS) if ( TIME == test_double ) { /* Breakpoint reached */ /* reset current breakpoint */ - test_double = info->all_timepoints[info->index] - 1.0e-10; + test_double = loc->all_timepoints[*row_index] - 1.0e-10; cm_event_queue( test_double ); /* Output new values... */ - for (i=0; iwidth; i++) { + for (i=0; iwidth; i++) { /* retrieve output value */ - cm_get_source_value(info->index, i , info->all_bits, &out); + cm_get_source_value(*row_index, i , loc->all_data, &out); OUTPUT_STATE(out[i]) = out.state; OUTPUT_DELAY(out[i]) = 1.0e-10; @@ -1147,12 +1135,12 @@ void cm_d_source(ARGS) } /* increment breakpoint */ - (info->index)++; + (*row_index)++; /* set next breakpoint as long as depth has not been exceeded */ - if ( info->index < info->depth ) { - test_double = info->all_timepoints[info->index] - 1.0e-10; + if ( *row_index < loc->depth ) { + test_double = loc->all_timepoints[*row_index] - 1.0e-10; cm_event_queue( test_double ); } } @@ -1160,7 +1148,7 @@ void cm_d_source(ARGS) else { /* Last source file breakpoint has been exceeded... do not change the value of the output */ - for (i=0; iwidth; i++) { + for (i=0; iwidth; i++) { OUTPUT_CHANGED(out[i]) = FALSE; } } diff --git a/src/xspice/icm/digital/d_source/ifspec.ifs b/src/xspice/icm/digital/d_source/ifspec.ifs index 744b544e1..bc91adc8f 100644 --- a/src/xspice/icm/digital/d_source/ifspec.ifs +++ b/src/xspice/icm/digital/d_source/ifspec.ifs @@ -19,7 +19,6 @@ SUMMARY NAME_TABLE: - C_Function_Name: cm_d_source Spice_Model_Name: d_source Description: "digital signal source" @@ -27,7 +26,6 @@ Description: "digital signal source" PORT_TABLE: - Port_Name: out Description: "output" Direction: out @@ -41,7 +39,6 @@ Null_Allowed: no PARAMETER_TABLE: - Parameter_Name: input_file Description: "digital input vector filename" Data_Type: string @@ -54,7 +51,6 @@ Null_Allowed: no PARAMETER_TABLE: - Parameter_Name: input_load Description: "input loading capacitance (F)" Data_Type: real @@ -62,4 +58,11 @@ Default_Value: 1.0e-12 Limits: - Vector: no Vector_Bounds: - -Null_Allowed: no +Null_Allowed: no + + +STATIC_VAR_TABLE: + +Static_Var_Name: locdata +Description: "local static data" +Data_Type: pointer