From 1f6c4d633894a12f5bb571755bb6de4e7e052ec8 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 3 Oct 2020 10:20:28 +0200 Subject: [PATCH] Add a new code model pswitch, behaviour directly compatible to PSPICE (rounded corner at cntl_on) --- src/xspice/icm/xtradev/modpath.lst | 1 + src/xspice/icm/xtradev/pswitch/cfunc.mod | 262 ++++++++++++++++++++++ src/xspice/icm/xtradev/pswitch/ifspec.ifs | 83 +++++++ visualc/xspice/xtradev.vcxproj | 4 + 4 files changed, 350 insertions(+) create mode 100644 src/xspice/icm/xtradev/pswitch/cfunc.mod create mode 100644 src/xspice/icm/xtradev/pswitch/ifspec.ifs diff --git a/src/xspice/icm/xtradev/modpath.lst b/src/xspice/icm/xtradev/modpath.lst index 4e30d11f6..ec7a2f87f 100644 --- a/src/xspice/icm/xtradev/modpath.lst +++ b/src/xspice/icm/xtradev/modpath.lst @@ -9,3 +9,4 @@ potentiometer zener memristor sidiode +pswitch diff --git a/src/xspice/icm/xtradev/pswitch/cfunc.mod b/src/xspice/icm/xtradev/pswitch/cfunc.mod new file mode 100644 index 000000000..e8d552b04 --- /dev/null +++ b/src/xspice/icm/xtradev/pswitch/cfunc.mod @@ -0,0 +1,262 @@ +/*.......1.........2.........3.........4.........5.........6.........7.........8 +================================================================================ + +FILE pswitch/cfunc.mod + +3-Clause BSD + +Copyright 2020 The ngspice team + + +AUTHORS + + 27 September 2020 Holger Vogt + + +MODIFICATIONS + + +SUMMARY + + This file contains the functional description of the pswitch + code model. + + +INTERFACES + + FILE ROUTINE CALLED + + CMmacros.h cm_message_send(); + + +REFERENCED FILES + + Inputs from and outputs to ARGS structure. + + +NON-STANDARD FEATURES + + NONE + +===============================================================================*/ + +/*=== INCLUDE FILES ====================*/ + +#include + + + +/*=== CONSTANTS ========================*/ + + + + +/*=== MACROS ===========================*/ + + + + +/*=== LOCAL VARIABLES & TYPEDEFS =======*/ + +typedef struct { + + double logmean; /* log-mean of resistor values */ + double logratio; /* log-ratio of resistor values */ + double cntl_mean; /* mean of control values */ + double cntl_diff; /* diff of control values */ + double intermediate; /* intermediate value used to calculate + the resistance of the switch when the + controlling voltage is between cntl_on + and cntl_of */ + double c1; /* some constants */ + double c2; + double c3; +} Local_Data_t; + + +/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ + +static void +cm_pswitch_callback(ARGS, Mif_Callback_Reason_t reason) +{ + switch (reason) { + case MIF_CB_DESTROY: { + Local_Data_t *loc = STATIC_VAR (locdata); + free(loc); + break; + } + } +} + + + + + + +/*============================================================================== + +FUNCTION cm_pswitch() + +AUTHORS + + 27 September 2020 Holger Vogt + +MODIFICATIONS + +SUMMARY + + This function implements the pswitch code model. + +INTERFACES + + FILE ROUTINE CALLED + + CMmacros.h cm_message_send(); + +RETURNED VALUE + + Returns inputs and outputs via ARGS structure. + +GLOBAL VARIABLES + + NONE + +NON-STANDARD FEATURES + + NONE + +==============================================================================*/ + +/*=== CM_PSWITCH ROUTINE ===*/ + + + +void cm_pswitch(ARGS) /* structure holding parms, + inputs, outputs, etc. */ +{ + double cntl_on; /* voltage above which switch come on */ + double cntl_off; /* voltage below the switch has resistance roff */ + double r_on; /* on resistance */ + double r_off; /* off resistance */ + double logmean; /* log-mean of resistor values */ + double logratio; /* log-ratio of resistor values */ + double cntl_mean; /* mean of control values */ + double cntl_diff; /* diff of control values */ + double intermediate; /* intermediate value used to calculate + the resistance of the switch when the + controlling voltage is between cntl_on + and cntl_of */ + double r; /* value of the resistance of the switch */ + double pi_pvout; /* partial of the output wrt input */ + double pi_pcntl; /* partial of the output wrt control input */ + + Mif_Complex_t ac_gain; + + char *cntl_error = "\n*****ERROR*****\nPSWITCH: CONTROL voltage delta less than 1.0e-12\n"; + + Local_Data_t *loc; /* Pointer to local static data, not to be included + in the state vector */ + + + /* Retrieve frequently used parameters... */ + + cntl_on = PARAM(cntl_on); + cntl_off = PARAM(cntl_off); + r_on = PARAM(r_on); + r_off = PARAM(r_off); + + if( r_on < 1.0e-3 ) r_on = 1.0e-3; /* Set minimum 'ON' resistance */ + + if( (fabs(cntl_on - cntl_off) < 1.0e-12) ) { + cm_message_send(cntl_error); + return; + } + + if(INIT == 1) { /* first time through, allocate memory, set static parameters */ + /*** allocate static storage for *loc ***/ + STATIC_VAR (locdata) = calloc (1 , sizeof ( Local_Data_t )); + loc = STATIC_VAR (locdata); + + if ( PARAM(log) == MIF_TRUE ) { /* Logarithmic Variation in 'R' */ + loc->logmean = log(sqrt(r_on * r_off)); + loc->logratio = log(r_on / r_off); + loc->cntl_mean = (cntl_on + cntl_off) / 2.; + loc->cntl_diff = cntl_on - cntl_off; + loc->intermediate = loc->logratio / loc->cntl_diff; + loc->c1 = 1.5 * loc->logratio / loc->cntl_diff; + loc->c3 = 2. * loc->logratio / pow(loc->cntl_diff, 3); + loc->c2 = 3 * loc->c3; + } else { + loc->cntl_diff = cntl_on - cntl_off; + loc->intermediate = (r_on - r_off) / (cntl_on - cntl_off); + } + } + + loc = STATIC_VAR (locdata); + + if ( PARAM(log) == MIF_TRUE ) { /* Logarithmic Variation in 'R' */ + logmean = loc->logmean; + logratio = loc->logratio; + cntl_mean = loc->cntl_mean; + cntl_diff = loc->cntl_diff; + intermediate = loc->intermediate; + double inmean = INPUT(cntl_in) - cntl_mean; + if (cntl_on >= cntl_off) { + if (INPUT(cntl_in) >= cntl_on) { + r = r_on; + } + else if (INPUT(cntl_in) <= cntl_off) { + r = r_off; + } + else { + r = exp(logmean + 3 * logratio * inmean / (2 * cntl_diff) - loc->c3 * pow(inmean, 3)); + if(r= cntl_off) { + r = r_off; + } + else { + r = exp(logmean + 3 * logratio * inmean / (2 * cntl_diff) - loc->c3 * pow(inmean, 3)); +// r = exp(logmean + 3 * logratio * (INPUT(cntl_in) - cntl_mean) / (2 * cntl_diff) - 2 * logratio * pow((INPUT(cntl_in) - cntl_mean), 3) / pow(cntl_diff, 3)); + if(rc2 * inmean * inmean - loc->c1 * INPUT(cntl_in)); + pi_pvout = 1.0 / r; + + } + else { /* Linear Variation in 'R' */ + intermediate = loc->intermediate; + cntl_diff = loc->cntl_diff; + r = INPUT(cntl_in) * intermediate + ((r_off*cntl_on - + r_on*cntl_off) / cntl_diff); + if(r<=1.0e-9) r=1.0e-9;/* minimum resistance limiter */ + pi_pvout = 1.0 / r; + pi_pcntl = -intermediate * INPUT(out) / (r*r); + } + + if(ANALYSIS != MIF_AC) { /* Output DC & Transient Values */ + OUTPUT(out) = INPUT(out) / r; +// PARTIAL(out,out) = pi_pvout; +// PARTIAL(out,cntl_in) = pi_pcntl; + cm_analog_auto_partial(); + + /* Note that the minus signs are required because current is positive + flowing INTO rather than OUT OF a component node. */ + } + else { /* Output AC Gain Values */ + ac_gain.real = -pi_pvout; /* See comment on minus signs above... */ + ac_gain.imag= 0.0; + AC_GAIN(out,out) = ac_gain; + + ac_gain.real = -pi_pcntl; + ac_gain.imag= 0.0; + AC_GAIN(out,cntl_in) = ac_gain; + } +} + diff --git a/src/xspice/icm/xtradev/pswitch/ifspec.ifs b/src/xspice/icm/xtradev/pswitch/ifspec.ifs new file mode 100644 index 000000000..29a285d6f --- /dev/null +++ b/src/xspice/icm/xtradev/pswitch/ifspec.ifs @@ -0,0 +1,83 @@ +/*.......1.........2.........3.........4.........5.........6.........7.........8 +================================================================================ +3-Clause BSD + +Copyright 2020 The ngspice team + + +AUTHORS + + 27 September 2020 Holger Vogt + + +SUMMARY + + This file contains the interface specification file for the + analog pswitch code model. + +===============================================================================*/ + +NAME_TABLE: + + +C_Function_Name: cm_pswitch +Spice_Model_Name: pswitch +Description: "analog PSPICE compatible switch" + + +PORT_TABLE: + + +Port_Name: cntl_in out +Description: "input" "resistive output" +Direction: in inout +Default_Type: v gd +Allowed_Types: [v,vd,i,id,vnam] [gd] +Vector: no no +Vector_Bounds: - - +Null_Allowed: no no + + +PARAMETER_TABLE: + + +Parameter_Name: cntl_off cntl_on +Description: "control 'off' val" "control 'on' val" +Data_Type: real real +Default_Value: 0.0 1.0 +Limits: - - +Vector: no no +Vector_Bounds: - - +Null_Allowed: yes yes + + +PARAMETER_TABLE: + +Parameter_Name: log r_off +Description: "Log-linear switch" "off resistance" +Data_Type: boolean real +Default_Value: TRUE 1.0e12 +Limits: - - +Vector: no no +Vector_Bounds: - - +Null_Allowed: yes yes + + + +PARAMETER_TABLE: + +Parameter_Name: r_on +Description: "on resistance" +Data_Type: real +Default_Value: 1.0 +Limits: - +Vector: no +Vector_Bounds: - +Null_Allowed: yes + + +STATIC_VAR_TABLE: + +Static_Var_Name: locdata +Description: "local static data" +Data_Type: pointer diff --git a/visualc/xspice/xtradev.vcxproj b/visualc/xspice/xtradev.vcxproj index 3ff05ff78..608ced1ac 100644 --- a/visualc/xspice/xtradev.vcxproj +++ b/visualc/xspice/xtradev.vcxproj @@ -220,6 +220,8 @@ ..\..\src\xspice\%(RelativeDir);%(AdditionalIncludeDirectories) + + @@ -257,6 +259,8 @@ + +