update to osdi 0.3
This commit is contained in:
parent
68b8e41def
commit
deb33cbe8e
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
|
|
||||||
#define OSDI_VERSION_MAJOR_CURR 0
|
#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_MASK 3
|
||||||
#define PARA_TY_REAL 0
|
#define PARA_TY_REAL 0
|
||||||
|
|
@ -108,7 +108,7 @@ typedef struct OsdiDescriptor {
|
||||||
|
|
||||||
uint32_t num_collapsible;
|
uint32_t num_collapsible;
|
||||||
OsdiNodePair *collapsible;
|
OsdiNodePair *collapsible;
|
||||||
size_t is_collapsible_offset;
|
size_t collapsed_offset;
|
||||||
|
|
||||||
OsdiNoiseSource *noise_sources;
|
OsdiNoiseSource *noise_sources;
|
||||||
uint32_t num_noise_src;
|
uint32_t num_noise_src;
|
||||||
|
|
@ -120,8 +120,6 @@ typedef struct OsdiDescriptor {
|
||||||
|
|
||||||
size_t residual_resist_offset;
|
size_t residual_resist_offset;
|
||||||
size_t residual_react_offset;
|
size_t residual_react_offset;
|
||||||
size_t jacobian_resist_offset;
|
|
||||||
size_t jacobian_react_offset;
|
|
||||||
size_t node_mapping_offset;
|
size_t node_mapping_offset;
|
||||||
size_t jacobian_ptr_resist_offset;
|
size_t jacobian_ptr_resist_offset;
|
||||||
size_t jacobian_ptr_react_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);
|
void *(*access)(void *inst, void *model, uint32_t id, uint32_t flags);
|
||||||
|
|
||||||
OsdiInitInfo (*setup_model)(void *handle, void *model);
|
void (*setup_model)(void *handle, void *model, OsdiSimParas *sim_params,
|
||||||
OsdiInitInfo (*setup_instance)(void *handle, void *inst, void *model,
|
OsdiInitInfo *res);
|
||||||
double temperature, uint32_t num_terminals);
|
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,
|
uint32_t (*eval)(void *handle, void *inst, void *model, uint32_t flags,
|
||||||
double *prev_solve, OsdiSimParas *sim_params);
|
double *prev_solve, OsdiSimParas *sim_params);
|
||||||
void (*load_noise)(void *inst, void *model, double freq, double *noise_dens,
|
void (*load_noise)(void *inst, void *model, double freq, double *noise_dens,
|
||||||
double *ln_noise_dens);
|
double *ln_noise_dens);
|
||||||
void (*load_residual_resist)(void *inst, double *dst);
|
void (*load_residual_resist)(void *inst, void* model, double *dst);
|
||||||
void (*load_residual_react)(void *inst, double *dst);
|
void (*load_residual_react)(void *inst, void* model, double *dst);
|
||||||
void (*load_spice_rhs_dc)(void *inst, double *dst, double* prev_solve);
|
void (*load_spice_rhs_dc)(void *inst, void* model, double *dst,
|
||||||
void (*load_spice_rhs_tran)(void *inst, double *dst, double* prev_solve, double alpha);
|
double* prev_solve);
|
||||||
void (*load_jacobian_resist)(void *inst);
|
void (*load_spice_rhs_tran)(void *inst, void* model, double *dst,
|
||||||
void (*load_jacobian_react)(void *inst, double alpha);
|
double* prev_solve, double alpha);
|
||||||
void (*load_jacobian_tran)(void *inst, 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;
|
}OsdiDescriptor;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,13 +22,15 @@ int OSDIacLoad(GENmodel *inModel, CKTcircuit *ckt) {
|
||||||
OsdiRegistryEntry *entry = osdi_reg_entry_model(inModel);
|
OsdiRegistryEntry *entry = osdi_reg_entry_model(inModel);
|
||||||
const OsdiDescriptor *descr = entry->descriptor;
|
const OsdiDescriptor *descr = entry->descriptor;
|
||||||
for (gen_model = inModel; gen_model; gen_model = gen_model->GENnextModel) {
|
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;
|
for (gen_inst = gen_model->GENinstances; gen_inst;
|
||||||
gen_inst = gen_inst->GENnextInstance) {
|
gen_inst = gen_inst->GENnextInstance) {
|
||||||
void *inst = osdi_instance_data(entry, gen_inst);
|
void *inst = osdi_instance_data(entry, gen_inst);
|
||||||
// nothing to calculate just load the matrix entries calculated during
|
// nothing to calculate just load the matrix entries calculated during
|
||||||
// operating point iterations
|
// operating point iterations
|
||||||
descr->load_jacobian_resist(inst);
|
descr->load_jacobian_resist(inst, model);
|
||||||
descr->load_jacobian_react(inst, ckt->CKTomega);
|
descr->load_jacobian_react(inst, model, ckt->CKTomega);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (OK);
|
return (OK);
|
||||||
|
|
|
||||||
|
|
@ -49,3 +49,6 @@ typedef struct OsdiNgspiceHandle {
|
||||||
uint32_t kind;
|
uint32_t kind;
|
||||||
char *name;
|
char *name;
|
||||||
} OsdiNgspiceHandle;
|
} OsdiNgspiceHandle;
|
||||||
|
|
||||||
|
/* values returned by $simparam*/
|
||||||
|
OsdiSimParas get_simparams(const CKTcircuit *ckt);
|
||||||
|
|
|
||||||
|
|
@ -13,13 +13,34 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#define NUM_SIM_PARAMS 4
|
#define NUM_SIM_PARAMS 5
|
||||||
char *sim_params[NUM_SIM_PARAMS + 1] = {"gdev", "gmin", "tnom",
|
char *sim_params[NUM_SIM_PARAMS + 1] = {
|
||||||
"simulatorVersion", NULL};
|
"gdev", "gmin", "tnom", "simulatorVersion", "sourceScaleFactor", NULL};
|
||||||
char *sim_params_str[1] = {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) {
|
extern int OSDIload(GENmodel *inModel, CKTcircuit *ckt) {
|
||||||
OsdiNgspiceHandle handle;
|
OsdiNgspiceHandle handle;
|
||||||
GENmodel *gen_model;
|
GENmodel *gen_model;
|
||||||
|
|
@ -35,6 +56,8 @@ extern int OSDIload(GENmodel *inModel, CKTcircuit *ckt) {
|
||||||
|
|
||||||
uint32_t flags = CALC_RESIST_JACOBIAN;
|
uint32_t flags = CALC_RESIST_JACOBIAN;
|
||||||
|
|
||||||
|
OsdiSimParas sim_params_ = get_simparams(ckt);
|
||||||
|
|
||||||
if (is_init_smsig || is_sweep) {
|
if (is_init_smsig || is_sweep) {
|
||||||
flags |= CALC_OP;
|
flags |= CALC_OP;
|
||||||
}
|
}
|
||||||
|
|
@ -57,18 +80,6 @@ extern int OSDIload(GENmodel *inModel, CKTcircuit *ckt) {
|
||||||
|
|
||||||
int ret = OK;
|
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);
|
OsdiRegistryEntry *entry = osdi_reg_entry_model(inModel);
|
||||||
const OsdiDescriptor *descr = entry->descriptor;
|
const OsdiDescriptor *descr = entry->descriptor;
|
||||||
|
|
||||||
|
|
@ -116,10 +127,10 @@ extern int OSDIload(GENmodel *inModel, CKTcircuit *ckt) {
|
||||||
if (is_tran) {
|
if (is_tran) {
|
||||||
/* load dc matrix and capacitances (charge derivative multiplied with
|
/* load dc matrix and capacitances (charge derivative multiplied with
|
||||||
* CKTag[0]) */
|
* 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)*/
|
/* 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]);
|
ckt->CKTag[0]);
|
||||||
|
|
||||||
uint32_t *node_mapping =
|
uint32_t *node_mapping =
|
||||||
|
|
@ -155,11 +166,11 @@ extern int OSDIload(GENmodel *inModel, CKTcircuit *ckt) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* copy internal derivatives into global matrix */
|
/* 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
|
/* 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include "ngspice/ngspice.h"
|
#include "ngspice/ngspice.h"
|
||||||
#include "ngspice/typedefs.h"
|
#include "ngspice/typedefs.h"
|
||||||
|
|
||||||
|
#include "osdi.h"
|
||||||
#include "osdidefs.h"
|
#include "osdidefs.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
@ -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)) {
|
if (info.flags & (EVAL_RET_FLAG_FATAL | EVAL_RET_FLAG_FINISH)) {
|
||||||
return (E_PANIC);
|
return (E_PANIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.num_errors == 0) {
|
if (info.num_errors == 0) {
|
||||||
return (OK);
|
return (OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < info.num_errors; i++) {
|
for (uint32_t i = 0; i < info.num_errors; i++) {
|
||||||
OsdiInitError *err = &info.errors[i];
|
OsdiInitError *err = &info.errors[i];
|
||||||
switch (err->code) {
|
switch (err->code) {
|
||||||
case INIT_ERR_OUT_OF_BOUNDS: {
|
case INIT_ERR_OUT_OF_BOUNDS: {
|
||||||
char *param = descr->param_opvar[err->payload.parameter_id].name[0];
|
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;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
printf("Unkown OSDO init error code %d!", err->code);
|
printf("Unkown OSDO init error code %d!\n", err->code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(info.errors);
|
free(info.errors);
|
||||||
errMsg = "Errors occurred during initalization";
|
errMsg = tprintf("%i errors occurred during initalization", info.num_errors);
|
||||||
return (E_PRIVATE);
|
return (E_PRIVATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -65,8 +68,7 @@ static uint32_t collapse_nodes(const OsdiDescriptor *descr, void *inst,
|
||||||
/* access data inside instance */
|
/* access data inside instance */
|
||||||
uint32_t *node_mapping =
|
uint32_t *node_mapping =
|
||||||
(uint32_t *)(((char *)inst) + descr->node_mapping_offset);
|
(uint32_t *)(((char *)inst) + descr->node_mapping_offset);
|
||||||
bool *is_collapsible =
|
bool *collapsed = (bool *)(((char *)inst) + descr->collapsed_offset);
|
||||||
(bool *)(((char *)inst) + descr->is_collapsible_offset);
|
|
||||||
|
|
||||||
/* without collapsing just return the total number of nodes */
|
/* without collapsing just return the total number of nodes */
|
||||||
uint32_t num_nodes = descr->num_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++) {
|
for (uint32_t i = 0; i < descr->num_collapsible; i++) {
|
||||||
/* check if the collapse hint (V(x,y) <+ 0) was executed */
|
/* check if the collapse hint (V(x,y) <+ 0) was executed */
|
||||||
if (!is_collapsible[i]) {
|
if (!collapsed[i]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -174,6 +176,8 @@ int OSDIsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
|
||||||
|
|
||||||
OsdiRegistryEntry *entry = osdi_reg_entry_model(inModel);
|
OsdiRegistryEntry *entry = osdi_reg_entry_model(inModel);
|
||||||
const OsdiDescriptor *descr = entry->descriptor;
|
const OsdiDescriptor *descr = entry->descriptor;
|
||||||
|
OsdiSimParas sim_params_ = get_simparams(ckt);
|
||||||
|
OsdiSimParas *sim_params = &sim_params_;
|
||||||
|
|
||||||
/* setup a temporary buffer */
|
/* setup a temporary buffer */
|
||||||
uint32_t *node_ids = TMALLOC(uint32_t, descr->num_nodes);
|
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)*/
|
/* setup model parameter (setup_model)*/
|
||||||
handle = (OsdiNgspiceHandle){.kind = 1, .name = gen_model->GENmodName};
|
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);
|
res = handle_init_info(init_info, descr);
|
||||||
if (res) {
|
if (res) {
|
||||||
errRtn = "OSDI setup_model";
|
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
|
/* calculate op independent data, init instance parameters and determine
|
||||||
which collapsing occurs*/
|
which collapsing occurs*/
|
||||||
handle = (OsdiNgspiceHandle){.kind = 2, .name = gen_inst->GENname};
|
handle = (OsdiNgspiceHandle){.kind = 2, .name = gen_inst->GENname};
|
||||||
init_info = descr->setup_instance((void *)&handle, inst, model, temp,
|
descr->setup_instance((void *)&handle, inst, model, temp,
|
||||||
connected_terminals);
|
connected_terminals, sim_params, &init_info);
|
||||||
res = handle_init_info(init_info, descr);
|
res = handle_init_info(init_info, descr);
|
||||||
if (res) {
|
if (res) {
|
||||||
errRtn = "OSDI setup_instance";
|
errRtn = "OSDI setup_instance";
|
||||||
|
|
@ -283,12 +289,15 @@ extern int OSDItemp(GENmodel *inModel, CKTcircuit *ckt) {
|
||||||
OsdiRegistryEntry *entry = osdi_reg_entry_model(inModel);
|
OsdiRegistryEntry *entry = osdi_reg_entry_model(inModel);
|
||||||
const OsdiDescriptor *descr = entry->descriptor;
|
const OsdiDescriptor *descr = entry->descriptor;
|
||||||
|
|
||||||
|
OsdiSimParas sim_params_ = get_simparams(ckt);
|
||||||
|
OsdiSimParas *sim_params = &sim_params_;
|
||||||
|
|
||||||
for (gen_model = inModel; gen_model != NULL;
|
for (gen_model = inModel; gen_model != NULL;
|
||||||
gen_model = gen_model->GENnextModel) {
|
gen_model = gen_model->GENnextModel) {
|
||||||
void *model = osdi_model_data(gen_model);
|
void *model = osdi_model_data(gen_model);
|
||||||
|
|
||||||
handle = (OsdiNgspiceHandle){.kind = 4, .name = gen_model->GENmodName};
|
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);
|
res = handle_init_info(init_info, descr);
|
||||||
if (res) {
|
if (res) {
|
||||||
errRtn = "OSDI setup_model (OSDItemp)";
|
errRtn = "OSDI setup_model (OSDItemp)";
|
||||||
|
|
@ -312,8 +321,8 @@ extern int OSDItemp(GENmodel *inModel, CKTcircuit *ckt) {
|
||||||
|
|
||||||
handle = (OsdiNgspiceHandle){.kind = 2, .name = gen_inst->GENname};
|
handle = (OsdiNgspiceHandle){.kind = 2, .name = gen_inst->GENname};
|
||||||
// TODO optional terminals
|
// TODO optional terminals
|
||||||
init_info = descr->setup_instance((void *)&handle, inst, model, temp,
|
descr->setup_instance((void *)&handle, inst, model, temp,
|
||||||
descr->num_terminals);
|
descr->num_terminals, sim_params, &init_info);
|
||||||
res = handle_init_info(init_info, descr);
|
res = handle_init_info(init_info, descr);
|
||||||
if (res) {
|
if (res) {
|
||||||
errRtn = "OSDI setup_instance (OSDItemp)";
|
errRtn = "OSDI setup_instance (OSDItemp)";
|
||||||
|
|
@ -343,9 +352,8 @@ extern int OSDIunsetup(GENmodel *inModel, CKTcircuit *ckt) {
|
||||||
void *inst = osdi_instance_data(entry, gen_inst);
|
void *inst = osdi_instance_data(entry, gen_inst);
|
||||||
|
|
||||||
// reset is collapsible
|
// reset is collapsible
|
||||||
bool *is_collapsible =
|
bool *collapsed = (bool *)(((char *)inst) + descr->collapsed_offset);
|
||||||
(bool *)(((char *)inst) + descr->is_collapsible_offset);
|
memset(collapsed, 0, sizeof(bool) * descr->num_collapsible);
|
||||||
memset(is_collapsible, 0, sizeof(bool) * descr->num_collapsible);
|
|
||||||
|
|
||||||
uint32_t *node_mapping =
|
uint32_t *node_mapping =
|
||||||
(uint32_t *)(((char *)inst) + descr->node_mapping_offset);
|
(uint32_t *)(((char *)inst) + descr->node_mapping_offset);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue