From 1d026475a2dab67c8e532ff035f67830f20bffcd Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 9 Sep 2022 15:24:37 +0200 Subject: [PATCH] pwlts: a pwl v/i source with time input, smoothing and limiting functions --- src/xspice/icm/analog/modpath.lst | 1 + src/xspice/icm/analog/pwlts/cfunc.mod | 342 +++++++++++++++++++++++++ src/xspice/icm/analog/pwlts/ifspec.ifs | 92 +++++++ visualc/xspice/analog.vcxproj | 4 +- 4 files changed, 438 insertions(+), 1 deletion(-) create mode 100644 src/xspice/icm/analog/pwlts/cfunc.mod create mode 100644 src/xspice/icm/analog/pwlts/ifspec.ifs diff --git a/src/xspice/icm/analog/modpath.lst b/src/xspice/icm/analog/modpath.lst index 834054af6..481162718 100644 --- a/src/xspice/icm/analog/modpath.lst +++ b/src/xspice/icm/analog/modpath.lst @@ -18,3 +18,4 @@ s_xfer triangle file_source delay +pwlts diff --git a/src/xspice/icm/analog/pwlts/cfunc.mod b/src/xspice/icm/analog/pwlts/cfunc.mod new file mode 100644 index 000000000..45d74b4d6 --- /dev/null +++ b/src/xspice/icm/analog/pwlts/cfunc.mod @@ -0,0 +1,342 @@ +/*.......1.........2.........3.........4.........5.........6.........7.........8 +================================================================================ + +FILE pwlts/cfunc.mod + +Public Domain + + +AUTHORS + + Original author of pwl + 19 Apr 1991 Jeffrey P. Murray + +Pwl with time input and smoothing: pwlts + 9 Sep 2022 Holger Vogt + +SUMMARY + + This file contains the model-specific routines used to + functionally describe the pwlts (piece-wise linear time based) code model. + + +INTERFACES + + FILE ROUTINE CALLED + + CMutil.c void cm_smooth_corner(); + + CMmacros.h cm_message_send(); + + +REFERENCED FILES + + Inputs from and outputs to ARGS structure. + + +NON-STANDARD FEATURES + + NONE + +===============================================================================*/ + +/*=== INCLUDE FILES ====================*/ + +#include + + + +/*=== CONSTANTS ========================*/ + +#define FRACTION 0.30 +#define EPSILON 1.0e-9 + + + +/*=== MACROS ===========================*/ + + + + +/*=== LOCAL VARIABLES & TYPEDEFS =======*/ + + + + +/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ + + + +#include + + +/*============================================================================== + +FUNCTION void cm_pwlts + +AUTHORS + + 9 Sep 2022 Holger Vogt + +MODIFICATIONS + + +SUMMARY + + This function implements the pwlts code model. + +INTERFACES + + FILE ROUTINE CALLED + + CMutil.c void cm_smooth_corner(); + + CMmacros.h cm_message_send(); + + +RETURNED VALUE + + Returns outputs via ARGS structure. + +GLOBAL VARIABLES + + NONE + +NON-STANDARD FEATURES + + NONE + +==============================================================================*/ + +static void +cm_pwlts_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); + if (last_x_value) + free(last_x_value); + if (x) + free(x); + if (y) + free(y); + STATIC_VAR (last_x_value) = NULL; + STATIC_VAR (x) = NULL; + STATIC_VAR (y) = NULL; + break; + } + } +} + +/*=== CM_PWLTS ROUTINE ================*/ + +void cm_pwlts(ARGS) /* structure holding parms, + inputs, outputs, etc. */ +{ + int i; /* generic loop counter index */ + int size; /* size of the x_array */ + + double input_domain; /* smoothing range */ + double *x; /* pointer to the x-coordinate array */ + double *y; /* pointer to the y-coordinate array */ + double lower_seg; /* x segment below which input resides */ + double upper_seg; /* x segment above which the input resides */ + double lower_slope; /* slope of the lower segment */ + double upper_slope; /* slope of the upper segment */ + double x_input; /* input */ + double out = 0.0; /* output + * Init to 0 to suppress compiler warning */ + double dout_din = 0.0; /* partial derivative of the output wrt input. + * Init to 0 to suppress compiler warning */ + double threshold_lower; /* value below which the output begins smoothing */ + double threshold_upper; /* value above which the output begins smoothing */ + double test1; /* debug testing value */ + double test2; /* debug testing value */ + double *last_x_value; /* static variable for limiting */ + double test; /* temp storage variable for limit testing */ + + Mif_Complex_t ac_gain; + + CALLBACK = cm_pwlts_callback; + + char *allocation_error="\n***ERROR***\nPWL: Allocation calloc failed!\n"; + char *limit_error="\n***ERROR***\nPWL: Violation of 50% rule in breakpoints!\n"; + + /* Retrieve frequently used parameters... */ + + input_domain = PARAM(input_domain); + + /* size including space for two additional x,y pairs */ + size = PARAM_SIZE(x_array) + 2; + + + /* 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)); + last_x_value = (double *) STATIC_VAR(last_x_value); + + /* Allocate storage for breakpoint domain & range values */ + STATIC_VAR(x) = (double *) calloc((size_t) size, sizeof(double)); + x = (double *) STATIC_VAR(x); + if (!x) { + 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); + } + + /* Retrieve x and y values. */ + for (i=1; i= (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]); + + out = y[size-1] + (x_input - x[size-1]) * dout_din; + } + else { /*** x_input within bounds of end midpoints... ***/ + /*** must determine position progressively & then ***/ + /*** calculate required output. ***/ + + for (i=1; i..\..\src\xspice\%(RelativeDir);%(AdditionalIncludeDirectories) + + @@ -302,4 +304,4 @@ - + \ No newline at end of file