diff --git a/examples/xspice/various/astate.cir b/examples/xspice/various/astate.cir new file mode 100644 index 000000000..ae4ec0070 --- /dev/null +++ b/examples/xspice/various/astate.cir @@ -0,0 +1,23 @@ +state test +* transient simulation only +* 0 <= astate_no <= 3 +* out delayed by astate_no accepted time steps +* current or voltage in- and outputs + +Vsin1 in 0 SIN (0 1.5 1k) +Rin in 0 1.5 + +astate1 in out newstate +.model newstate astate(astate_no=2) + +astate2 %vnam(Vsin1) %id(out2+ 0) newstate2 +.model newstate2 astate(astate_no=3) +R2 out2+ 0 0.9 + +.control +tran 10u 2m +set xbrushwidth=2 +plot v(in) v(out) v(out2+) +.endc + +.end diff --git a/examples/xspice/various/astate_pulse.cir b/examples/xspice/various/astate_pulse.cir new file mode 100644 index 000000000..fba10b904 --- /dev/null +++ b/examples/xspice/various/astate_pulse.cir @@ -0,0 +1,20 @@ +state test +* transient simulation only +* 0 <= astate_no <= 3 +* out delayed by astate_no accepted time steps +* current or voltage in- and outputs + + +Iin iin imeas pulse (1 3 0 2u 2u 198u 400u) +Vmeas imeas 0 0 +astate3 %i(iin) %i(iout) newstate3 +.model newstate3 astate(astate_no=3) +R3 iout 0 0.9 + +.control +tran 100n 1m +set xbrushwidth=2 +plot i(Vmeas) v(iout) +.endc + +.end diff --git a/src/xspice/icm/analog/astate/cfunc.mod b/src/xspice/icm/analog/astate/cfunc.mod new file mode 100644 index 000000000..cf987bb47 --- /dev/null +++ b/src/xspice/icm/analog/astate/cfunc.mod @@ -0,0 +1,188 @@ +/*.......1.........2.........3.........4.........5.........6.........7.........8 +================================================================================ + +FILE astate/cfunc.mod + +3-clause BSD + +Copyright 2025 +The ngspice team + +AUTHORS + + 20 September 2025 Holger Vogt + + +MODIFICATIONS + + + +SUMMARY + + This file contains the functional description of the analog + state code model. + + +INTERFACES + + FILE ROUTINE CALLED + + + +REFERENCED FILES + + Inputs from and outputs to ARGS structure. + + +NON-STANDARD FEATURES + + NONE + +===============================================================================*/ + +/*=== INCLUDE FILES ====================*/ + +#include + + +/*=== CONSTANTS ========================*/ + + + + +/*=== MACROS ===========================*/ + + + + +/*=== LOCAL VARIABLES & TYPEDEFS =======*/ + +typedef struct { + double state1; /* first state value */ + double state2; /* second state value */ + double state3; /* third state value */ + double outval; /* output value */ + double xval1; /* first x value */ + double xval2; /* second x value */ + double xval3; /* third x value */ +} stLocal_Data_t; + + + + + +/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ + +static void cm_astate_callback(ARGS, Mif_Callback_Reason_t reason); + +/*=== CM_STATE ROUTINE ===*/ + +void cm_astate(ARGS) +{ + int state_number = 0; + double outval = 0.0; + + stLocal_Data_t *loc; /* Pointer to local static data, not to be included + in the state vector */ + + + if (ANALYSIS != MIF_AC) { /**** only Transient Analysis and dc ****/ + + /** INIT: allocate storage **/ + + if (INIT==1) { + + CALLBACK = cm_astate_callback; + + /*** allocate static storage for *loc ***/ + if ((loc = (stLocal_Data_t *) (STATIC_VAR(locdata) = calloc(1, + sizeof(stLocal_Data_t)))) == (stLocal_Data_t *) NULL) { + cm_message_send("Unable to allocate Local_Data_t " + "in cm_astate()"); + return; + } + loc->state1 = 0; + loc->state2 = 0; + loc->state3 = 0; + loc->outval = 0; + loc->xval1 = 0; + loc->xval2 = 0; + loc->xval3 = 0; + } + + /* retrieve previous values */ + + loc = STATIC_VAR (locdata); + + state_number = PARAM(astate_no); + + if (state_number == 0) { + OUTPUT(out) = INPUT(in); + return; + } + + if (TIME == loc->xval1) { + switch(state_number) { + case 1: + loc->outval = loc->state1; + break; + case 2: + loc->outval = loc->state2; + break; + case 3: + loc->outval = loc->state3; + break; + default: + loc->outval = INPUT(in); + break; + } + } + else if (TIME > loc->xval1) { + loc->state3 = loc->state2; + loc->state2 = loc->state1; + loc->state1 = INPUT(in); + + loc->xval3 = loc->xval2; + loc->xval2 = loc->xval1; + loc->xval1 = TIME; + } + /* initial time iteration */ + else if (TIME == 0.0) { + loc->state1 = loc->outval = INPUT(in); + loc->xval1 = 0.0; + } + /* time step rejected ? */ + else if (TIME < loc->xval1){ + loc->state1 = INPUT(in); + loc->xval1 = TIME; + } + /* output */ + if (ANALYSIS == MIF_TRAN) { + OUTPUT(out) = loc->outval; + } + else { /* dc */ + OUTPUT(out) = INPUT(in); + } + } + else { + OUTPUT(out) = INPUT(in); + } +} + +/* free the memory created locally */ +static void cm_astate_callback(ARGS, Mif_Callback_Reason_t reason) +{ + switch (reason) { + case MIF_CB_DESTROY: { + stLocal_Data_t *loc = (stLocal_Data_t *) STATIC_VAR(locdata); + if (loc == (stLocal_Data_t *) NULL) { + break; + } + + free(loc); + + STATIC_VAR(locdata) = NULL; + break; + } + } +} /* end of function cm_astate_callback */ diff --git a/src/xspice/icm/analog/astate/ifspec.ifs b/src/xspice/icm/analog/astate/ifspec.ifs new file mode 100644 index 000000000..7e11d8311 --- /dev/null +++ b/src/xspice/icm/analog/astate/ifspec.ifs @@ -0,0 +1,58 @@ +/*.......1.........2.........3.........4.........5.........6.........7.........8 +================================================================================ + +------------------------------------------------------------------------- + Copyright 2025 + The ngspice team + 3 - Clause BSD license + (see COPYING or https://opensource.org/licenses/BSD-3-Clause) +------------------------------------------------------------------------- + +AUTHORS + + 20 September 2025 Holger Vogt + + +SUMMARY + + This file contains the interface specification file for the + astate code model. + +===============================================================================*/ + +NAME_TABLE: + +C_Function_Name: cm_astate +Spice_Model_Name: astate +Description: "analog state return" + + +PORT_TABLE: + +Port_Name: in out +Description: "input" "output" +Direction: in out +Default_Type: v v +Allowed_Types: [v,vd,vnam,i,id] [v,vd,i,id] +Vector: no no +Vector_Bounds: - - +Null_Allowed: no no + + +PARAMETER_TABLE: + +Parameter_Name: astate_no +Description: "state to be returned" +Data_Type: int +Default_Value: 1 +Limits: [0 3] +Vector: no +Vector_Bounds: - +Null_Allowed: yes + + +STATIC_VAR_TABLE: + +Static_Var_Name: locdata +Description: "local static data" +Data_Type: pointer diff --git a/src/xspice/icm/analog/modpath.lst b/src/xspice/icm/analog/modpath.lst index acf24b33f..1c6f1595d 100644 --- a/src/xspice/icm/analog/modpath.lst +++ b/src/xspice/icm/analog/modpath.lst @@ -20,3 +20,4 @@ triangle file_source delay pwlts +astate diff --git a/visualc/xspice/analog.vcxproj b/visualc/xspice/analog.vcxproj index 57074ec99..4c81fd959 100644 --- a/visualc/xspice/analog.vcxproj +++ b/visualc/xspice/analog.vcxproj @@ -244,6 +244,8 @@ + + @@ -291,6 +293,8 @@ + +