From deb33cbe8e38d09fb742f001161734a403dec78e Mon Sep 17 00:00:00 2001 From: DSPOM Date: Sat, 14 May 2022 09:48:00 +0200 Subject: [PATCH] update to osdi 0.3 --- src/osdi/osdi.h | 30 ++++++++++++++------------- src/osdi/osdiacld.c | 6 ++++-- src/osdi/osdidefs.h | 3 +++ src/osdi/osdiload.c | 49 +++++++++++++++++++++++++++----------------- src/osdi/osdisetup.c | 38 ++++++++++++++++++++-------------- 5 files changed, 76 insertions(+), 50 deletions(-) diff --git a/src/osdi/osdi.h b/src/osdi/osdi.h index d0bc6baa4..e7aaa4095 100644 --- a/src/osdi/osdi.h +++ b/src/osdi/osdi.h @@ -10,7 +10,7 @@ #define OSDI_VERSION_MAJOR_CURR 0 -#define OSDI_VERSION_MINOR_CURR 2 +#define OSDI_VERSION_MINOR_CURR 3 #define PARA_TY_MASK 3 #define PARA_TY_REAL 0 @@ -108,7 +108,7 @@ typedef struct OsdiDescriptor { uint32_t num_collapsible; OsdiNodePair *collapsible; - size_t is_collapsible_offset; + size_t collapsed_offset; OsdiNoiseSource *noise_sources; uint32_t num_noise_src; @@ -120,8 +120,6 @@ typedef struct OsdiDescriptor { size_t residual_resist_offset; size_t residual_react_offset; - size_t jacobian_resist_offset; - size_t jacobian_react_offset; size_t node_mapping_offset; size_t jacobian_ptr_resist_offset; size_t jacobian_ptr_react_offset; @@ -131,21 +129,25 @@ typedef struct OsdiDescriptor { void *(*access)(void *inst, void *model, uint32_t id, uint32_t flags); - OsdiInitInfo (*setup_model)(void *handle, void *model); - OsdiInitInfo (*setup_instance)(void *handle, void *inst, void *model, - double temperature, uint32_t num_terminals); + void (*setup_model)(void *handle, void *model, OsdiSimParas *sim_params, + OsdiInitInfo *res); + void (*setup_instance)(void *handle, void *inst, void *model, + double temperature, uint32_t num_terminals, + OsdiSimParas *sim_params, OsdiInitInfo *res); uint32_t (*eval)(void *handle, void *inst, void *model, uint32_t flags, double *prev_solve, OsdiSimParas *sim_params); void (*load_noise)(void *inst, void *model, double freq, double *noise_dens, double *ln_noise_dens); - void (*load_residual_resist)(void *inst, double *dst); - void (*load_residual_react)(void *inst, double *dst); - void (*load_spice_rhs_dc)(void *inst, double *dst, double* prev_solve); - void (*load_spice_rhs_tran)(void *inst, double *dst, double* prev_solve, double alpha); - void (*load_jacobian_resist)(void *inst); - void (*load_jacobian_react)(void *inst, double alpha); - void (*load_jacobian_tran)(void *inst, double alpha); + void (*load_residual_resist)(void *inst, void* model, double *dst); + void (*load_residual_react)(void *inst, void* model, double *dst); + void (*load_spice_rhs_dc)(void *inst, void* model, double *dst, + double* prev_solve); + void (*load_spice_rhs_tran)(void *inst, void* model, double *dst, + double* prev_solve, double alpha); + void (*load_jacobian_resist)(void *inst, void* model); + void (*load_jacobian_react)(void *inst, void* model, double alpha); + void (*load_jacobian_tran)(void *inst, void* model, double alpha); }OsdiDescriptor; diff --git a/src/osdi/osdiacld.c b/src/osdi/osdiacld.c index 9a00f2402..b3e3aef52 100644 --- a/src/osdi/osdiacld.c +++ b/src/osdi/osdiacld.c @@ -22,13 +22,15 @@ int OSDIacLoad(GENmodel *inModel, CKTcircuit *ckt) { OsdiRegistryEntry *entry = osdi_reg_entry_model(inModel); const OsdiDescriptor *descr = entry->descriptor; for (gen_model = inModel; gen_model; gen_model = gen_model->GENnextModel) { + void *model = osdi_model_data(gen_model); + for (gen_inst = gen_model->GENinstances; gen_inst; gen_inst = gen_inst->GENnextInstance) { void *inst = osdi_instance_data(entry, gen_inst); // nothing to calculate just load the matrix entries calculated during // operating point iterations - descr->load_jacobian_resist(inst); - descr->load_jacobian_react(inst, ckt->CKTomega); + descr->load_jacobian_resist(inst, model); + descr->load_jacobian_react(inst, model, ckt->CKTomega); } } return (OK); diff --git a/src/osdi/osdidefs.h b/src/osdi/osdidefs.h index ab2d8ae62..09d83fe0e 100644 --- a/src/osdi/osdidefs.h +++ b/src/osdi/osdidefs.h @@ -49,3 +49,6 @@ typedef struct OsdiNgspiceHandle { uint32_t kind; char *name; } OsdiNgspiceHandle; + +/* values returned by $simparam*/ +OsdiSimParas get_simparams(const CKTcircuit *ckt); diff --git a/src/osdi/osdiload.c b/src/osdi/osdiload.c index b8bc5cfa1..29694999e 100644 --- a/src/osdi/osdiload.c +++ b/src/osdi/osdiload.c @@ -13,13 +13,34 @@ #include #include #include +#include #include -#define NUM_SIM_PARAMS 4 -char *sim_params[NUM_SIM_PARAMS + 1] = {"gdev", "gmin", "tnom", - "simulatorVersion", NULL}; +#define NUM_SIM_PARAMS 5 +char *sim_params[NUM_SIM_PARAMS + 1] = { + "gdev", "gmin", "tnom", "simulatorVersion", "sourceScaleFactor", NULL}; char *sim_params_str[1] = {NULL}; +double sim_param_vals[NUM_SIM_PARAMS] = {}; + +/* values returned by $simparam*/ +OsdiSimParas get_simparams(const CKTcircuit *ckt) { + + double simulatorVersion = strtod(PACKAGE_VERSION, NULL); + double gdev = ckt->CKTgmin; + double sourceScaleFactor = ckt->CKTsrcFact; + double gmin = ((ckt->CKTgmin) > (ckt->CKTdiagGmin)) ? (ckt->CKTgmin) + : (ckt->CKTdiagGmin); + double sim_param_vals_[NUM_SIM_PARAMS] = { + gdev, gmin, ckt->CKTnomTemp, simulatorVersion, sourceScaleFactor}; + memcpy(&sim_param_vals, &sim_param_vals_, sizeof(double) * NUM_SIM_PARAMS); + OsdiSimParas sim_params_ = {.names = sim_params, + .vals = (double *)&sim_param_vals, + .names_str = sim_params_str, + .vals_str = NULL}; + return sim_params_; +} + extern int OSDIload(GENmodel *inModel, CKTcircuit *ckt) { OsdiNgspiceHandle handle; GENmodel *gen_model; @@ -35,6 +56,8 @@ extern int OSDIload(GENmodel *inModel, CKTcircuit *ckt) { uint32_t flags = CALC_RESIST_JACOBIAN; + OsdiSimParas sim_params_ = get_simparams(ckt); + if (is_init_smsig || is_sweep) { flags |= CALC_OP; } @@ -57,18 +80,6 @@ extern int OSDIload(GENmodel *inModel, CKTcircuit *ckt) { int ret = OK; - /* values returned by $simparam*/ - double simulatorVersion = strtod(PACKAGE_VERSION, NULL); - double gdev = ckt->CKTgmin; - double gmin = ((ckt->CKTgmin) > (ckt->CKTdiagGmin)) ? (ckt->CKTgmin) - : (ckt->CKTdiagGmin); - double sim_param_vals[NUM_SIM_PARAMS] = {gdev, gmin, ckt->CKTnomTemp, - simulatorVersion}; - OsdiSimParas sim_params_ = {.names = sim_params, - .vals = sim_param_vals, - .names_str = sim_params_str, - .vals_str = NULL}; - OsdiRegistryEntry *entry = osdi_reg_entry_model(inModel); const OsdiDescriptor *descr = entry->descriptor; @@ -116,10 +127,10 @@ extern int OSDIload(GENmodel *inModel, CKTcircuit *ckt) { if (is_tran) { /* load dc matrix and capacitances (charge derivative multiplied with * CKTag[0]) */ - descr->load_jacobian_tran(inst, ckt->CKTag[0]); + descr->load_jacobian_tran(inst, model, ckt->CKTag[0]); /* load static rhs and dynamic linearized rhs (SUM Vb * dIa/dVb)*/ - descr->load_spice_rhs_tran(inst, ckt->CKTrhs, ckt->CKTrhsOld, + descr->load_spice_rhs_tran(inst, model, ckt->CKTrhs, ckt->CKTrhsOld, ckt->CKTag[0]); uint32_t *node_mapping = @@ -155,11 +166,11 @@ extern int OSDIload(GENmodel *inModel, CKTcircuit *ckt) { } } else { /* copy internal derivatives into global matrix */ - descr->load_jacobian_resist(inst); + descr->load_jacobian_resist(inst, model); /* calculate spice RHS from internal currents and store into global RHS */ - descr->load_spice_rhs_dc(inst, ckt->CKTrhs, ckt->CKTrhsOld); + descr->load_spice_rhs_dc(inst, model, ckt->CKTrhs, ckt->CKTrhsOld); } } } diff --git a/src/osdi/osdisetup.c b/src/osdi/osdisetup.c index b5b197741..61340cee3 100644 --- a/src/osdi/osdisetup.c +++ b/src/osdi/osdisetup.c @@ -7,6 +7,7 @@ #include "ngspice/ngspice.h" #include "ngspice/typedefs.h" +#include "osdi.h" #include "osdidefs.h" #include @@ -20,24 +21,26 @@ static int handle_init_info(OsdiInitInfo info, const OsdiDescriptor *descr) { if (info.flags & (EVAL_RET_FLAG_FATAL | EVAL_RET_FLAG_FINISH)) { return (E_PANIC); } + if (info.num_errors == 0) { return (OK); } + for (uint32_t i = 0; i < info.num_errors; i++) { OsdiInitError *err = &info.errors[i]; switch (err->code) { case INIT_ERR_OUT_OF_BOUNDS: { char *param = descr->param_opvar[err->payload.parameter_id].name[0]; - printf("Parameter %s is out of bounds!", param); + printf("Parameter %s is out of bounds!\n", param); break; } default: - printf("Unkown OSDO init error code %d!", err->code); + printf("Unkown OSDO init error code %d!\n", err->code); } } free(info.errors); - errMsg = "Errors occurred during initalization"; + errMsg = tprintf("%i errors occurred during initalization", info.num_errors); return (E_PRIVATE); } @@ -65,8 +68,7 @@ static uint32_t collapse_nodes(const OsdiDescriptor *descr, void *inst, /* access data inside instance */ uint32_t *node_mapping = (uint32_t *)(((char *)inst) + descr->node_mapping_offset); - bool *is_collapsible = - (bool *)(((char *)inst) + descr->is_collapsible_offset); + bool *collapsed = (bool *)(((char *)inst) + descr->collapsed_offset); /* without collapsing just return the total number of nodes */ uint32_t num_nodes = descr->num_nodes; @@ -78,7 +80,7 @@ static uint32_t collapse_nodes(const OsdiDescriptor *descr, void *inst, for (uint32_t i = 0; i < descr->num_collapsible; i++) { /* check if the collapse hint (V(x,y) <+ 0) was executed */ - if (!is_collapsible[i]) { + if (!collapsed[i]) { continue; } @@ -174,6 +176,8 @@ int OSDIsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, OsdiRegistryEntry *entry = osdi_reg_entry_model(inModel); const OsdiDescriptor *descr = entry->descriptor; + OsdiSimParas sim_params_ = get_simparams(ckt); + OsdiSimParas *sim_params = &sim_params_; /* setup a temporary buffer */ uint32_t *node_ids = TMALLOC(uint32_t, descr->num_nodes); @@ -191,7 +195,9 @@ int OSDIsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, /* setup model parameter (setup_model)*/ handle = (OsdiNgspiceHandle){.kind = 1, .name = gen_model->GENmodName}; - init_info = descr->setup_model((void *)&handle, model); + descr->setup_model((void *)&handle, model, sim_params, &init_info); + printf("setup_model: %i %i %p\n", init_info.flags, init_info.num_errors, + init_info.errors); res = handle_init_info(init_info, descr); if (res) { errRtn = "OSDI setup_model"; @@ -228,8 +234,8 @@ int OSDIsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, /* calculate op independent data, init instance parameters and determine which collapsing occurs*/ handle = (OsdiNgspiceHandle){.kind = 2, .name = gen_inst->GENname}; - init_info = descr->setup_instance((void *)&handle, inst, model, temp, - connected_terminals); + descr->setup_instance((void *)&handle, inst, model, temp, + connected_terminals, sim_params, &init_info); res = handle_init_info(init_info, descr); if (res) { errRtn = "OSDI setup_instance"; @@ -283,12 +289,15 @@ extern int OSDItemp(GENmodel *inModel, CKTcircuit *ckt) { OsdiRegistryEntry *entry = osdi_reg_entry_model(inModel); const OsdiDescriptor *descr = entry->descriptor; + OsdiSimParas sim_params_ = get_simparams(ckt); + OsdiSimParas *sim_params = &sim_params_; + for (gen_model = inModel; gen_model != NULL; gen_model = gen_model->GENnextModel) { void *model = osdi_model_data(gen_model); handle = (OsdiNgspiceHandle){.kind = 4, .name = gen_model->GENmodName}; - init_info = descr->setup_model((void *)&handle, model); + descr->setup_model((void *)&handle, model, sim_params, &init_info); res = handle_init_info(init_info, descr); if (res) { errRtn = "OSDI setup_model (OSDItemp)"; @@ -312,8 +321,8 @@ extern int OSDItemp(GENmodel *inModel, CKTcircuit *ckt) { handle = (OsdiNgspiceHandle){.kind = 2, .name = gen_inst->GENname}; // TODO optional terminals - init_info = descr->setup_instance((void *)&handle, inst, model, temp, - descr->num_terminals); + descr->setup_instance((void *)&handle, inst, model, temp, + descr->num_terminals, sim_params, &init_info); res = handle_init_info(init_info, descr); if (res) { errRtn = "OSDI setup_instance (OSDItemp)"; @@ -343,9 +352,8 @@ extern int OSDIunsetup(GENmodel *inModel, CKTcircuit *ckt) { void *inst = osdi_instance_data(entry, gen_inst); // reset is collapsible - bool *is_collapsible = - (bool *)(((char *)inst) + descr->is_collapsible_offset); - memset(is_collapsible, 0, sizeof(bool) * descr->num_collapsible); + bool *collapsed = (bool *)(((char *)inst) + descr->collapsed_offset); + memset(collapsed, 0, sizeof(bool) * descr->num_collapsible); uint32_t *node_mapping = (uint32_t *)(((char *)inst) + descr->node_mapping_offset);