Add analog code model astate.

It reports the previous state (delayed by 1 to 3 time steps)
of the input node. Single or differential voltage or current.
This commit is contained in:
Holger Vogt 2025-09-21 15:52:51 +02:00
parent 144f1c6fc6
commit b8357edddc
6 changed files with 294 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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 <stdlib.h>
/*=== 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 */

View File

@ -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

View File

@ -20,3 +20,4 @@ triangle
file_source
delay
pwlts
astate

View File

@ -244,6 +244,8 @@
<ClCompile Include="icm\analog\slew\slew-ifspec.c" />
<ClCompile Include="icm\analog\square\square-cfunc.c" />
<ClCompile Include="icm\analog\square\square-ifspec.c" />
<ClCompile Include="icm\analog\astate\astate-cfunc.c" />
<ClCompile Include="icm\analog\astate\astate-ifspec.c" />
<ClCompile Include="icm\analog\summer\summer-cfunc.c" />
<ClCompile Include="icm\analog\summer\summer-ifspec.c" />
<ClCompile Include="icm\analog\s_xfer\s_xfer-cfunc.c" />
@ -291,6 +293,8 @@
<None Include="..\..\src\xspice\icm\analog\slew\ifspec.ifs" />
<None Include="..\..\src\xspice\icm\analog\square\cfunc.mod" />
<None Include="..\..\src\xspice\icm\analog\square\ifspec.ifs" />
<None Include="..\..\src\xspice\icm\analog\astate\cfunc.mod" />
<None Include="..\..\src\xspice\icm\analog\astate\ifspec.ifs" />
<None Include="..\..\src\xspice\icm\analog\summer\cfunc.mod" />
<None Include="..\..\src\xspice\icm\analog\summer\ifspec.ifs" />
<None Include="..\..\src\xspice\icm\analog\s_xfer\cfunc.mod" />