diff --git a/src/xspice/icm/digital/d_pwm/cfunc.mod b/src/xspice/icm/digital/d_pwm/cfunc.mod index af6e323c8..e64d6efcd 100644 --- a/src/xspice/icm/digital/d_pwm/cfunc.mod +++ b/src/xspice/icm/digital/d_pwm/cfunc.mod @@ -19,7 +19,7 @@ MODIFICATIONS 23 Aug 1991 Jeffrey P. Murray 30 Sep 1991 Jeffrey P. Murray - + 06 Oct 2022 Holger Vogt SUMMARY @@ -69,7 +69,10 @@ NON-STANDARD FEATURES /*=== LOCAL VARIABLES & TYPEDEFS =======*/ - +typedef struct { + double *x; + double *y; +} Local_Data_t; /*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ @@ -120,6 +123,27 @@ NON-STANDARD FEATURES ==============================================================================*/ +static void cm_d_pwm_callback(ARGS, + Mif_Callback_Reason_t reason) +{ + switch (reason) { + case MIF_CB_DESTROY: { + Local_Data_t *loc = STATIC_VAR(locdata); + if (loc) { + if (loc->x) + free(loc->x); + if(loc->y) + free(loc->y); + free(loc); + STATIC_VAR(locdata) = loc = NULL; + } + break; + } /* end of case MIF_CB_DESTROY */ + } /* end of switch over reason being called */ +} /* end of function cm_d_pwm_callback */ + + + /*=== CM_D_PWM ROUTINE ===*/ /************************************************************* @@ -179,15 +203,12 @@ void cm_d_pwm(ARGS) slope; /* slope value...used to extrapolate freq values past endpoints. */ - int i, /* generic loop counter index */ cntl_size, /* control array size */ dc_size; /* duty cycle array size */ - - - - + Local_Data_t *loc; /* Pointer to local static data, not to be included + in the state vector (save memory!) */ /**** Retrieve frequently used parameters... ****/ @@ -195,7 +216,6 @@ void cm_d_pwm(ARGS) dc_size = PARAM_SIZE(dc_array); frequency = PARAM(frequency); - /* check and make sure that the control array is the same size as the frequency array */ @@ -204,10 +224,8 @@ void cm_d_pwm(ARGS) return; } - if (INIT) { /*** Test for INIT == TRUE. If so, allocate storage, etc. ***/ - /* Allocate storage for internal variables */ cm_analog_alloc(0, sizeof(double)); cm_analog_alloc(1, sizeof(double)); @@ -220,15 +238,35 @@ void cm_d_pwm(ARGS) t3 = (double *) cm_analog_get_ptr(2,0); + /*** allocate static storage for *loc ***/ + STATIC_VAR (locdata) = calloc (1 , sizeof ( Local_Data_t )); + loc = STATIC_VAR (locdata); + CALLBACK = cm_d_pwm_callback; + + x = loc->x = (double *) calloc((size_t) cntl_size, sizeof(double)); + if (!x) { + cm_message_send(d_pwm_allocation_error); + return; + } + y = loc->y = (double *) calloc((size_t) cntl_size, sizeof(double)); + if (!y) { + cm_message_send(d_pwm_allocation_error); + if(x) + free(x); + return; + } + /* Retrieve x and y values. */ + for (i=0; ix; + y = loc->y; /* Retrieve cntl_input value. */ cntl_input = INPUT(cntl_in); @@ -346,7 +358,6 @@ void cm_d_pwm(ARGS) // cm_message_send(d_pwm_positive_dc_error); } - /* calculate the instantaneous phase */ *phase = *phase_old + frequency * (TIME - T(1)); @@ -354,7 +365,6 @@ void cm_d_pwm(ARGS) the period */ dphase = *phase_old - floor(*phase_old); - /* Calculate the time variables and the output value for this iteration */ @@ -365,8 +375,6 @@ void cm_d_pwm(ARGS) if(TIME < *t3) { cm_event_queue(*t3); } - - } else @@ -380,7 +388,6 @@ void cm_d_pwm(ARGS) if(TIME < *t1) { cm_event_queue(*t1); - } } else { @@ -395,23 +402,12 @@ void cm_d_pwm(ARGS) } *t3 = T(1) + (1 - dphase)/frequency; - - } - - - - if(x) free(x); - if(y) free(y); - - } break; - case EVENT: /** discrete call...lots to do **/ - test_double = TIME; if ( 0.0 == TIME ) { /* DC analysis...preset values, @@ -424,7 +420,6 @@ void cm_d_pwm(ARGS) } *phase = *phase / 360.0; - /* set phase value to init_phase */ *phase_old = *phase; @@ -433,16 +428,12 @@ void cm_d_pwm(ARGS) *t3 = -1; } - - /* Calculate the time variables and the output value for this iteration */ /* Output is always set to STRONG */ OUTPUT_STRENGTH(out) = STRONG; - - if( *t1 == TIME ) { /* rising edge */ OUTPUT_STATE(out) = ONE; @@ -471,9 +462,7 @@ void cm_d_pwm(ARGS) } } } - break; - } } diff --git a/src/xspice/icm/digital/d_pwm/ifspec.ifs b/src/xspice/icm/digital/d_pwm/ifspec.ifs index da6ed4da3..cde238f16 100644 --- a/src/xspice/icm/digital/d_pwm/ifspec.ifs +++ b/src/xspice/icm/digital/d_pwm/ifspec.ifs @@ -75,3 +75,9 @@ Vector: no no Vector_Bounds: - - Null_Allowed: yes yes + +STATIC_VAR_TABLE: + +Static_Var_Name: locdata +Description: "local static data" +Data_Type: pointer