Initial prototype of "spider" code model, used to vary arbitrary

device parameters during simulation.
This commit is contained in:
Giles Atkinson 2025-05-05 14:06:33 +01:00
parent 71f6063873
commit 9bb8588bee
6 changed files with 133 additions and 1 deletions

View File

@ -406,6 +406,12 @@ struct Mif_Private {
Mif_Inst_Var_Data_t **inst_var; /* Information about each inst variable */
Mif_Callback_t *callback; /* Callback function */
// Rude hack here!
CKTcircuit *ckt;
struct SPICEdev **sdevs;
struct IFdevice **ifdevs;
unsigned int devices; /* Size of device table in *ckt. */
};

View File

@ -344,7 +344,7 @@ static void EVTcreate_state(
state_data = ckt->evt->data.state;
/* Exit immediately if no states on this instance */
if(state_data->desc[inst_index] == NULL)
if (!state_data || state_data->desc[inst_index] == NULL)
return;
/* Get size of state block to be allocated */

View File

@ -10,3 +10,4 @@ zener
memristor
sidiode
pswitch
spider

View File

@ -0,0 +1,89 @@
#include <string.h>
#include "ngspice/ifsim.h"
#include "ngspice/devdefs.h"
#include "ngspice/gendefs.h"
/* Modified copy from spiceif.c. FIX ME! */
static IFparm *parmlookup(IFdevice *dev, char *param)
{
IFparm *p;
int i;
if (dev->numInstanceParms) {
for (i = 0; i < *(dev->numInstanceParms); i++) {
p = dev->instanceParms + i;
if ((p->dataType & IF_SET) && !strcmp(p->keyword, param)) {
while ((p->dataType & IF_REDUNDANT) && i > 0)
i--;
if ((p->dataType & IF_VARTYPES) != IF_REAL)
return NULL;
return p;
}
}
}
if (dev->numModelParms) {
for (i = 0; i < *(dev->numModelParms); i++) {
p = dev->modelParms + i;
if ((p->dataType & IF_SET) && !strcmp(p->keyword, param)) {
while ((p->dataType & IF_REDUNDANT) && i > 0)
i--;
if ((p->dataType & IF_VARTYPES) != IF_REAL)
return NULL;
return p;
}
}
}
return NULL;
}
void ucm_spider(ARGS)
{
CKTcircuit *ckt;
SPICEdev *sdev;
IFdevice *ifdev;
GENmodel *mod;
GENinstance *dev;
IFparm *p;
char *what;
IFvalue nval;
double v;
int i;
if (INIT) {
// cm_irreversible(1);
return;
}
ckt = mif_private->ckt;
what = PARAM(parameter);
nval.rValue = INPUT(value);
if (!strcmp(what, "temp")) {
/* Set the overall circuit temperature. */
ckt->CKTtemp = nval.rValue;
}
for (i = 0; i < mif_private->devices; ++i) {
ifdev = mif_private->ifdevs[i];
p = parmlookup(ifdev, what); // Cache me!
if (!p)
continue;
sdev = mif_private->sdevs[i];
for (mod = ckt->CKThead[i]; mod; mod = mod->GENnextModel) {
for (dev = mod->GENinstances; dev; dev = dev->GENnextInstance) {
/* Try setting the named parameter on this device.
* Modelled on cktparam.c.
*/
sdev->DEVparam(p->id, &nval, dev, NULL);
}
}
}
}

View File

@ -0,0 +1,30 @@
/* Hack XSPICE device allow altering arbirary parameter during simulation. */
NAME_TABLE:
Spice_Model_Name: spider
C_Function_Name: ucm_spider
Description: "Parameter tweaker"
PORT_TABLE:
Port_Name: value
Description: "input"
Direction: in
Default_Type: v
Allowed_Types: [v, vd, i, id]
Vector: no
Vector_Bounds: -
Null_Allowed: no
PARAMETER_TABLE:
Parameter_Name: parameter
Description: "Name of parameter to be varied"
Data_Type: string
Default_Value: -
Limits: -
Vector: no
Vector_Bounds: -
Null_Allowed: no

View File

@ -50,6 +50,7 @@ NON-STANDARD FEATURES
#include "ngspice/cktdefs.h"
#include "ngspice/devdefs.h"
#include "ngspice/sperror.h"
#include "ngspice/fteext.h"
#include "ngspice/evt.h"
@ -173,6 +174,11 @@ MIFload(
/* Setup the circuit data in the structure to be passed to the code models */
/* *********************************************************************** */
cm_data.ckt = ckt;
cm_data.sdevs = DEVices;
cm_data.ifdevs = ft_sim->devices;
cm_data.devices = ft_sim->numDevices;
/* anal_init is set if this is the first iteration at any step in */
/* an analysis */
if(!(ckt->CKTmode & MODEINITFLOAT))