diff --git a/src/xspice/icm/analog/pwl/cfunc.mod b/src/xspice/icm/analog/pwl/cfunc.mod index 1fa7136cf..2bcfb4b01 100644 --- a/src/xspice/icm/analog/pwl/cfunc.mod +++ b/src/xspice/icm/analog/pwl/cfunc.mod @@ -8,18 +8,18 @@ Public Domain Georgia Tech Research Corporation Atlanta, Georgia 30332 PROJECT A-8503-405 - -AUTHORS + +AUTHORS 19 Apr 1991 Jeffrey P. Murray -MODIFICATIONS +MODIFICATIONS 25 Sep 1991 Jeffrey P. Murray 2 Oct 1991 Jeffrey P. Murray - + 1 Nov 2020 Holger Vogt SUMMARY @@ -27,21 +27,21 @@ SUMMARY functionally describe the pwl (piece-wise linear) code model. -INTERFACES +INTERFACES - FILE ROUTINE CALLED + FILE ROUTINE CALLED - CMutil.c void cm_smooth_corner(); + CMutil.c void cm_smooth_corner(); + + CMmacros.h cm_message_send(); - CMmacros.h cm_message_send(); - CM.c void cm_analog_not_converged() REFERENCED FILES Inputs from and outputs to ARGS structure. - + NON-STANDARD FEATURES @@ -53,7 +53,7 @@ NON-STANDARD FEATURES #include - + /*=== CONSTANTS ========================*/ @@ -66,53 +66,53 @@ NON-STANDARD FEATURES - -/*=== LOCAL VARIABLES & TYPEDEFS =======*/ + +/*=== LOCAL VARIABLES & TYPEDEFS =======*/ + + - - /*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ - + /*============================================================================== FUNCTION double limit_x_value() -AUTHORS +AUTHORS 25 Sep 1991 Jeffrey P. Murray -MODIFICATIONS +MODIFICATIONS 2 Oct 1991 Jeffrey P. Murray SUMMARY - Limits a passed input value to some fraction - of the segment length defined by - (x_upper - x_lower). The fractional value in - question is passed as a value to the routine - (fraction). - + Limits a passed input value to some fraction + of the segment length defined by + (x_upper - x_lower). The fractional value in + question is passed as a value to the routine + (fraction). -INTERFACES - FILE ROUTINE CALLED +INTERFACES + + FILE ROUTINE CALLED CM.c void cm_analog_not_converged() RETURNED VALUE - + Returns a double. GLOBAL VARIABLES - + NONE NON-STANDARD FEATURES @@ -124,7 +124,7 @@ NON-STANDARD FEATURES #include /*=== Static LIMIT_X_VALUE ROUTINE ================*/ - + /** limit_x_value ******************************************/ /** **/ /** Limits a passed input value to some fraction **/ @@ -136,24 +136,24 @@ NON-STANDARD FEATURES /** 9/25/91 JPM **/ /***********************************************************/ -static double limit_x_value(double x_lower,double x_upper, - double x_input,double fraction, +static double limit_x_value(double x_lower,double x_upper, + double x_input,double fraction, double *last_x_value) { - double max_x_delta, /* maximum delta value permissible for + double max_x_delta, /* maximum delta value permissible for this segment domain. */ - hold; /* Holding variable for previous x_input value */ + hold; /* Holding variable for previous x_input value */ /** Limit effective change of input to fraction of value of lowest **/ - /** x-segment length... **/ + /** x-segment length... **/ /* calculate maximum delta value for this region */ max_x_delta = fraction * (x_upper - x_lower); /* Test new input */ if ( max_x_delta < fabs(x_input - *last_x_value) ) { - + hold = x_input; /* Assign new x_input based of direction of movement */ @@ -171,13 +171,13 @@ static double limit_x_value(double x_lower,double x_upper, /*** Debugging printf statement ***/ /* printf("Assigning new x_input...\nPrevious value=%e, New value=%e\n\n", hold,x_input); - */ + */ } else { /* No limiting of x_input required */ *last_x_value = x_input; } - + return x_input; } @@ -186,11 +186,11 @@ static double limit_x_value(double x_lower,double x_upper, FUNCTION void cm_pwl(> -AUTHORS +AUTHORS 19 Apr 1991 Jeffrey P. Murray -MODIFICATIONS +MODIFICATIONS 25 Sep 1991 Jeffrey P. Murray 2 Oct 1991 Jeffrey P. Murray @@ -199,23 +199,23 @@ SUMMARY This function implements the pwl code model. -INTERFACES +INTERFACES - FILE ROUTINE CALLED + FILE ROUTINE CALLED - CMutil.c void cm_smooth_corner(); + CMutil.c void cm_smooth_corner(); + + CMmacros.h cm_message_send(); - CMmacros.h cm_message_send(); - CM.c void cm_analog_not_converged() RETURNED VALUE - + Returns inputs and outputs via ARGS structure. GLOBAL VARIABLES - + NONE NON-STANDARD FEATURES @@ -230,14 +230,14 @@ cm_pwl_callback(ARGS, Mif_Callback_Reason_t reason) switch (reason) { case MIF_CB_DESTROY: { double *last_x_value = STATIC_VAR (last_x_value); - double *x = STATIC_VAR (x); - double *y = STATIC_VAR (y); + double *x = STATIC_VAR (x); + double *y = STATIC_VAR (y); free(last_x_value); free(x); free(y); STATIC_VAR (last_x_value) = NULL; STATIC_VAR (x) = NULL; - STATIC_VAR (y) = NULL; + STATIC_VAR (y) = NULL; break; } } @@ -245,7 +245,7 @@ cm_pwl_callback(ARGS, Mif_Callback_Reason_t reason) /*=== CM_PWL ROUTINE ================*/ -void cm_pwl(ARGS) /* structure holding parms, +void cm_pwl(ARGS) /* structure holding parms, inputs, outputs, etc. */ { int i; /* generic loop counter index */ @@ -281,11 +281,17 @@ void cm_pwl(ARGS) /* structure holding parms, input_domain = PARAM(input_domain); - size = PARAM_SIZE(x_array); + /* size including space for two additional x,y pairs */ + size = PARAM_SIZE(x_array) + 2; - - if (INIT==1) { /* First pass...allocate storage for previous value... */ + /* First pass: + Allocate storage for previous value. + Allocate storage for x an y input arrays + Read input array and store from + Add additional x,y pair at beginning and end of x, y arrays: + */ + if (INIT==1) { /* Allocate storage for last_x_value */ STATIC_VAR(last_x_value) = (double *) malloc(sizeof(double)); @@ -295,22 +301,41 @@ void cm_pwl(ARGS) /* structure holding parms, STATIC_VAR(x) = (double *) calloc((size_t) size, sizeof(double)); x = (double *) STATIC_VAR(x); if (!x) { - cm_message_send(allocation_error); + cm_message_send(allocation_error); } STATIC_VAR(y) = (double *) calloc((size_t) size, sizeof(double)); y = (double *) STATIC_VAR(y); if (!y) { - cm_message_send(allocation_error); + cm_message_send(allocation_error); } - /* Retrieve x and y values. */ - for (i=0; i= x[0] ) { x_input = *last_x_value = x[0]; /* Alert the simulator to non-convergence */ cm_analog_not_converged(); - } + } else { x_input = *last_x_value = test; } } - else + else if ( *last_x_value >= x[size-1] ) { /** Non-Limited input greater than x[size-1] **/ /* Obtain the test value of the input, if it has changed excessively */ @@ -391,7 +416,7 @@ void cm_pwl(ARGS) /* structure holding parms, else { test = limit_x_value(x[size-2],x[size-1],x_input,FRACTION,last_x_value); } - + /* If the test value is less than x[size-1], force to x[size-1] */ /* minus some epsilon value. */ if ( test < x[size-1] ) { @@ -399,7 +424,7 @@ void cm_pwl(ARGS) /* structure holding parms, /* Alert the simulator to non-convergence */ cm_analog_not_converged(); - } + } else { x_input = *last_x_value = test; } @@ -407,10 +432,10 @@ void cm_pwl(ARGS) /* structure holding parms, else { for (i=1; i x[i] ) { x_input = *last_x_value = x[i]; @@ -419,8 +444,8 @@ void cm_pwl(ARGS) /* structure holding parms, cm_analog_not_converged(); break; - } - else + } + else /* If the test value is less than x[i-1], force to x[i-1] */ /* minus some epsilon value... */ if ( test < x[i-1] ) { @@ -432,7 +457,7 @@ void cm_pwl(ARGS) /* structure holding parms, break; } else { /* Use returned value for next input */ - x_input = *last_x_value = test; + x_input = *last_x_value = test; break; } } @@ -440,9 +465,9 @@ void cm_pwl(ARGS) /* structure holding parms, } /* Assign new limited value back to the input for */ - /* use in the matrix calculations.... */ - INPUT(in) = x_input; - + /* use in the matrix calculations.... */ + INPUT(in) = x_input; + /*** Add debugging printf statement ***/ /* printf("Limited x_input=%e\n\n", @@ -450,7 +475,7 @@ void cm_pwl(ARGS) /* structure holding parms, */ - /**** End internal limiting ****/ + /**** End internal limiting ****/ @@ -459,13 +484,13 @@ void cm_pwl(ARGS) /* structure holding parms, if (x_input <= (x[0] + x[1])/2.0) {/*** x_input below lowest midpoint ***/ dout_din = (y[1] - y[0])/(x[1] - x[0]); - + /* Compute new output */ out = y[0] + (x_input - x[0]) * dout_din; - + } else { - if (x_input >= (x[size-2] + x[size-1])/2.0) { + if (x_input >= (x[size-2] + x[size-1])/2.0) { /*** x_input above highest midpoint ***/ dout_din = (y[size-1] - y[size-2]) / (x[size-1] - x[size-2]); @@ -477,10 +502,10 @@ void cm_pwl(ARGS) /* structure holding parms, /*** calculate required output. ***/ for (i=1; i