Second batch of added files.

This commit is contained in:
pnenzi 2003-07-23 20:06:10 +00:00
parent 9317355c0c
commit 758bedc716
56 changed files with 9277 additions and 0 deletions

24
src/frontend/com_dl.c Executable file
View File

@ -0,0 +1,24 @@
#include <ngspice.h> /* for wl */
#include "ftedefs.h"
#include <devdefs.h> /* solve deps in dev.h*/
#include <../spicelib/devices/dev.h> /*for load library commands*/
#ifdef XSPICE
void com_codemodel(wordlist *wl){
wordlist *ww;
for(ww = wl;ww;ww = ww->wl_next)
if(load_opus(wl->wl_word))
fprintf(cp_err,"Error: Library %s couldn't be loaded!\n",ww->wl_word);
return;
}
#endif
#ifdef DEVLIB
void com_use(wordlist *wl){
wordlist *ww;
for(ww = wl;ww;ww = ww->wl_next)
if(load_dev(wl->wl_word))
fprintf(cp_err,"Error: Library %s couldn't be loaded!\n",ww->wl_word);
return;
}
#endif

12
src/frontend/com_dl.h Executable file
View File

@ -0,0 +1,12 @@
#ifndef _COM_DL_H
#define _COM_DL_H 1
#ifdef XSPICE
void com_codemodel(wordlist *wl);
#endif
#ifdef DEVLIB
void com_use(wordlist *wl);
#endif
#endif

315
src/frontend/hpgl.c Normal file
View File

@ -0,0 +1,315 @@
/**********
Author: Jim Groves
**********/
/*
HPGL driver
*/
/*
1000 plotter units / inch - 1pu = 0.025mm 1pu = 1mil
SP - select pen
PU - pen up (PU x,y)
PD - pen down (PD x,y)
LT - line type
0 dots only at plotted points
1 . . . . .
2 ___ ___ ___ ___
3 ---- ---- ---- ----
4 ----- . ----- . ----- . -----.
5 ---- - ---- - ---- -
6 --- - - --- - - --- - - --- - -
null - solid line
IN - initialize
DF - default values (PA, solid line, set 0)
PA - plot absolute
SI - absolute character size (SI width, height) in cm
*/
#include "spice.h"
#include "cpdefs.h"
#include "graph.h"
#include "ftedbgra.h"
#include "ftedev.h"
#include "fteinput.h"
#include "variable.h"
#define RAD_TO_DEG (180.0 / M_PI)
#define DEVDEP(g) (*((GLdevdep *) (g)->devdep))
#define MAX_GL_LINES 9999
#define SOLID 0
#define DOTTED 1
#define gtype graph->grid.gridtype
#define xoff dispdev->minx
#define yoff dispdev->miny
#define XOFF 25 /* printer left margin */
#define YOFF 28 /* printer bottom margin */
#define XTADJ 0 /* printer text adjustment x */
#define YTADJ 0 /* printer text adjustment y */
#define DELXMAX 360 /* printer gridsize divisible by 10, [7-2] */
#define DELYMAX 360 /* printer gridsize divisible by [10-8], [6-2] */
#define FONTWIDTH 6 /* printer default fontwidth */
#define FONTHEIGHT 8 /* printer default fontheight */
typedef struct {
int lastlinestyle; /* initial invalid value */
int lastx, lasty, linecount;
} GLdevdep;
static char *linestyle[] = {
"", /* solid */
"1", /* was 1 - dotted */
"", /* longdashed */
"3", /* shortdashed */
"4", /* longdotdashed */
"5", /* shortdotdashed */
"1"
};
static FILE *plotfile;
char psfont[128], psfontsize[32], psscale[32];
static int fontwidth = FONTWIDTH;
static int fontheight = FONTHEIGHT;
static int jgmult = 10;
static int screenflag = 0;
static double tocm = 0.0025;
static double scale; /* Used for fine tuning */
static int hcopygraphid;
extern int DestroyGraph (int id);
extern void internalerror (char *message);
int GL_Init()
{
if (!cp_getvar("hcopyscale", VT_STRING, psscale)) {
scale = 1.0;
} else {
sscanf(psscale, "%lf", &scale);
if ((scale <= 0) || (scale > 10))
scale = 1.0;
}
dispdev->numlinestyles = NUMELEMS(linestyle);
dispdev->numcolors = 6;
dispdev->width = DELXMAX * scale;
dispdev->height = DELYMAX * scale;
screenflag = 0;
dispdev->minx = XOFF * 1.0;
dispdev->miny = YOFF * 1.0;
return(0);
}
/* devdep initially contains name of output file */
int GL_NewViewport(graph)
GRAPH *graph;
{
/* double scaleps, scalex, scaley; */
hcopygraphid = graph->graphid;
if (!(plotfile = fopen(graph->devdep, "w"))) {
perror(graph->devdep);
graph->devdep = (char *) NULL;
return(1);
}
if (graph->absolute.width) {
/* hardcopying from the screen */
screenflag = 1;
/* scale to fit on 8 1/2 square */
}
/* reasonable values, used in gr_ for placement */
graph->fontwidth = fontwidth * scale; /* was 12, p.w.h. */
graph->fontheight = fontheight * scale; /* was 24, p.w.h. */
graph->absolute.width = dispdev->width;
graph->absolute.height = dispdev->height;
/* Also done in gr_init, if called . . . */
graph->viewportxoff = 16 * fontwidth;
graph->viewportyoff = 8 * fontheight;
xoff = XOFF;
yoff = YOFF;
/* start file off with a % */
fprintf(plotfile, "IN;DF;PA;");
fprintf(plotfile, "SI %f,%f;", tocm*jgmult*fontwidth*scale,tocm*jgmult*fontheight*scale);
#ifdef notdef
if (!screenflag)
#endif
graph->devdep = tmalloc(sizeof(GLdevdep));
DEVDEP(graph).lastlinestyle = -1;
DEVDEP(graph).lastx = -1;
DEVDEP(graph).lasty = -1;
DEVDEP(graph).linecount = 0;
graph->linestyle = -1;
return 0;
}
int GL_Close()
{
/* in case GL_Close is called as part of an abort,
w/o having reached GL_NewViewport */
if (plotfile) {
if (DEVDEP(currentgraph).lastlinestyle != -1) {
DEVDEP(currentgraph).linecount = 0;
}
fclose(plotfile);
plotfile = NULL;
}
/* In case of hardcopy command destroy the hardcopy graph
* and reset currentgraph to graphid 1, if possible
*/
if (!screenflag) {
DestroyGraph(hcopygraphid);
currentgraph = FindGraph(1);
}
return 0;
}
int GL_Clear()
{
/* do nothing */
return 0;
}
int GL_DrawLine(x1, y1, x2, y2)
int x1, y1, x2, y2;
{
/* note: this is not extendible to more than one graph
=> will have to give NewViewport a writeable graph XXX */
if (DEVDEP(currentgraph).linecount == 0
|| x1 != DEVDEP(currentgraph).lastx
|| y1 != DEVDEP(currentgraph).lasty)
{
fprintf(plotfile, "PU;PA %d , %d ;", jgmult*(x1 + xoff), jgmult*(y1 + yoff));
}
if (x1 != x2 || y1 != y2) {
fprintf(plotfile, "PD;PA %d , %d ;", jgmult*(x2 + xoff), jgmult*(y2 + yoff));
DEVDEP(currentgraph).linecount += 1;
}
DEVDEP(currentgraph).lastx = x2;
DEVDEP(currentgraph).lasty = y2;
DEVDEP(currentgraph).lastlinestyle = currentgraph->linestyle;
return 0;
}
/* ARGSUSED */
int GL_Arc(x0, y0, r, theta1, theta2)
int x0, y0, r;
double theta1, theta2;
{
double x1, y1;
double angle1, angle2;
while (theta1 >= theta2)
theta2 += 2 * M_PI;
angle1 = (double) (RAD_TO_DEG * theta1);
angle2 = (double) (RAD_TO_DEG * theta2);
x1 = (double) x0 + r * cos(theta1);
y1 = (double) y0 + r * sin(theta1);
/*
fprintf(plotfile, "%lf %lf moveto ", x1+(double)xoff, y1+(double)yoff);
fprintf(plotfile, "%d %d %d %lf %lf arc\n", x0+xoff, y0+yoff, r,
angle1, angle2);
fprintf(plotfile, "stroke\n");
*/
DEVDEP(currentgraph).linecount = 0;
return 0;
}
int GL_Text(text, x, y)
char *text;
int x, y;
{
/* int savedlstyle; */
/* move to (x, y) */
fprintf(plotfile, "PU;PA %d , %d;", jgmult*(x+xoff+XTADJ), jgmult*(y+yoff+YTADJ));
fprintf(plotfile, "LB %s \x03", text);
DEVDEP(currentgraph).lastx = -1;
DEVDEP(currentgraph).lasty = -1;
return 0;
}
int
GL_SetLinestyle(linestyleid)
int linestyleid;
{
/* special case
get it when GL_Text restores a -1 linestyle */
if (linestyleid == -1) {
currentgraph->linestyle = -1;
return 0;
}
if (linestyleid < 0 || linestyleid > dispdev->numlinestyles) {
internalerror("bad linestyleid");
return 0;
}
if (currentgraph->linestyle != linestyleid) {
fprintf(plotfile, "LT %s ;", linestyle[linestyleid]);
currentgraph->linestyle = linestyleid;
}
return 0;
}
/* ARGSUSED */
int GL_SetColor(colorid)
int colorid;
{
/*va: unused: static int flag = 0;*/ /* A hack */
fprintf(plotfile, "SP %d;", colorid);
return 0;
}
int GL_Update()
{
fflush(plotfile);
return 0;
}

24
src/include/cluster.h Executable file
View File

@ -0,0 +1,24 @@
#ifndef _CLUSTER_H_
#define _CLUSTER_H_
#include <cktdefs.h>
/* Cluster definitions */
#define PORT 1234
#define TIME_PORT 1235
#define DOMAIN_NAME "cluster.multigig"
#define CLUSTER_WIDTH 4
#define TIME_HOST "time.cluster.multigig"
/* does all the setups */
extern int CLUsetup(CKTcircuit *ckt);
/* reads input pipes and sets voltages*/
/* call each time the present time is changed, ie just before NIinter*/
extern int CLUinput(CKTcircuit *ckt);
/* call after each accepted timestep, ie CKTdump */
extern int CLUoutput(CKTcircuit *ckt);
/* the time step control */
extern int CLUsync(double time,double *delta, int error);
#endif

49
src/include/cm.h Executable file
View File

@ -0,0 +1,49 @@
#ifndef CM_DEFINED
#define CM_DEFINED
/* ===========================================================================
FILE CM.h
MEMBER OF process XSPICE
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Bill Kuhn
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
This file is includes all include data in the CM package.
INTERFACES
None.
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
=========================================================================== */
#include "cmtypes.h"
#include "cmconstants.h" // K.A. wrong name
//#include "Cmconsta.h"
#include "cmproto.h"
#include "mifcmdat.h"
#endif /* CM_DEFINED */

57
src/include/cmconstants.h Executable file
View File

@ -0,0 +1,57 @@
#ifndef CMCONSTANTS_DEFINED
#define CMCONSTANTS_DEFINED
/* ===========================================================================
FILE CMconstants.h
MEMBER OF process XSPICE
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Bill Kuhn
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
This file contains constants used by code models.
INTERFACES
None.
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
=========================================================================== */
#include "miftypes.h"
/***** Define Constants *******************************************/
#define FALSE 0
#define TRUE 1
#define DC MIF_DC
#define AC MIF_AC
#define TRANSIENT MIF_TRAN
#define ANALOG MIF_ANALOG
#define EVENT MIF_EVENT_DRIVEN
#endif /* CMCONSTANTS_DEFINED */

95
src/include/cmproto.h Executable file
View File

@ -0,0 +1,95 @@
#ifndef CMPROTO_DEFINED
#define CMPROTO_DEFINED
/* ===========================================================================
FILE CMproto.h
MEMBER OF process XSPICE
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Jeff Murray, Bill Kuhn
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
This file contains ANSI C function prototypes for cm_xxx functions
called by code models.
INTERFACES
None.
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
=========================================================================== */
/* Prototypes for functions used by internal code models */
/* The actual functions reside in ../ICM/CMutil.c */
/* 12/17/90 */
#include "cmtypes.h"
void cm_climit_fcn(double in, double in_offset, double cntl_upper,
double cntl_lower, double lower_delta,
double upper_delta, double limit_range,
double gain, int percent, double *out_final,
double *pout_pin_final, double *pout_pcntl_lower_final,
double *pout_pcntl_upper_final);
void cm_smooth_corner(double x_input, double x_center, double y_center,
double domain, double lower_slope, double upper_slope,
double *y_output, double *dy_dx);
void cm_smooth_discontinuity(double x_input, double x_lower, double y_lower,
double x_upper, double y_upper,
double *y_output, double *dy_dx);
double cm_smooth_pwl(double x_input, double *x, double *y, int size,
double input_domain, double *dout_din);
double cm_analog_ramp_factor(void);
void *cm_analog_alloc(int tag, int bytes);
void *cm_analog_get_ptr(int tag, int timepoint);
int cm_analog_integrate(double integrand, double *integral, double *partial);
int cm_analog_converge(double *state);
int cm_analog_set_temp_bkpt(double time);
int cm_analog_set_perm_bkpt(double time);
void cm_analog_not_converged(void);
void cm_analog_auto_partial(void);
void *cm_event_alloc(int tag, int bytes);
void *cm_event_get_ptr(int tag, int timepoint);
int cm_event_queue(double time);
char *cm_message_get_errmsg(void);
int cm_message_send(char *msg);
double cm_netlist_get_c(void);
double cm_netlist_get_l(void);
Complex_t cm_complex_set(double real, double imag);
Complex_t cm_complex_add(Complex_t x, Complex_t y);
Complex_t cm_complex_subtract(Complex_t x, Complex_t y);
Complex_t cm_complex_multiply(Complex_t x, Complex_t y);
Complex_t cm_complex_divide(Complex_t x, Complex_t y);
#endif /* CMPROTO_DEFINED */

71
src/include/cmtypes.h Executable file
View File

@ -0,0 +1,71 @@
#ifndef CMTYPES_DEFINED
#define CMTYPES_DEFINED
/* ===========================================================================
FILE CMtypes.h
MEMBER OF process XSPICE
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Jeff Murray, Bill Kuhn
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
This file contains type definitions used by code models.
INTERFACES
None.
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
=========================================================================== */
#include "miftypes.h"
/***** Define Typedefs ********************************************/
typedef int Boolean_t;
typedef Mif_Complex_t Complex_t;
typedef enum {
ZERO, /* Normally referenced as 0 */
ONE, /* Normally referenced as 1 */
UNKNOWN, /* Unknown */
} Digital_State_t;
typedef enum {
STRONG, /* strong */
RESISTIVE, /* resistive */
HI_IMPEDANCE, /* high impedance */
UNDETERMINED, /* unknown strength */
} Digital_Strength_t;
typedef struct {
Digital_State_t state;
Digital_Strength_t strength;
} Digital_t;
#endif /* CMTYPES_DEFINED */

79
src/include/dllitf.h Executable file
View File

@ -0,0 +1,79 @@
/*
DLL load interface
(c)2000 Arpad Buermen
*/
#ifndef __DLLITF_H
#define __DLLITF_H
#include "mifproto.h"
#include "cmproto.h"
// This structure contains pointers to core SPICE OPUS functions used in CMs and UDNs.
// A pointer to this structure is passed to the dll when the dll is loaded.
struct coreInfo_t {
// MIF stuff
void ((*dllitf_MIF_INP2A)(void *, INPtables *, card *));
char * ((*dllitf_MIFgetMod)(void *, char *, INPmodel **, INPtables *));
IFvalue * ((*dllitf_MIFgetValue)(void *, char **, int, INPtables *, char **));
int ((*dllitf_MIFsetup)(SMPmatrix *, GENmodel *, CKTcircuit *, int *));
int ((*dllitf_MIFunsetup)(GENmodel *, CKTcircuit *));
int ((*dllitf_MIFload)(GENmodel *, CKTcircuit *));
int ((*dllitf_MIFmParam)(int, IFvalue *, GENmodel *));
int ((*dllitf_MIFask)(CKTcircuit *, GENinstance *, int, IFvalue *, IFvalue *));
int ((*dllitf_MIFmAsk)(CKTcircuit *, GENmodel *, int, IFvalue *));
int ((*dllitf_MIFtrunc)(GENmodel *, CKTcircuit *, double *));
int ((*dllitf_MIFconvTest)(GENmodel *, CKTcircuit *));
int ((*dllitf_MIFdelete)(GENmodel *, IFuid, GENinstance **));
int ((*dllitf_MIFmDelete)(GENmodel **, IFuid, GENmodel *));
void ((*dllitf_MIFdestroy)(GENmodel **));
char * ((*dllitf_MIFgettok)(char **));
char * ((*dllitf_MIFget_token)(char **, Mif_Token_Type_t *));
Mif_Cntl_Src_Type_t ((*dllitf_MIFget_cntl_src_type)(Mif_Port_Type_t, Mif_Port_Type_t));
char * ((*dllitf_MIFcopy)(char *));
// CM stuff
void ((*dllitf_cm_climit_fcn)(double, double, double, double, double, double,
double, double, int, double *, double *, double *,
double *));
void ((*dllitf_cm_smooth_corner)(double, double, double, double, double, double,
double *, double *));
void ((*dllitf_cm_smooth_discontinuity)(double, double, double, double, double,
double *, double *));
double ((*dllitf_cm_smooth_pwl)(double, double *, double *, int, double, double *));
double ((*dllitf_cm_analog_ramp_factor)(void));
void * ((*dllitf_cm_analog_alloc)(int, int));
void * ((*dllitf_cm_analog_get_ptr)(int, int));
int ((*dllitf_cm_analog_integrate)(double, double *, double *));
int ((*dllitf_cm_analog_converge)(double *));
int ((*dllitf_cm_analog_set_temp_bkpt)(double));
int ((*dllitf_cm_analog_set_perm_bkpt)(double));
void ((*dllitf_cm_analog_not_converged)(void));
void ((*dllitf_cm_analog_auto_partial)(void));
void * ((*dllitf_cm_event_alloc)(int, int));
void * ((*dllitf_cm_event_get_ptr)(int, int));
int ((*dllitf_cm_event_queue)(double));
char * ((*dllitf_cm_message_get_errmsg)(void));
int ((*dllitf_cm_message_send)(char *));
double ((*dllitf_cm_netlist_get_c)(void));
double ((*dllitf_cm_netlist_get_l)(void));
Complex_t ((*dllitf_cm_complex_set)(double, double));
Complex_t ((*dllitf_cm_complex_add)(Complex_t, Complex_t));
Complex_t ((*dllitf_cm_complex_subtract)(Complex_t, Complex_t));
Complex_t ((*dllitf_cm_complex_multiply)(Complex_t, Complex_t));
Complex_t ((*dllitf_cm_complex_divide)(Complex_t, Complex_t));
FILE * ((*dllitf_cm_stream_out)(void));
FILE * ((*dllitf_cm_stream_in)(void));
FILE * ((*dllitf_cm_stream_err)(void));
/*Other stuff*/
void * ((*dllitf_malloc_pj)(size_t));
void * ((*dllitf_calloc_pj)(size_t, size_t));
void * ((*dllitf_realloc_pj)(void *, size_t));
void ((*dllitf_free_pj)(void *));
char * ((*dllitf_tmalloc)(int));
char * ((*dllitf_trealloc)(char *, int));
void ((*dllitf_txfree)(char *));
};
#endif

109
src/include/enh.h Executable file
View File

@ -0,0 +1,109 @@
#ifndef ENH_HEADER
#define ENH_HEADER x
/* ===========================================================================
FILE ENH.h
MEMBER OF process XSPICE
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Bill Kuhn
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
This file contains typedefs used by the event-driven algorithm.
INTERFACES
None.
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
=========================================================================== */
#include "miftypes.h"
#include "fteinp.h"
/*
The following data is used in implementing various enhancements made to the
simulator. The main struct is dynamically allocated in ckt so that incremental additions
can be made more easily without the need to recompile multiple modules.
Allocation and initialization is done in CKTinit.c which should be the only
module needed to recompile after additions are made here.
*/
typedef enum {
ENH_ANALOG_NODE, /* An analog node */
ENH_EVENT_NODE, /* An event-driven node */
ENH_ANALOG_BRANCH, /* A branch current */
ENH_ANALOG_INSTANCE, /* An analog instance */
ENH_EVENT_INSTANCE, /* An event-driven instance */
ENH_HYBRID_INSTANCE, /* A hybrid (analog/event-driven) instance */
} Enh_Conv_Source_t;
typedef struct {
double current; /* The current dynamic breakpoint time */
double last; /* The last used dynamic breakpoint time */
} Enh_Bkpt_t;
typedef struct {
double ramptime; /* supply ramping time specified on .options */
} Enh_Ramp_t;
typedef struct {
Mif_Boolean_t last_NIiter_call; /* True if this is the last call to NIiter() */
Mif_Boolean_t report_conv_probs; /* True if conv test functions should send debug info */
} Enh_Conv_Debug_t;
typedef struct {
Mif_Boolean_t enabled; /* True if convergence limiting enabled on code models */
double abs_step; /* Minimum limiting step size */
double step; /* Fractional step amount */
} Enh_Conv_Limit_t;
typedef struct {
Mif_Boolean_t enabled; /* True if rshunt option used */
double gshunt; /* 1.0 / rshunt */
int num_nodes; /* Number of nodes in matrix */
double **diag; /* Pointers to matrix diagonals */
} Enh_Rshunt_t;
typedef struct {
Enh_Bkpt_t breakpoint; /* Data used by dynamic breakpoints */
Enh_Ramp_t ramp; /* New options added to simulator */
Enh_Conv_Debug_t conv_debug; /* Convergence debug info dumping data */
Enh_Conv_Limit_t conv_limit; /* Convergence limiting info */
Enh_Rshunt_t rshunt_data; /* Shunt conductance from nodes to ground */
} Enh_Ckt_Data_t;
void ENHreport_conv_prob(Enh_Conv_Source_t type, char *name, char *msg);
struct line *ENHtranslate_poly(struct line *deck);
#endif /* ENH_HEADER */

371
src/include/evt.h Executable file
View File

@ -0,0 +1,371 @@
#ifndef EVT_HEADER
#define EVT_HEADER x
/* ===========================================================================
FILE EVT.h
MEMBER OF process XSPICE
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Bill Kuhn
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
This file contains the definition of the evt data structure and all
its substructures. The single evt structure is housed inside of
the main 3C1 circuit structure 'ckt' and contains virtually all
information about the event-driven simulation.
INTERFACES
None.
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
=========================================================================== */
#include "mifdefs.h"
#include "mifcmdat.h"
#include "miftypes.h"
/* ************** */
/* Info structure */
/* ************** */
typedef struct Evt_Output_Info_s {
struct Evt_Output_Info_s *next; /* the next in the linked list */
int node_index; /* index into node info struct for this output */
int output_subindex; /* index into output data in node data struct */
int inst_index; /* Index of instance the port is on */
int port_index; /* Index of port the output corresponds to */
} Evt_Output_Info_t;
typedef struct Evt_Port_Info_s {
struct Evt_Port_Info_s *next; /* the next in the linked list of node info */
int inst_index; /* Index of instance the port is on */
int node_index; /* index of node the port is connected to */
char *node_name; /* name of node port is connected to */
char *inst_name; /* instance name */
char *conn_name; /* connection name on instance */
int port_num; /* port number of instance connector */
} Evt_Port_Info_t;
typedef struct Evt_Inst_Index_s {
struct Evt_Inst_Index_s *next; /* the next in the linked list */
int index; /* the value of the index */
} Evt_Inst_Index_t;
typedef struct Evt_Node_Info_s {
struct Evt_Node_Info_s *next; /* the next in the linked list */
char *name; /* Name of node in deck */
int udn_index; /* Index of the node type */
Mif_Boolean_t invert; /* True if need to make inverted copy */
int num_ports; /* Number of ports connected to this node */
int num_outputs; /* Number of outputs connected to this node */
int num_insts; /* The number of insts receiving node as input */
Evt_Inst_Index_t *inst_list; /* Linked list of indexes of these instances */
} Evt_Node_Info_t;
typedef struct Evt_Inst_Info_s {
struct Evt_Inst_Info_s *next; /* the next in the linked list of node info */
MIFinstance *inst_ptr; /* Pointer to MIFinstance struct for this instance */
} Evt_Inst_Info_t;
typedef struct {
Evt_Inst_Info_t *inst_list; /* static info about event/hybrid instances */
Evt_Node_Info_t *node_list; /* static info about event nodes */
Evt_Port_Info_t *port_list; /* static info about event ports */
Evt_Output_Info_t *output_list; /* static info about event outputs */
int *hybrid_index; /* vector of inst indexs for hybrids */
Evt_Inst_Info_t **inst_table; /* vector of pointers to elements in inst_list */
Evt_Node_Info_t **node_table; /* vector of pointers to elements in node_list */
Evt_Port_Info_t **port_table; /* vector of pointers to elements in port_list */
Evt_Output_Info_t **output_table; /* vector of pointers to elements in output_list */
} Evt_Info_t;
/* *************** */
/* Queue structure */
/* *************** */
typedef struct Evt_Inst_Event_s {
struct Evt_Inst_Event_s *next; /* the next in the linked list */
double event_time; /* Time for this event to happen */
double posted_time; /* Time at which event was entered in queue */
} Evt_Inst_Event_t;
typedef struct {
Evt_Inst_Event_t **head; /* Beginning of linked lists */
Evt_Inst_Event_t ***current; /* Beginning of pending events */
Evt_Inst_Event_t ***last_step; /* Values of 'current' at last accepted timepoint */
Evt_Inst_Event_t **free; /* Linked lists of items freed by backups */
double last_time; /* Time at which last_step was set */
double next_time; /* Earliest next event time in queue */
int num_modified; /* Number modified since last accepted timepoint */
int *modified_index; /* Indexes of modified instances */
Mif_Boolean_t *modified; /* Flags used to prevent multiple entries */
int num_pending; /* Count of number of pending events in lists */
int *pending_index; /* Indexes of pending events */
Mif_Boolean_t *pending; /* Flags used to prevent multiple entries */
int num_to_call; /* Count of number of instances that need to be called */
int *to_call_index; /* Indexes of instances to be called */
Mif_Boolean_t *to_call; /* Flags used to prevent multiple entries */
} Evt_Inst_Queue_t;
typedef struct {
int num_to_eval; /* Count of number of nodes that need to be evaluated */
int *to_eval_index; /* Indexes of nodes to be evaluated */
Mif_Boolean_t *to_eval; /* Flags used to prevent multiple entries */
int num_changed; /* Count of number of nodes that changed */
int *changed_index; /* Indexes of nodes that changed */
Mif_Boolean_t *changed; /* Flags used to prevent multiple entries */
} Evt_Node_Queue_t;
typedef struct Evt_Output_Event_s {
struct Evt_Output_Event_s *next; /* the next in the linked list */
double event_time; /* Time for this event to happen */
double posted_time; /* Time at which event was entered in queue */
Mif_Boolean_t removed; /* True if event has been deactivated */
double removed_time; /* Time at which event was deactivated */
void *value; /* The delayed value sent to this output */
} Evt_Output_Event_t;
typedef struct {
Evt_Output_Event_t **head; /* Beginning of linked lists */
Evt_Output_Event_t ***current; /* Beginning of pending events */
Evt_Output_Event_t ***last_step; /* Values of 'current' at last accepted timepoint */
Evt_Output_Event_t **free; /* Linked lists of items freed by backups */
double last_time; /* Time at which last_step was set */
double next_time; /* Earliest next event time in queue */
int num_modified; /* Number modified since last accepted timepoint */
int *modified_index; /* Indexes of modified outputs */
Mif_Boolean_t *modified; /* Flags used to prevent multiple entries */
int num_pending; /* Count of number of pending events in lists */
int *pending_index; /* Indexes of pending events */
Mif_Boolean_t *pending; /* Flags used to prevent multiple entries */
int num_changed; /* Count of number of outputs that changed */
int *changed_index; /* Indexes of outputs that changed */
Mif_Boolean_t *changed; /* Flags used to prevent multiple entries */
} Evt_Output_Queue_t;
typedef struct {
Evt_Inst_Queue_t inst; /* dynamic queue for instances */
Evt_Node_Queue_t node; /* dynamic queue of changing nodes */
Evt_Output_Queue_t output; /* dynamic queue of delayed outputs */
} Evt_Queue_t;
/* ************** */
/* Data structure */
/* ************** */
typedef struct Evt_Node_s {
struct Evt_Node_s *next; /* pointer to next in linked list */
Mif_Boolean_t op; /* true if computed from op analysis */
double step; /* DC step or time at which data was computed */
void **output_value; /* Array of outputs posted to this node */
void *node_value; /* Resultant computed from output values */
void *inverted_value; /* Inverted copy of node_value */
} Evt_Node_t;
typedef struct {
Evt_Node_t **head; /* Beginning of linked lists */
Evt_Node_t ***tail; /* Location of last item added to list */
Evt_Node_t ***last_step; /* 'tail' at last accepted timepoint */
Evt_Node_t **free; /* Linked lists of items freed by backups */
int num_modified; /* Number modified since last accepted timepoint */
int *modified_index; /* Indexes of modified nodes */
Mif_Boolean_t *modified; /* Flags used to prevent multiple entries */
Evt_Node_t *rhs; /* Location where model outputs are placed */
Evt_Node_t *rhsold; /* Location where model inputs are retrieved */
double *total_load; /* Location where total load inputs are retrieved */
} Evt_Node_Data_t;
typedef struct Evt_State_s {
struct Evt_State_s *next; /* Pointer to next state */
struct Evt_State_s *prev; /* Pointer to previous state */
double step; /* Time at which state was assigned (0 for DC) */
void *block; /* Block of memory holding all states on inst */
} Evt_State_t;
typedef struct Evt_State_Desc_s {
struct Evt_State_Desc_s *next; /* Pointer to next description */
int tag; /* Tag for this state */
int size; /* Size of this state */
int offset; /* Offset of this state into the state block */
} Evt_State_Desc_t;
typedef struct {
Evt_State_t **head; /* Beginning of linked lists */
Evt_State_t ***tail; /* Location of last item added to list */
Evt_State_t ***last_step; /* 'tail' at last accepted timepoint */
Evt_State_t **free; /* Linked lists of items freed by backups */
int num_modified; /* Number modified since last accepted timepoint */
int *modified_index; /* List of indexes modified */
Mif_Boolean_t *modified; /* Flags used to prevent multiple entries */
int *total_size; /* Total bytes for all states allocated */
Evt_State_Desc_t **desc; /* Lists of description structures */
} Evt_State_Data_t;
typedef struct Evt_Msg_s {
struct Evt_Msg_s *next; /* Pointer to next state */
Mif_Boolean_t op; /* true if output from op analysis */
double step; /* DC step or time at which message was output */
char *text; /* The value of the message text */
int port_index; /* The index of the port from which the message came */
} Evt_Msg_t;
typedef struct {
Evt_Msg_t **head; /* Beginning of linked lists */
Evt_Msg_t ***tail; /* Location of last item added to list */
Evt_Msg_t ***last_step; /* 'tail' at last accepted timepoint */
Evt_Msg_t **free; /* Linked lists of items freed by backups */
int num_modified; /* Number modified since last accepted timepoint */
int *modified_index; /* List of indexes modified */
Mif_Boolean_t *modified; /* Flags used to prevent multiple entries */
} Evt_Msg_Data_t;
typedef struct {
int op_alternations; /* Total alternations between event and analog */
int op_load_calls; /* Total load calls in DCOP analysis */
int op_event_passes; /* Total passes through event iteration loop */
int tran_load_calls; /* Total inst calls in transient analysis */
int tran_time_backups; /* Number of transient timestep cuts */
} Evt_Statistic_t;
typedef struct {
Evt_Node_Data_t *node; /* dynamic event solution vector */
Evt_State_Data_t *state; /* dynamic event instance state data */
Evt_Msg_Data_t *msg; /* dynamic event message data */
Evt_Statistic_t *statistics; /* Statistics for events, etc. */
} Evt_Data_t;
/* **************** */
/* Counts structure */
/* **************** */
typedef struct {
int num_insts; /* number of event/hybrid instances parsed */
int num_hybrids; /* number of hybrids parsed */
int num_hybrid_outputs; /* number of outputs on all hybrids parsed */
int num_nodes; /* number of event nodes parsed */
int num_ports; /* number of event ports parsed */
int num_outputs; /* number of event outputs parsed */
} Evt_Count_t;
/* **************** */
/* Limits structure */
/* **************** */
typedef struct {
int max_event_passes; /* maximum loops in attempting convergence of event nodes */
int max_op_alternations; /* maximum loops through event/analog alternation */
} Evt_Limit_t;
/* ************** */
/* Jobs structure */
/* ************** */
typedef struct {
int num_jobs; /* Number of jobs run */
char **job_name; /* Names of different jobs */
Evt_Node_Data_t **node_data; /* node_data for different jobs */
Evt_State_Data_t **state_data; /* state_data for different jobs */
Evt_Msg_Data_t **msg_data; /* messages for different jobs */
Evt_Statistic_t **statistics; /* Statistics for different jobs */
} Evt_Job_t;
/* ***************** */
/* Options structure */
/* ***************** */
typedef struct {
Mif_Boolean_t op_alternate; /* Alternate analog/event solutions in OP analysis */
} Evt_Option_t;
/* ****************** */
/* Main evt structure */
/* ****************** */
typedef struct {
Evt_Count_t counts; /* Number of insts, nodes, etc. */
Evt_Info_t info; /* Static info about insts, etc. */
Evt_Queue_t queue; /* Dynamic queued events */
Evt_Data_t data; /* Results and state data */
Evt_Limit_t limits; /* Iteration limits, etc. */
Evt_Job_t jobs; /* Data held from multiple job runs */
Evt_Option_t options; /* Data input on .options cards */
} Evt_Ckt_Data_t;
#endif /* EVT_HEADER */

124
src/include/evtproto.h Executable file
View File

@ -0,0 +1,124 @@
#ifndef EVTPROTO_HEADER
#define EVTPROTO_HEADER x
/* ===========================================================================
FILE EVTproto.h
MEMBER OF process XSPICE
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Bill Kuhn
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
This file contains ANSI C function prototypes for functions
in the event-driven simulation algorithm package.
INTERFACES
None.
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
=========================================================================== */
#include "cktdefs.h"
#include "cpstd.h"
#include "mifdefs.h"
#include "ipc.h"
/* ******************* */
/* Function Prototypes */
/* ******************* */
int EVTinit(CKTcircuit *ckt);
/*int EVTinit2(CKTcircuit *ckt);*/
void EVTtermInsert(
CKTcircuit *ckt,
MIFinstance *fast,
char *node_name,
char *type_name,
int conn_num,
int port_num,
char **err_msg);
int EVTsetup(CKTcircuit *ckt);
int EVTiter(CKTcircuit *ckt);
void EVTbackup(CKTcircuit *ckt, double new_time);
double EVTnext_time(CKTcircuit *ckt);
void EVTqueue_output(
CKTcircuit *ckt,
int output_index,
int udn_index,
Evt_Output_Event_t *new_event,
double posted_time,
double event_time);
void EVTqueue_inst(
CKTcircuit *ckt,
int inst_index,
double posted_time,
double event_time);
void EVTdequeue(CKTcircuit *ckt, double time);
int EVTload(CKTcircuit *ckt, int inst_index);
void EVTprint(wordlist *wl);
int EVTop(
CKTcircuit *ckt,
long firstmode,
long continuemode,
int max_iter,
Mif_Boolean_t first_call);
void EVTop_save(
CKTcircuit *ckt,
Mif_Boolean_t op,
double step);
void EVTnode_copy(
CKTcircuit *ckt,
int node_index,
Evt_Node_t *from,
Evt_Node_t **to);
void EVTcall_hybrids(CKTcircuit *ckt);
void EVTdump(
CKTcircuit *ckt,
Ipc_Anal_t mode,
double step);
void EVTaccept(
CKTcircuit *ckt, /* main circuit struct */
double time); /* time at which analog soln was accepted */
#endif /* EVTPROTO_HEADER */

123
src/include/evtudn.h Executable file
View File

@ -0,0 +1,123 @@
#ifndef EVTUDN_HEADER
#define EVTUDN_HEADER x
/* ===========================================================================
FILE EVTudn.h
MEMBER OF process XSPICE
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Bill Kuhn
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
This file contains the definition of "User-Defined Nodes".
These nodes are integrated into the simulator similar to the
way models are tied into SPICE 3C1, so that new node types
can be relatively easily added. The functions (required and
optional) are listed below. For optional functions, the
function can be left undefined and the pointer placed into the
Evt_Udn_Info_t structure can be specified as NULL.
Required functions:
create - allocate data structure used as inputs and outputs to code models
initialize - set structure to appropriate initial value for first use as model input
copy - make a copy of the contents into created but possibly uninitialized structure
compare - determine if two structures are equal in value
Optional functions:
dismantle - free allocations _inside_ structure (but not structure itself)
invert - invert logical value of structure
resolve - determine the resultant when multiple outputs are connected to a node
plot_val - output a real value for specified structure component for plotting purposes
print_val - output a string value for specified structure component for printing
ipc_val - output a binary data structure and size of the structure for IPC
INTERFACES
None.
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
=========================================================================== */
#include "miftypes.h" /* for Mif_Boolean_t used in udn_..._compare */
#define MALLOCED_PTR (*evt_struct_ptr)
#define STRUCT_PTR evt_struct_ptr
#define STRUCT_PTR_1 evt_struct_ptr_1
#define STRUCT_PTR_2 evt_struct_ptr_2
#define EQUAL (*evt_equal)
#define INPUT_STRUCT_PTR evt_input_struct_ptr
#define OUTPUT_STRUCT_PTR evt_output_struct_ptr
#define INPUT_STRUCT_PTR_ARRAY evt_input_struct_ptr_array
#define INPUT_STRUCT_PTR_ARRAY_SIZE evt_input_struct_ptr_array_size
#define STRUCT_MEMBER_ID evt_struct_member_id
#define PLOT_VAL (*evt_plot_val)
#define PRINT_VAL (*evt_print_val)
#define IPC_VAL (*evt_ipc_val)
#define IPC_VAL_SIZE (*evt_ipc_val_size)
#define CREATE_ARGS void **evt_struct_ptr
#define INITIALIZE_ARGS void *evt_struct_ptr
#define COMPARE_ARGS void *evt_struct_ptr_1, \
void *evt_struct_ptr_2, \
Mif_Boolean_t *evt_equal
#define COPY_ARGS void *evt_input_struct_ptr, \
void *evt_output_struct_ptr
#define DISMANTLE_ARGS void *evt_struct_ptr
#define INVERT_ARGS void *evt_struct_ptr
#define RESOLVE_ARGS int evt_input_struct_ptr_array_size, \
void **evt_input_struct_ptr_array, \
void *evt_output_struct_ptr
#define PLOT_VAL_ARGS void *evt_struct_ptr, \
char *evt_struct_member_id, \
double *evt_plot_val
#define PRINT_VAL_ARGS void *evt_struct_ptr, \
char *evt_struct_member_id, \
char **evt_print_val
#define IPC_VAL_ARGS void *evt_struct_ptr, \
void **evt_ipc_val, \
int *evt_ipc_val_size
typedef struct {
char *name;
char *description;
void ((*create)(CREATE_ARGS));
void ((*dismantle)(DISMANTLE_ARGS));
void ((*initialize)(INITIALIZE_ARGS));
void ((*invert)(INVERT_ARGS));
void ((*copy)(COPY_ARGS));
void ((*resolve)(RESOLVE_ARGS));
void ((*compare)(COMPARE_ARGS));
void ((*plot_val)(PLOT_VAL_ARGS));
void ((*print_val)(PRINT_VAL_ARGS));
void ((*ipc_val)(IPC_VAL_ARGS));
} Evt_Udn_Info_t;
extern int g_evt_num_udn_types;
extern Evt_Udn_Info_t **g_evt_udn_info;
#endif /* EVTUDN_HEADER */

122
src/include/ipc.h Executable file
View File

@ -0,0 +1,122 @@
/* $Id$
*
*/
/*============================================================================
FILE IPC.h
MEMBER OF process XSPICE
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Steve Tynor
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
Provides compatibility for the new SPICE simulator to both the MSPICE user
interface and BCP (via ATESSE v.1 style AEGIS mailboxes) and the new ATESSE
v.2 Simulator Interface and BCP (via Bsd Sockets).
INTERFACES
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
============================================================================*/
#ifndef IPC_DEFINED
#define IPC_DEFINED
#define IPC_MAX_LINE_LEN 80
#define IPC_MAX_PATH_LEN 2048
/* Known socket port for server and client to communicate: */
#define SOCKET_PORT 1064
/* Recognition character for Beginning Of Line of message: */
#define BOL_CHAR '\\'
/* Length (in bytes) of a socket message header: */
#define SOCK_MSG_HDR_LEN 5
typedef int Ipc_Boolean_t;
#define IPC_FALSE 0
#define IPC_TRUE 1
typedef struct { /* Don't change this type! It is cast elsewhere */
double real;
double imag;
} Ipc_Complex_t;
/*---------------------------------------------------------------------------*/
typedef enum {
IPC_STATUS_OK,
IPC_STATUS_NO_DATA,
IPC_STATUS_END_OF_DECK,
IPC_STATUS_EOF,
IPC_STATUS_ERROR,
} Ipc_Status_t;
#if 0
/*---------------------------------------------------------------------------*/
typedef void* Ipc_Connection_t;
/*
* A connection is an `opaque' type - the user has no access to the details of
* the implementation. Indeed the details are different depending on whether
* underlying transport mechanism is AEGIS Mailboxes or Bsd Sockets (or
* something else...)
*/
#endif
/*---------------------------------------------------------------------------*/
typedef enum {
IPC_WAIT,
IPC_NO_WAIT,
} Ipc_Wait_t;
/*---------------------------------------------------------------------------*/
typedef enum {
IPC_PROTOCOL_V1, /* >DATAB records in ATESSE v.1 format
* Handles v.1 style logfile name passing protocol
*/
IPC_PROTOCOL_V2, /* >DATAB records in ATESSE v.2 format
*/
} Ipc_Protocol_t;
/*---------------------------------------------------------------------------*/
typedef enum {
IPC_MODE_BATCH,
IPC_MODE_INTERACTIVE,
} Ipc_Mode_t;
/*---------------------------------------------------------------------------*/
typedef enum {
IPC_ANAL_DCOP,
IPC_ANAL_DCTRCURVE,
IPC_ANAL_AC,
IPC_ANAL_TRAN,
} Ipc_Anal_t;
#endif /* IPC_DEFINED */

52
src/include/ipcproto.h Executable file
View File

@ -0,0 +1,52 @@
/* IPC.c */
Ipc_Boolean_t kw_match (char *keyword , char *str );
Ipc_Status_t ipc_initialize_server (char *server_name , Ipc_Mode_t m , Ipc_Protocol_t p );
Ipc_Status_t ipc_terminate_server (void );
Ipc_Status_t ipc_get_line (char *str , int *len , Ipc_Wait_t wait );
Ipc_Status_t ipc_flush (void );
Ipc_Status_t ipc_send_line_binary (char *str , int len );
Ipc_Status_t ipc_send_line (char *str );
Ipc_Status_t ipc_send_data_prefix (double time );
Ipc_Status_t ipc_send_dcop_prefix (void );
Ipc_Status_t ipc_send_data_suffix (void );
Ipc_Status_t ipc_send_dcop_suffix (void );
Ipc_Status_t ipc_send_errchk (void );
Ipc_Status_t ipc_send_end (void );
int stuff_binary_v1 (double d1 , double d2 , int n , char *buf , int pos );
Ipc_Status_t ipc_send_double (char *tag , double value );
Ipc_Status_t ipc_send_complex (char *tag , Ipc_Complex_t value );
Ipc_Status_t ipc_send_int (char *tag , int value );
Ipc_Status_t ipc_send_boolean (char *tag , Ipc_Boolean_t value );
Ipc_Status_t ipc_send_string (char *tag , char *value );
Ipc_Status_t ipc_send_int_array (char *tag , int array_len , int *value );
Ipc_Status_t ipc_send_double_array (char *tag , int array_len , double *value );
Ipc_Status_t ipc_send_complex_array (char *tag , int array_len , Ipc_Complex_t *value );
Ipc_Status_t ipc_send_boolean_array (char *tag , int array_len , Ipc_Boolean_t *value );
Ipc_Status_t ipc_send_string_array (char *tag , int array_len , char **value );
Ipc_Status_t ipc_send_evtdict_prefix ();
Ipc_Status_t ipc_send_evtdict_suffix ();
Ipc_Status_t ipc_send_evtdata_prefix ();
Ipc_Status_t ipc_send_evtdata_suffix ();
Ipc_Status_t ipc_send_event(int, double, double, char *, void *, int);
/* IPCtiein.c */
void ipc_handle_stop (void );
void ipc_handle_returni (void );
void ipc_handle_mintime (double time );
void ipc_handle_vtrans (char *vsrc , char *dev );
void ipc_send_stdout (void );
void ipc_send_stderr (void );
Ipc_Status_t ipc_send_std_files (void );
Ipc_Boolean_t ipc_screen_name (char *name , char *mapped_name );
int ipc_get_devices (void *circuit , char *device , char ***names , double **modtypes );
void ipc_free_devices (int num_items , char **names , double *modtypes );
void ipc_check_pause_stop (void );
/* IPCaegis.c */
Ipc_Status_t ipc_transport_initialize_server (char *server_name , Ipc_Mode_t m , Ipc_Protocol_t p , char *batch_filename );
Ipc_Status_t extract_msg (char *str , int *len );
Ipc_Status_t ipc_transport_get_line (char *str , int *len , Ipc_Wait_t wait );
Ipc_Status_t ipc_transport_terminate_server (void );
Ipc_Status_t ipc_transport_send_line (char *str , int len );

96
src/include/ipctiein.h Executable file
View File

@ -0,0 +1,96 @@
/*============================================================================
FILE IPCtiein.h
MEMBER OF process XSPICE
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Bill Kuhn
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
Provides a protocol independent interface between the simulator
and the IPC method used to interface to CAE packages.
INTERFACES
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
============================================================================*/
#ifndef IPC_TIEIN_DEFINED
#define IPC_TIEIN_DEFINED
#include "ipc.h"
#include "ipcproto.h"
#define IPC_STDOUT_FILE_NAME "/usr/tmp/atesse_xspice.out"
#define IPC_STDERR_FILE_NAME "/usr/tmp/atesse_xspice.err"
/*
Ipc_Vtrans_t is used by functions that return results to translate
voltage source names to the names of the devices they monitor.
This table is built from #VTRANS cards in the incoming deck and
is provided for ATESSE 1.0 compatibility.
*/
typedef struct {
int size; /* Size of arrays */
char **vsrc_name; /* Array of voltage source name prefixes */
char **device_name; /* Array of device names the vsources map to */
} Ipc_Vtrans_t;
/*
Ipc_Tiein_t is used by the SPICE mods that take care of interprocess communications
activities.
*/
typedef struct {
Ipc_Boolean_t enabled; /* True if we are using IPC */
Ipc_Mode_t mode; /* INTERACTIVE or BATCH mode */
Ipc_Anal_t anal_type; /* DCOP, AC, ... mode */
Ipc_Boolean_t syntax_error; /* True if error occurred during parsing */
Ipc_Boolean_t run_error; /* True if error occurred during simulation */
Ipc_Boolean_t errchk_sent; /* True if #ERRCHK has been sent */
Ipc_Boolean_t returni; /* True if simulator should return currents */
double mintime; /* Minimum time between timepoints returned */
double last_time; /* Last timepoint returned */
double cpu_time; /* CPU time used during simulation */
Ipc_Boolean_t *send; /* Used by OUTinterface to determine what to send */
char *log_file; /* Path to write log file */
Ipc_Vtrans_t vtrans; /* Used by OUTinterface to translate v sources */
Ipc_Boolean_t stop_analysis; /* True if analysis should be terminated */
} Ipc_Tiein_t;
extern Ipc_Tiein_t g_ipc;
#endif /* IPC_TIEIN_DEFINED */

87
src/include/mif.h Executable file
View File

@ -0,0 +1,87 @@
#ifndef MIF
#define MIF
/* ===========================================================================
FILE MIF.h
MEMBER OF process XSPICE
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Bill Kuhn
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
This file structure definitions global data used with the MIF package.
The global data structure is used to circumvent the need to modify
argument lists in existing SPICE 3C1 functions.
INTERFACES
None.
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
=========================================================================== */
#include "miftypes.h"
#include "mifdefs.h"
#include "cktdefs.h"
typedef struct {
Mif_Boolean_t init; /* TRUE if first call to model */
Mif_Boolean_t anal_init; /* TRUE if first call for this analysis type */
Mif_Analysis_t anal_type; /* The type of analysis being performed */
Mif_Call_Type_t call_type; /* Type of call to code model - analog or event-driven */
double evt_step; /* The current DC step or time in event analysis */
} Mif_Circuit_Info_t;
typedef struct {
double current; /* The current dynamic breakpoint time */
double last; /* The last used dynamic breakpoint time */
} Mif_Bkpt_Info_t;
typedef struct {
Mif_Boolean_t global; /* Set by .option to force all models to use auto */
Mif_Boolean_t local; /* Set by individual model to request auto partials */
} Mif_Auto_Partial_t;
typedef struct {
Mif_Circuit_Info_t circuit; /* Circuit data that will be needed by MIFload */
MIFinstance *instance; /* Current instance struct */
CKTcircuit *ckt; /* The ckt struct for the circuit */
char *errmsg; /* An error msg from a cm_... function */
Mif_Bkpt_Info_t breakpoint; /* Data used by dynamic breakpoints */
Mif_Auto_Partial_t auto_partial; /* Flags to enable auto partial computations */
} Mif_Info_t;
/* These are defined in mif.c */
extern int MIFiSize;
extern int MIFmSize;
extern Mif_Info_t g_mif_info;
#endif /* MIF */

373
src/include/mifcmdat.h Executable file
View File

@ -0,0 +1,373 @@
#ifndef MIFCMDAT
#define MIFCMDAT
/* ===========================================================================
FILE MIFcmdat.h
MEMBER OF process XSPICE
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Bill Kuhn
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
This file contains the data structure definitions used by
code model and the associated MIF package.
A special preprocessor (cmpp) is used on models written by a
user to turn items like INPUT(<name>) into the appropriate structure
reference.
INTERFACES
None.
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
=========================================================================== */
#include "miftypes.h"
/* ************************************************************************** */
/*
* Pointers into matrix for a voltage input, voltage output partial
*/
typedef struct Mif_E_Ptr_s {
double *branch_poscntl; /* Branch row, positive controlling column */
double *branch_negcntl; /* Branch row, negative controlling column */
} Mif_E_Ptr_t;
/*
* Pointers into matrix for a current input, current output partial
*/
typedef struct Mif_F_Ptr_s {
double *pos_ibranchcntl; /* Positive row, controlling branch column */
double *neg_ibranchcntl; /* Negative row, controlling branch column */
} Mif_F_Ptr_t;
/*
* Pointers into matrix for a voltage input, current output partial
*/
typedef struct Mif_G_Ptr_s {
double *pos_poscntl; /* Positive row, positive controlling column */
double *pos_negcntl; /* Positive row, negative controlling column */
double *neg_poscntl; /* Negative row, positive controlling column */
double *neg_negcntl; /* Negative row, negative controlling column */
} Mif_G_Ptr_t;
/*
* Pointers into matrix for a current input, voltage output partial
*/
typedef struct Mif_H_Ptr_s {
double *branch_ibranchcntl; /* Branch row, controlling branch column */
} Mif_H_Ptr_t;
/*
* Matrix pointers associated with a particular port (of a particular type)
*/
typedef union Mif_Port_Ptr_u {
Mif_E_Ptr_t e; /* Pointers for voltage input, voltage output */
Mif_F_Ptr_t f; /* Pointers for current input, current output */
Mif_G_Ptr_t g; /* Pointers for voltage input, current output */
Mif_H_Ptr_t h; /* Pointers for current input, voltage output */
} Mif_Port_Ptr_t;
/*
* Array of matrix data pointers for particular ports in a connection
*/
typedef struct Mif_Conn_Ptr_s {
Mif_Port_Ptr_t *port; /* Data for a particular port */
} Mif_Conn_Ptr_t;
/*
* Row numbers and matrix entry pointers for loading the matrix and RHS with
* data appropriate for the particular output port and input ports.
*/
typedef struct Mif_Smp_Ptr_s {
/* Data at this level is for this connection. The Mif_Conn_Ptr_t */
/* subtree is used only if this connection is an output. It supplies */
/* the matrix pointers required for loading the partials from each */
/* input. */
/* node connection equation numbers */
int pos_node; /* Row associated with positive node */
int neg_node; /* Row associated with negative node */
/* V source branch equation numbers */
int branch; /* Row associated with V output branch */
int ibranch; /* Row associated with I input branch */
/* matrix pointers for V source output */
double *pos_branch; /* Positive node row, branch column */
double *neg_branch; /* Negative node row, branch column */
double *branch_pos; /* Branch row, positive node column */
double *branch_neg; /* Branch row, negative node column */
/* matrix pointers for the zero-valued V source associated with an I input */
double *pos_ibranch; /* Positive node row, branch column */
double *neg_ibranch; /* Negative node row, branch column */
double *ibranch_pos; /* Branch row, positive node column */
double *ibranch_neg; /* Branch row, negative node column */
/* array of pointer info required for putting partials into the matrix */
Mif_Conn_Ptr_t *input; /* Matrix pointers associated with inputs */
} Mif_Smp_Ptr_t;
/* ******************************************************************** */
/*
* Partial derivatives wrt ports of a particular input connection
*/
typedef struct Mif_Partial_s {
double *port; /* Partial wrt this port */
} Mif_Partial_t;
/*
* AC gains wrt ports of a particular input connection
*/
typedef struct Mif_AC_Gain_s {
Mif_Complex_t *port; /* AC gain wrt this port */
} Mif_AC_Gain_t;
/*
* Data used to access information in event struct in CKTcircuit struct ckt
*/
typedef struct {
int node_index; /* Index of node in event-driven structures */
int output_subindex; /* Subindex of output on node */
int port_index; /* Index of port in event-driven structures */
int output_index; /* Index of output in event-driven structures */
} Mif_Evt_Data_t;
/*
* Information about individual port(s) of a connection.
*/
typedef struct Mif_Port_Data_s {
Mif_Port_Type_t type; /* Port type - e.g. MIF_VOLTAGE, ... */
char *type_str; /* Port type in string form */
char *pos_node_str; /* Positive node identifier */
char *neg_node_str; /* Negative node identifier */
char *vsource_str; /* Voltage source identifier */
Mif_Boolean_t is_null; /* Set to true if null in SPICE deck */
Mif_Value_t input; /* The input value */
Mif_Value_t output; /* The output value */
Mif_Partial_t *partial; /* Partials for this port wrt inputs */
Mif_AC_Gain_t *ac_gain; /* AC gains for this port wrt inputs */
int old_input; /* Index into CKTstate for old input */
Mif_Boolean_t invert; /* True if state should be inverted */
Mif_Boolean_t changed; /* A new output has been assigned */
double load; /* Load factor output to this port */
double total_load; /* Total load for this port */
double delay; /* Digital delay for this output port */
char *msg; /* Message string output to port */
Mif_Smp_Ptr_t smp_data; /* Pointers used to load matrix/rhs */
Mif_Evt_Data_t evt_data; /* Data used to access evt struct */
double nominal_output; /* Saved output when doing auto partial */
} Mif_Port_Data_t;
/* ******************************************************************** */
/*
* Information in MIFinstance struct used by cm_.. support functions.
*/
typedef struct Mif_State_s { /* for cm_analog_alloc() */
int tag; /* Tag identifying this particular state */
int index; /* Index into ckt->CKTstate[i] vector */
int doubles; /* Number of doubles allocated for this state */
int bytes; /* Actual number of bytes requested by cm_analog_alloc() */
} Mif_State_t;
typedef struct Mif_Intgr_s { /* for cm_analog_integrate() */
int byte_index; /* Byte offset into state array */
} Mif_Intgr_t;
typedef struct Mif_Conv_s { /* for cm_analog_converge() */
int byte_index; /* Byte offset into state array */
double last_value; /* Value at last iteration */
} Mif_Conv_t;
/* ******************************************************************** */
/*
* Information about the circuit in which this model is simulating.
*/
typedef struct Mif_Circ_Data_s {
Mif_Boolean_t init; /* True if first call to model - a setup pass */
Mif_Analysis_t anal_type; /* Current analysis type */
Mif_Boolean_t anal_init; /* True if first call in this analysis type */
Mif_Call_Type_t call_type; /* Analog or event type call */
double time; /* Current analysis time */
double frequency; /* Current analysis frequency */
double temperature; /* Current analysis temperature */
double t[8]; /* History of last 8 analysis times t[0]=time */
} Mif_Circ_Data_t;
/*
* The structure associated with a named "connection" on the model.
*/
typedef struct Mif_Conn_Data_s {
char *name; /* Name of this connection - currently unused */
char *description; /* Description of this connection - unused */
Mif_Boolean_t is_null; /* Set to true if null in SPICE deck */
Mif_Boolean_t is_input; /* Set to true if connection is an input */
Mif_Boolean_t is_output; /* Set to true if connection is an output */
int size; /* The size of an array (1 if scalar) */
Mif_Port_Data_t **port; /* Pointer(s) to port(s) for this connection */
} Mif_Conn_Data_t;
/*
* Values for model parameters
*/
typedef struct Mif_Param_Data_s {
Mif_Boolean_t is_null; /* True if no value given on .model card */
int size; /* Size of array (1 if scalar) */
Mif_Value_t *element; /* Value of parameter(s) */
} Mif_Param_Data_t;
/*
* Values for instance variables
*/
typedef struct Mif_Inst_Var_Data_s {
int size; /* Size of array (1 if scalar) */
Mif_Value_t *element; /* Value of instance variables(s) */
} Mif_Inst_Var_Data_t;
/* ************************************************************************* */
/*
* HERE IT IS!!!
* The top level data structure passed to code models.
*/
typedef struct Mif_Private_s {
Mif_Circ_Data_t circuit; /* Information about the circuit */
int num_conn; /* Number of connections on this model */
Mif_Conn_Data_t **conn; /* Information about each connection */
int num_param; /* Number of parameters on this model */
Mif_Param_Data_t **param; /* Information about each parameter */
int num_inst_var; /* Number of instance variables */
Mif_Inst_Var_Data_t **inst_var; /* Information about each inst variable */
} Mif_Private_t;
#endif /* MIFCMDAT */

111
src/include/mifdefs.h Executable file
View File

@ -0,0 +1,111 @@
#ifndef MIFDEFS
#define MIFDEFS
/* ===========================================================================
FILE MIFdefs.h
MEMBER OF process XSPICE
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Bill Kuhn
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
This file contains (augmented) SPICE 3C1 compatible typedefs for use
with code models. These typedefs define the data structures that are
used internally to describe instances and models in the circuit
description linked lists.
INTERFACES
None.
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
=========================================================================== */
#include "mifcmdat.h"
#include "ifsim.h"
/* The per-instance data structure */
typedef struct sMIFinstance {
struct sMIFmodel *MIFmodPtr; /* backpointer to model */
struct sMIFinstance *MIFnextInstance; /* pointer to next instance of current model */
IFuid MIFname; /* pointer to character string naming this instance */
int num_conn; /* number of connections on the code model */
Mif_Conn_Data_t **conn; /* array of data structures for each connection */
int num_inst_var; /* number of instance variables on the code model */
Mif_Inst_Var_Data_t **inst_var; /* array of structs for each instance var */
int num_param; /* number of parameters on the code model */
Mif_Param_Data_t **param; /* array of structs for each parameter */
int num_state; /* Number of state tags used for this inst */
Mif_State_t *state; /* Info about states */
int num_intgr; /* Number of integrals */
Mif_Intgr_t *intgr; /* Info for integrals */
int num_conv; /* Number of things to be converged */
Mif_Conv_t *conv; /* Info for convergence things */
Mif_Boolean_t initialized; /* True if model called once already */
Mif_Boolean_t analog; /* true if this inst is analog or hybrid type */
Mif_Boolean_t event_driven; /* true if this inst is event-driven or hybrid type */
int inst_index; /* Index into inst_table in evt struct in ckt */
} MIFinstance ;
/* The per model data structure */
typedef struct sMIFmodel {
int MIFmodType; /* type index of this device type */
struct sMIFmodel *MIFnextModel; /* pointer to next possible model in linked list */
MIFinstance *MIFinstances; /* pointer to list of instances that have this model */
IFuid MIFmodName; /* pointer to character string naming this model */
int num_param; /* number of parameters on the code model */
Mif_Param_Data_t **param; /* array of structs for each parameter */
Mif_Boolean_t analog; /* true if this model is analog or hybrid type */
Mif_Boolean_t event_driven; /* true if this model is event-driven or hybrid type */
} MIFmodel;
/* NOTE: There are no device parameter tags, since the ask, mAsk, ... */
/* functions for code models work out of the generic code model structure */
#endif /* MIFDEFS */

120
src/include/mifparse.h Executable file
View File

@ -0,0 +1,120 @@
#ifndef MIFPARSE
#define MIFPARSE
/* ===========================================================================
FILE MIFparse.h
MEMBER OF process XSPICE
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Bill Kuhn
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
This file contains the information structure definitions used by the
code model parser to check for valid connections and parameters.
Structures of these types are created by the code model preprocessor
(cmpp) from the user created ifspec.ifs file.
INTERFACES
None.
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
=========================================================================== */
#include "miftypes.h"
/*
* Information about a connection used by the parser to error check input
*/
typedef struct Mif_Conn_Info_s {
char *name; /* Name of this connection */
char *description; /* Description of this connection */
Mif_Dir_t direction; /* Is this connection an input, output, or both? */
Mif_Port_Type_t default_port_type; /* The default port type */
char *default_type; /* The default type in string form */
int num_allowed_types; /* The size of the allowed type arrays */
Mif_Port_Type_t *allowed_type; /* The allowed types */
char **allowed_type_str; /* The allowed types in string form */
Mif_Boolean_t is_array; /* True if connection is an array */
Mif_Boolean_t has_lower_bound; /* True if there is an array size lower bound */
int lower_bound; /* Array size lower bound */
Mif_Boolean_t has_upper_bound; /* True if there is an array size upper bound */
int upper_bound; /* Array size upper bound */
Mif_Boolean_t null_allowed; /* True if null is allowed for this connection */
} Mif_Conn_Info_t;
/*
* Information about a parameter used by the parser to error check input
*/
typedef struct Mif_Param_Info_s {
char *name; /* Name of this parameter */
char *description; /* Description of this parameter */
Mif_Data_Type_t type; /* Is this a real, boolean, string, ... */
Mif_Boolean_t has_default; /* True if there is a default value */
Mif_Parse_Value_t default_value; /* The default value */
Mif_Boolean_t has_lower_limit; /* True if there is a lower limit */
Mif_Parse_Value_t lower_limit; /* The lower limit for this parameter */
Mif_Boolean_t has_upper_limit; /* True if there is a upper limit */
Mif_Parse_Value_t upper_limit; /* The upper limit for this parameter */
Mif_Boolean_t is_array; /* True if parameter is an array */
Mif_Boolean_t has_conn_ref; /* True if parameter is associated with a connector */
int conn_ref; /* The subscript of the associated connector */
Mif_Boolean_t has_lower_bound; /* True if there is an array size lower bound */
int lower_bound; /* Array size lower bound */
Mif_Boolean_t has_upper_bound; /* True if there is an array size upper bound */
int upper_bound; /* Array size upper bound */
Mif_Boolean_t null_allowed; /* True if null is allowed for this parameter */
} Mif_Param_Info_t;
/*
* Information about an instance parameter used by the parser to error check input
*/
typedef struct Mif_Inst_Var_Info_s {
char *name; /* Name of this instance var */
char *description; /* Description of this instance var */
Mif_Data_Type_t type; /* Is this a real, boolean, string, ... */
Mif_Boolean_t is_array; /* True if instance var is an array */
} Mif_Inst_Var_Info_t;
#endif /* MIFPARSE */

157
src/include/mifproto.h Executable file
View File

@ -0,0 +1,157 @@
#ifndef MIFPROTO
#define MIFPROTO
/* ===========================================================================
FILE MIFproto.h
MEMBER OF process XSPICE
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Bill Kuhn
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
This file contains ANSI C function prototypes for functions in the
MIF package.
INTERFACES
None.
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
=========================================================================== */
#include "ifsim.h"
#include "inpdefs.h"
#include "smpdefs.h"
#include "cktdefs.h"
#include "miftypes.h"
extern void MIF_INP2A(
void *ckt, /* circuit structure to put mod/inst structs in */
INPtables *tab, /* symbol table for node names, etc. */
card *current /* the card we are to parse */
);
extern char * MIFgetMod(
void *ckt,
char *name,
INPmodel **model,
INPtables *tab
);
extern IFvalue * MIFgetValue(
void *ckt,
char **line,
int type,
INPtables *tab,
char **err
);
extern int MIFsetup(
SMPmatrix *matrix,
GENmodel *inModel,
CKTcircuit *ckt,
int *state
);
extern int MIFload(
GENmodel *inModel,
CKTcircuit *ckt
);
extern int MIFmParam(
int param_index,
IFvalue *value,
GENmodel *inModel
);
extern int MIFask(
CKTcircuit *ckt,
GENinstance *inst,
int param_index,
IFvalue *value,
IFvalue *select
);
extern int MIFmAsk(
CKTcircuit *ckt,
GENmodel *inModel,
int param_index,
IFvalue *value
);
extern int MIFtrunc(
GENmodel *inModel,
CKTcircuit *ckt,
double *timeStep
);
extern int MIFconvTest(
GENmodel *inModel,
CKTcircuit *ckt
);
extern int MIFdelete(
GENmodel *inModel,
IFuid name,
GENinstance **inst
);
extern int MIFmDelete(
GENmodel **inModel,
IFuid modname,
GENmodel *model
);
extern void MIFdestroy(
GENmodel **inModel
);
extern char *MIFgettok(
char **s
);
extern char *MIFget_token(
char **s,
Mif_Token_Type_t *type
);
extern Mif_Cntl_Src_Type_t MIFget_cntl_src_type(
Mif_Port_Type_t in_port_type,
Mif_Port_Type_t out_port_type
);
extern char *MIFcopy(char *);
#endif /* MIFPROTO */

226
src/include/miftypes.h Executable file
View File

@ -0,0 +1,226 @@
#ifndef MIFTYPES
#define MIFTYPES
/* ===========================================================================
FILE MIFtypes.h
MEMBER OF process XSPICE
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Bill Kuhn
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
This file contains typedefs shared by several header files in
the MIF package.
INTERFACES
None.
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
=========================================================================== */
/* ***************************************************************************** */
typedef int Mif_Boolean_t;
#define MIF_FALSE 0
#define MIF_TRUE 1
typedef int Mif_Status_t;
#define MIF_OK 0
#define MIF_ERROR 1
/*
typedef enum {
MIF_OK,
MIF_ERROR,
} Mif_Status_t;
*/
/* ***************************************************************************** */
/*
* The type of call to a code model - analog or event-driven
*/
typedef enum {
MIF_ANALOG, /* Analog call */
MIF_EVENT_DRIVEN, /* Event-driven call */
} Mif_Call_Type_t;
/*
* Analysis type enumerations
*/
typedef enum {
MIF_DC, /* A DC or DCOP analysis */
MIF_AC, /* A swept AC analysis */
MIF_TRAN, /* A transient analysis */
} Mif_Analysis_t;
/*
* Port type enumerations
*/
typedef enum {
MIF_VOLTAGE, /* v - Single-ended voltage */
MIF_DIFF_VOLTAGE, /* vd - Differential voltage */
MIF_CURRENT, /* i - Single-ended current */
MIF_DIFF_CURRENT, /* id - Differential current */
MIF_VSOURCE_CURRENT, /* vnam - Voltage source current */
MIF_CONDUCTANCE, /* g - Single-ended VCIS */
MIF_DIFF_CONDUCTANCE, /* gd - Differential VCIS */
MIF_RESISTANCE, /* h - Single-ended ICVS */
MIF_DIFF_RESISTANCE, /* hd - Differential ICVS */
MIF_DIGITAL, /* d - Digital */
MIF_USER_DEFINED, /* <identifier> - Any user defined type */
} Mif_Port_Type_t;
/*
* The direction of a connector
*/
typedef enum {
MIF_IN, /* Input only */
MIF_OUT, /* Output only */
MIF_INOUT, /* Input and output (e.g. g or h type) */
} Mif_Dir_t;
/*
* The type of a parameter
*/
typedef enum {
MIF_BOOLEAN,
MIF_INTEGER,
MIF_REAL,
MIF_COMPLEX,
MIF_STRING,
} Mif_Data_Type_t;
/*
* The type of a token
*/
typedef enum {
MIF_LARRAY_TOK,
MIF_RARRAY_TOK,
MIF_LCOMPLEX_TOK,
MIF_RCOMPLEX_TOK,
MIF_PERCENT_TOK,
MIF_TILDE_TOK,
MIF_STRING_TOK,
MIF_NULL_TOK,
MIF_NO_TOK,
} Mif_Token_Type_t;
/*
* Type of controlled source
*/
typedef enum {
MIF_VCVS,
MIF_VCIS,
MIF_ICVS,
MIF_ICIS,
} Mif_Cntl_Src_Type_t;
/* ***************************************************************************** */
/*
* Complex numbers
*/
typedef struct {
double real;
double imag;
} Mif_Complex_t;
/*
* Values of different types used by the load, ... routines
*/
typedef union {
Mif_Boolean_t bvalue; /* For digital node value */
int ivalue; /* For integer parameters */
double rvalue; /* For spice node values and real parameters */
Mif_Complex_t cvalue; /* For complex parameters */
char *svalue; /* For string parameters */
void *pvalue; /* For user defined nodes */
} Mif_Value_t;
/*
* Values of different types used by the parser. Note that this is a structure
* instead of a union because we need to do initializations in the ifspec.c files for
* the models and unions cannot be initialized in any useful way in C
*
*/
typedef struct {
Mif_Boolean_t bvalue; /* For boolean values */
int ivalue; /* For integer values */
double rvalue; /* For real values */
Mif_Complex_t cvalue; /* For complex values */
char *svalue; /* For string values */
} Mif_Parse_Value_t;
#endif /* MIFTYPES */

66
src/include/multi_line.h Normal file
View File

@ -0,0 +1,66 @@
/*
* project.h
*
* Diagonalization by Successive Rotations Method
* (The Jacobi Method)
*
* Date: October 4, 1991
*
* Author: Shen Lin
*
* Copyright (C) University of California, Berkeley
*
*/
/************************************************************
*
* Macros
*
************************************************************/
#ifndef MAX
#define MAX(x, y) ((x) > (y) ? (x) : (y))
#endif
#ifndef MIN
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#endif
#ifndef ABS
#define ABS(x) ((x) >= 0 ? (x) : (-(x)))
#endif
#ifndef SGN
#define SGN(x) ((x) >= 0 ? (1.0) : (-1.0))
#endif
/************************************************************
*
* Defines
*
************************************************************/
#define MAX_DIM 16
#define Title "Diagonalization of a Symmetric matrix A (A = S^-1 D S)\n"
#define Left_deg 7 /* should be greater than or equal to 6 */
#define Right_deg 2
/************************************************************
*
* Data Structure Definitions
*
************************************************************/
typedef struct linked_list_of_max_entry{
struct linked_list_of_max_entry *next;
int row, col;
float value;
} MAXE, *MAXE_PTR;
typedef struct {
double *Poly[MAX_DIM];
double C_0[MAX_DIM];
} Mult_Out;
typedef struct {
double *Poly;
double C_0;
} Single_Out;

396
src/include/swec.h Normal file
View File

@ -0,0 +1,396 @@
/*
* project.h
*
* Timing Simulator (ESWEC)
*
* Date: October 5, 1990
*
* Author: Shen Lin
*
* Copyright (C) University of California, Berkeley
*
*/
#ifndef _SWEC_H_
#define _SWEC_H_
/************************************************************
*
* Defines
*
************************************************************/
#define MainTitle " Timing Simulator\n"
#define MAXDEVICE 4
#define MAXMOS 31500 /* suggested value */
#define MAXDD 256 /* suggested value */
#define MAXVCCS 128 /* suggested value */
#define MAXTIME 1000000
#define MAXNODE 136
#define TAB_SIZE 8192 /* originally 2048 */
#define NUM_STEPS_PER_MICRON 10 /* 0.1 micron is the smallest step */
#define MAX_FET_SIZE 80 /* largest fet in microns */
#define Vol_Step 1.0e-3 /* voltage resolution */
#define SCL 1000.0 /* voltage scaler (1V/3mv) */
#define MAX_CP_TX_LINES 4 /* max number of coupled lines in
a multiconductor line system */
/************************************************************
*
* Macro
*
************************************************************/
#ifndef MAX
#define MAX(x, y) ((x) > (y) ? (x) : (y))
#endif
#ifndef MIN
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#endif
#ifndef ABS
#define ABS(x) ((x) >= 0 ? (x) : (-(x)))
#endif
/************************************************************
*
* Data Structure Definitions
*
************************************************************/
typedef struct reglist REGLIST;
typedef struct node NODE;
typedef struct mosfet MOSFET;
typedef struct emosfet EMOSFET;
typedef struct diode DIODE;
typedef struct ediode EDIODE;
typedef struct vccs VCCS;
typedef struct evccs EVCCS;
typedef struct i_cap I_CAP;
typedef struct ei_cap EI_CAP;
typedef struct resistor RESISTOR;
typedef struct eresistor ERESISTOR;
typedef struct rline RLINE;
typedef struct erline ERLINE;
typedef struct txline TXLine;
typedef struct etxline ETXLine;
typedef struct cpline CPLine;
typedef struct ecpline ECPLine;
typedef struct bqueue BQUEUE;
typedef struct pqueue PQUEUE;
typedef struct ms_device MS_DEVICE;
typedef struct bp_device BP_DEVICE;
typedef struct dd_device DD_DEVICE;
struct mosfet{
int type; /* 1 : NMOS, 2 : PMOS */
MS_DEVICE *device; /* NULL if the nominal device model */
NODE *out_node;
NODE *in_node;
float Cs, Cd;
MOSFET *nx;
int time; /* instantaneous information */
float voltage, dvg; /* instantaneous information */
float vgN_1; /* gate voltage at previous event point */
float G; /* effective conductance at t(n) */
float effective; /* W over effective L */
int tabW; /* width in ns/um */
REGLIST *region; /* region associated with this mos */
/* NULL if driven by the node of the same region */
};
struct diode{
float Is; /* saturation current */
float Vj; /* junction potential */
double G;
NODE *in_node;
NODE *out_node;
DIODE *nx;
};
struct vccs{
float Is; /* saturation current */
NODE *in_node;
NODE *out_node;
NODE *pcv_node;
NODE *ncv_node;
DIODE *nx;
};
typedef struct {
char name[10]; /* device name */
int type; /* 1 : NMOS, 2 : PMOS */
int device_id; /* device id */
} DEVICENAME;
struct ms_device{
char name[10];
int used; /* device used in circuit flag */
float rho; /* device vsat denom param */
float alpha; /* device vsat denom vgg param */
float vt; /* device zero bias threshold voltage in mv*/
float gamma; /* device backgate bias vt param */
float fermi; /* device fermi potential in mv */
float theta; /* device backgate bias vt width param */
float mu; /* device vt width param */
float eta; /* device saturation slope */
float eta5; /* eta - 0.5 */
int pzld; /* positive lambda */
float lambda; /* channel-length modulation */
float kp; /* device conductance parameter */
float cgs0; /* gate-source overlap capacitance
per meter channel width */
float cgd0; /* gate-drain overlap capacitance
per meter channel width */
float cox; /* oxide-field capacitance
per square meter of gate area */
float cjsw; /* zero-biased junction sidewall capacitace
per meter of junction perimeter */
float cj0; /* zero-biased junction bottom capacitace
per square meter of junction area */
float keq; /* abrupt junction parameter */
float ld; /* lateral diffusion */
float *thresh;
float *sat;
float *dsat;
float *body;
float *gammod;
};
struct bp_device{
char name[10];
int type; /* 1 : NPN; 2 : PNP */
float rc; /* collector resistance */
float re; /* emitter resistance */
float rb; /* zero bias base resistance */
float Is; /* transport saturation current */
float Af; /* ideal maximum forward alpha */
float Ar; /* ideal maximum reverse alpha */
float Vje; /* B-E built-in potential */
float Vjc; /* B-C built-in potential */
};
struct dd_device{
char name[10];
float Is; /* saturation current */
float rs; /* ohmic resistance */
float Vj; /* junction potential */
};
typedef struct linked_lists_of_Bpoint{
struct linked_lists_of_Bpoint *next;
int time;
float voltage;
float slope;
} BPOINT, *BPOINTPTR;
typedef struct linked_lists_of_nodeName{
char id[24];
struct linked_lists_of_nodeName *left, *right;
NODE *nd;
} NDname, *NDnamePt;
struct node {
NDnamePt name;
EMOSFET *mptr; /* pointer to head of src/drn MOSFET list */
EMOSFET *gptr; /* pointer to head of gate MOSFET list */
EI_CAP *cptr; /* pointer to head of internodal cap list */
ERESISTOR *rptr; /* pointer to head of internodal resistor list */
ERLINE *rlptr; /* pointer to head of internodal TX line list */
ETXLine *tptr; /* pointer to head of transmission line list */
ECPLine *cplptr; /* pointer to head of coupled lines list */
EDIODE *ddptr; /* pointer to head of diode list */
EVCCS *vccsptr; /* pointer to head of VCCS list */
EVCCS *cvccsptr;/* pointer to head of controlled VCCS list */
NODE *next; /* pointer to next node */
REGLIST *region; /* region associated with this node */
NODE *base_ptr; /* group src/drn nodes into region */
/* charles 2,2 1/18/93
float V;
float dv; voltage at t(n-1) and slope at t(n)
*/
double V;
double dv;
float CL; /* grounded capacitance in F */
double gsum; /*^ sum of the equivalent conductance */
double cgsum; /*^ sum of the constant conductance */
double is; /*^ equivalent Is */
int tag; /* -2 : Vdd, -3 : Vss, -1 : initial value */
int flag; /*^ flag to show some features of the node */
PQUEUE *qptr; /*^ pointer to the entry in the queue or waiting list */
FILE *ofile; /* output file for the signal at this node */
/* NULL if not for print */
int dvtag;
};
struct reglist{
REGLIST *rnxt; /* pointer to next region */
NODE *nlist; /* node list */
MOSFET *mos;
I_CAP *cap;
RESISTOR *res;
TXLine *txl;
CPLine *cpl;
struct linked_lists_of_Bpoint *Bpoint; /* break points at primary inputs */
struct linked_lists_of_Bpoint *head; /* header of the break points at primary inputs */
int eTime; /* time when this region previously evaluated */
int DCvalue;
/* 1, 0, 2 : unknown, 3 : unchangeable 1, 4 : unchangeable 0 */
BQUEUE *prediction;
};
struct bqueue{
int key; /* time for the event to be fired, or DC weight */
BQUEUE *left;
BQUEUE *right;
BQUEUE *pred;
BQUEUE *pool;
REGLIST *region; /* region id */
};
struct pqueue {
NODE *node;
PQUEUE *next;
PQUEUE *prev;
};
struct i_cap {
NODE *in_node;
NODE *out_node;
float cap;
I_CAP *nx;
};
struct resistor {
NODE *in_node;
NODE *out_node;
float g; /* conductance */
int ifF; /* whether floating */
float g1; /* conductance for floating resistor */
RESISTOR *nx;
};
struct rline {
NODE *in_node;
NODE *out_node;
float g; /* conductance */
RLINE *nx;
};
typedef struct linked_lists_of_vi_txl{
struct linked_lists_of_vi_txl *next;
struct linked_lists_of_vi_txl *pool;
int time;
/* charles 2,2
float v_i, v_o;
float i_i, i_o;
*/
double v_i, v_o;
double i_i, i_o;
} VI_list_txl;
typedef struct linked_lists_of_vi{
struct linked_lists_of_vi *next;
struct linked_lists_of_vi *pool;
int time;
float v_i[MAX_CP_TX_LINES], v_o[MAX_CP_TX_LINES];
float i_i[MAX_CP_TX_LINES], i_o[MAX_CP_TX_LINES];
} VI_list;
typedef struct {
double c, x;
double cnv_i, cnv_o;
} TERM;
typedef struct {
int ifImg;
double aten;
TERM tm[3];
} TMS;
struct cpline {
int noL;
int ext;
float ratio[MAX_CP_TX_LINES];
float taul[MAX_CP_TX_LINES];
TMS *h1t[MAX_CP_TX_LINES][MAX_CP_TX_LINES];
TMS *h2t[MAX_CP_TX_LINES][MAX_CP_TX_LINES][MAX_CP_TX_LINES];
TMS *h3t[MAX_CP_TX_LINES][MAX_CP_TX_LINES][MAX_CP_TX_LINES];
double h1C[MAX_CP_TX_LINES][MAX_CP_TX_LINES];
double h2C[MAX_CP_TX_LINES][MAX_CP_TX_LINES][MAX_CP_TX_LINES];
double h3C[MAX_CP_TX_LINES][MAX_CP_TX_LINES][MAX_CP_TX_LINES];
double h1e[MAX_CP_TX_LINES][MAX_CP_TX_LINES][3];
NODE *in_node[MAX_CP_TX_LINES];
NODE *out_node[MAX_CP_TX_LINES];
int tag_i[MAX_CP_TX_LINES], tag_o[MAX_CP_TX_LINES];
CPLine *nx;
struct linked_lists_of_vi *vi_head;
struct linked_lists_of_vi *vi_tail;
float dc1[MAX_CP_TX_LINES], dc2[MAX_CP_TX_LINES];
};
struct txline {
int lsl; /* 1 if the line is lossless, otherwise 0 */
int ext; /* a flag, set if time step is greater than tau */
float ratio;
float taul;
double sqtCdL;
double h2_aten;
double h3_aten;
double h1C;
double h1e[3];
int ifImg;
NODE *in_node;
NODE *out_node;
int tag_i, tag_o;
TERM h1_term[3];
TERM h2_term[3];
TERM h3_term[6];
TXLine *nx;
struct linked_lists_of_vi_txl *vi_head;
struct linked_lists_of_vi_txl *vi_tail;
float dc1, dc2;
int newtp; /* flag indicating new time point */
};
struct evccs {
VCCS *vccs;
EVCCS *link;
};
struct ediode {
DIODE *dd;
EDIODE *link;
};
struct emosfet {
MOSFET *mos;
EMOSFET *link;
};
struct ei_cap {
I_CAP *cap;
EI_CAP *link;
};
struct eresistor {
RESISTOR *res;
ERESISTOR *link;
};
struct erline {
RLINE *rl;
ERLINE *link;
};
struct etxline {
TXLine *line;
ETXLine *link;
};
struct ecpline {
CPLine *line;
ECPLine *link;
};
#endif

View File

@ -0,0 +1,18 @@
## Process this file with automake to produce Makefile.in
noinst_LIBRARIES = libcpl.a
libcpl_a_SOURCES = \
cpl.c \
cpldest.c \
cplmdel.c \
cplparam.c \
cpldel.c \
cplload.c \
cplmpar.c \
cplsetup.c \
cplinit.c
INCLUDES = -I$(top_srcdir)/src/include
MAINTAINERCLEANFILES = Makefile.in

View File

@ -0,0 +1,39 @@
/**********
Copyright 1992 Regents of the University of California. All rights
reserved.
Author: 1992 Charles Hough
**********/
#include "ngspice.h"
#include <stdio.h>
#include "cpldefs.h"
#include "devdefs.h"
#include "ifsim.h"
#include "suffix.h"
IFparm CPLpTable[] = {
IOP("pos_nodes", CPL_POS_NODE, IF_VECTOR|IF_STRING, "in nodes"),
IOP("neg_nodes", CPL_NEG_NODE, IF_VECTOR|IF_STRING, "out nodes"),
IOP("dimension", CPL_DIM, IF_INTEGER, "number of coupled lines"),
IOP("length", CPL_LENGTH, IF_REAL, "length of lines"),
};
IFparm CPLmPTable[] = { /* model parameters */
IOP( "r", CPL_R, IF_REALVEC,"resistance per length"),
IOP( "l", CPL_L, IF_REALVEC,"inductance per length"),
IOP( "c", CPL_C, IF_REALVEC,"capacitance per length"),
IOP( "g", CPL_G, IF_REALVEC,"conductance per length"),
IOP( "length", CPL_length, IF_REAL,"length"),
IP( "cpl", CPL_MOD_R, IF_FLAG,"Device is a cpl model"),
};
char *CPLnames[] = {
"P+",
"P-"
};
int CPLnSize = NUMELEMS(CPLnames);
int CPLiSize = sizeof(CPLinstance);
int CPLmSize = sizeof(CPLmodel);
int CPLmPTSize = NUMELEMS(CPLmPTable);
int CPLpTSize = NUMELEMS(CPLpTable);

View File

@ -0,0 +1,97 @@
#ifndef CPL
#define CPL
#include "ifsim.h"
#include "cktdefs.h"
#include "gendefs.h"
#include "complex.h"
#include "noisedef.h"
#include "swec.h"
/* information used to describe a single instance */
typedef struct sCPLinstance {
struct sCPLmodel *CPLmodPtr; /* backpointer to model */
struct sCPLinstance *CPLnextInstance; /* pointer to next instance of
* current model*/
IFuid CPLname; /* pointer to character string naming this instance */
int dimension;
int *CPLposNodes;
int *CPLnegNodes;
double CPLlength;
int *CPLibr1;
int *CPLibr2;
CPLine *cplines; /* pointer to SWEC cplines type */
CPLine *cplines2; /* temporary pointer to SWEC cplines type */
char **in_node_names;
char **out_node_names;
double **CPLibr1Ibr1;
double **CPLibr2Ibr2;
double **CPLposIbr1;
double **CPLnegIbr2;
/* trial */
double **CPLposPos;
double **CPLnegNeg;
double **CPLposNeg;
double **CPLnegPos;
double ***CPLibr1Pos;
double ***CPLibr2Neg;
double ***CPLibr1Neg;
double ***CPLibr2Pos;
double ***CPLibr1Ibr2;
double ***CPLibr2Ibr1;
unsigned CPLibr1Given : 1;
unsigned CPLibr2Given : 1;
unsigned CPLdcGiven : 1;
unsigned CPLlengthgiven : 1;
} CPLinstance ;
/* per model data */
typedef struct sCPLmodel { /* model structure for a cpl */
int CPLmodType; /* type index of this device type */
struct sCPLmodel *CPLnextModel; /* pointer to next possible model in
* linked list */
CPLinstance * CPLinstances; /* pointer to list of instances that have this
* model */
IFuid CPLmodName; /* pointer to character string naming this model */
double *Rm;
double *Gm;
double *Lm;
double *Cm;
double length;
unsigned Rmgiven : 1;
unsigned Lmgiven : 1;
unsigned Gmgiven : 1;
unsigned Cmgiven : 1;
unsigned lengthgiven : 1;
} CPLmodel;
/* instance parameters */
#define CPL_POS_NODE 1
#define CPL_NEG_NODE 2
#define CPL_DIM 3
#define CPL_LENGTH 4
/* model parameters */
#define CPL_R 101
#define CPL_C 102
#define CPL_G 103
#define CPL_L 104
#define CPL_length 105
#define CPL_MOD_R 106
#include "cplext.h"
extern VI_list *pool_vi;
#endif /*CPL*/

View File

@ -0,0 +1,38 @@
/**********
Copyright 1992 Regents of the University of California. All rights
reserved.
Author: 1992 Charles Hough
**********/
#include "ngspice.h"
#include <stdio.h>
#include "cpldefs.h"
#include "sperror.h"
#include "suffix.h"
int
CPLdelete(inModel,name,inst)
GENmodel *inModel;
IFuid name;
GENinstance **inst;
{
CPLmodel *model = (CPLmodel *)inModel;
CPLinstance **fast = (CPLinstance **)inst;
CPLinstance **prev = NULL;
CPLinstance *here;
for( ; model ; model = model->CPLnextModel) {
prev = &(model->CPLinstances);
for(here = *prev; here ; here = *prev) {
if(here->CPLname == name || (fast && here==*fast) ) {
*prev= here->CPLnextInstance;
FREE(here);
return(OK);
}
prev = &(here->CPLnextInstance);
}
}
return(E_NODEV);
}

View File

@ -0,0 +1,34 @@
/**********
Copyright 1992 Regents of the University of California. All rights
reserved.
Author: 1992 Charles Hough
**********/
#include "ngspice.h"
#include <stdio.h>
#include "cpldefs.h"
#include "suffix.h"
void
CPLdestroy(inModel)
GENmodel **inModel;
{
CPLmodel **model = (CPLmodel **)inModel;
CPLinstance *here;
CPLinstance *prev = NULL;
CPLmodel *mod = *model;
CPLmodel *oldmod = NULL;
for( ; mod ; mod = mod->CPLnextModel) {
if(oldmod) FREE(oldmod);
oldmod = mod;
prev = (CPLinstance *)NULL;
for(here = mod->CPLinstances ; here ; here = here->CPLnextInstance) {
if(prev) FREE(prev);
prev = here;
}
if(prev) FREE(prev);
}
if(oldmod) FREE(oldmod);
*model = NULL;
}

View File

@ -0,0 +1,19 @@
#ifdef __STDC__
/* extern int CPLaccept(CKTcircuit*,GENmodel*); */
extern int CPLdelete(GENmodel*,IFuid,GENinstance**);
extern void CPLdestroy(GENmodel**);
extern int CPLload(GENmodel*,CKTcircuit*);
extern int CPLmDelete(GENmodel**,IFuid,GENmodel*);
extern int CPLmParam(int,IFvalue*,GENmodel*);
extern int CPLparam(int,IFvalue*,GENinstance*,IFvalue*);
extern int CPLsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
#else /* stdc */
/* extern int CPLaccept(); */
extern int CPLdelete();
extern void CPLdestroy();
extern int CPLload();
extern int CPLmDelete();
extern int CPLmParam();
extern int CPLparam();
extern int CPLsetup();
#endif /* stdc */

View File

@ -0,0 +1,84 @@
#include <config.h>
#include <devdefs.h>
#include "cplitf.h"
#include "cplext.h"
#include "cplinit.h"
SPICEdev CPLinfo = {
{
"CplLines",
"Simple Coupled Multiconductor Lines",
&CPLnSize,
&CPLnSize,
CPLnames,
&CPLpTSize,
CPLpTable,
&CPLmPTSize,
CPLmPTable,
#ifdef XSPICE
/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/
NULL, /* This is a SPICE device, it has no MIF info data */
0, /* This is a SPICE device, it has no MIF info data */
NULL, /* This is a SPICE device, it has no MIF info data */
0, /* This is a SPICE device, it has no MIF info data */
NULL, /* This is a SPICE device, it has no MIF info data */
0, /* This is a SPICE device, it has no MIF info data */
NULL, /* This is a SPICE device, it has no MIF info data */
/*--------------------------- End of SDB fix -------------------------*/
#endif
0
},
CPLparam,
CPLmParam,
CPLload,
CPLsetup,
NULL,
NULL,
NULL,
NULL,
NULL, /* CPLfindBranch, */
NULL,
NULL,
CPLdestroy,
#ifdef DELETES
CPLmDelete,
CPLdelete,
#else /* DELETES */
NULL,
NULL,
#endif /* DELETES */
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
&CPLiSize,
&CPLmSize
};
SPICEdev *
get_cpl_info(void)
{
return &CPLinfo;
}

View File

@ -0,0 +1,13 @@
#ifndef _CPLINIT_H
#define _CPLINIT_H
extern IFparm CPLpTable[ ];
extern IFparm CPLmPTable[ ];
extern int CPLmPTSize;
extern int CPLpTSize;
extern char *CPLnames[ ];
extern int CPLiSize;
extern int CPLmSize;
extern int CPLnSize;
#endif

View File

@ -0,0 +1,6 @@
#ifndef DEV_CPL
#define DEV_CPL
SPICEdev *get_cpl_info(void);
#endif

View File

@ -0,0 +1,890 @@
/**********
Copyright 1992 Regents of the University of California. All rights
reserved.
Author: 1992 Charles Hough
**********/
#include "ngspice.h"
#include <stdio.h>
#include "cpldefs.h"
#include "sperror.h"
#include "suffix.h"
VI_list *pool_vi;
static double ratio[MAX_CP_TX_LINES];
static VI_list *new_vi();
static void free_vi();
static int get_pvs_vi();
static int update_cnv();
static int add_new_vi();
static int right_consts();
static int update_delayed_cnv();
static int multC();
static int expC();
static int divC();
static void update_cnv_a();
static void copy_cp();
/*ARGSUSED*/
int
CPLload(inModel,ckt)
GENmodel *inModel;
CKTcircuit *ckt;
{
register CPLmodel *model = (CPLmodel *)inModel;
register CPLinstance *here;
CPLine *cp, *cp2;
int *k, *l;
int time, time2;
double h, h1, f;
int hint;
float hf;
NODE *nd;
double v, v1, g;
int cond1, i;
int noL, m, p, q;
CKTnode *node;
VI_list *vi, *vi_before;
int before, delta;
int resindex;
h = ckt->CKTdelta;
h1 = 0.5 * h;
time2 = (int) (ckt->CKTtime * 1e12);
hint = (int)(h * 1e12);
hf = (float)(h * 1e12);
time = (int) ((ckt->CKTtime - ckt->CKTdelta) * 1e12);
cond1= ckt->CKTmode & MODEDC;
for( ; model != NULL; model = model->CPLnextModel ) {
for (here = model->CPLinstances; here != NULL ;
here=here->CPLnextInstance) {
cp = here->cplines;
if (cond1 || cp->vi_head == NULL) continue;
noL = cp->noL = here->dimension;
if (cp->vi_tail->time > time) {
time = cp->vi_tail->time;
hint = time2 - time;
}
before = cp->vi_tail->time;
vi_before = cp->vi_tail;
if (time > cp->vi_tail->time) {
copy_cp(cp, here->cplines2);
add_new_vi(here, ckt, time);
delta = time - before;
for (m = 0; m < noL; m++) {
nd = cp->in_node[m];
v = vi_before->v_i[m];
v1 = nd->V = cp->vi_tail->v_i[m];
nd->dv = (v1 - v) / delta;
}
for (m = 0; m < noL; m++) {
nd = cp->out_node[m];
v = vi_before->v_o[m];
v1 = nd->V = cp->vi_tail->v_o[m];
nd->dv = (v1 - v) / delta;
}
update_cnv(cp, (float)delta);
if (cp->ext) update_delayed_cnv(cp, (float)delta);
}
}
}
model = (CPLmodel *)inModel;
/* loop through all the models */
for( ; model != NULL; model = model->CPLnextModel ) {
/* loop through all the instances of the model */
for (here = model->CPLinstances; here != NULL ;
here=here->CPLnextInstance) {
double mintaul = 123456789.0;
cp = here->cplines;
cp2 = here->cplines2;
for (i = 0; i < cp->noL; i++) {
if (mintaul > cp->taul[i]) mintaul = cp->taul[i];
}
if (mintaul < hf) {
fprintf(stderr, "your time step is too large for tau.\n");
fprintf(stderr, "please decrease max time step in .tran card.\n");
fprintf(stderr, ".tran tstep tstop tstart tmax.\n");
fprintf(stderr, "make tmax smaller than %e and try again.\n",
mintaul * 1e-12);
return (1111);
}
noL = cp->noL = here->dimension;
if (cond1) {
resindex = 0;
for (m = 0; m < noL; m++) {
if (here->CPLlengthgiven)
g = model->Rm[resindex] * here->CPLlength;
else g = model->Rm[resindex] * here->CPLmodPtr->length;
*(here->CPLposIbr1[m]) += 1.0;
*(here->CPLnegIbr2[m]) += 1.0;
*(here->CPLibr1Ibr1[m]) += 1.0;
*(here->CPLibr1Ibr2[m][m]) += 1.0;
*(here->CPLibr2Pos[m][m]) += 1.0;
*(here->CPLibr2Neg[m][m]) -= 1.0;
*(here->CPLibr2Ibr1[m][m]) -= g;
resindex = resindex + noL - m;
}
continue;
}
/* dc setup */
if (here->CPLdcGiven == 0 && !cond1) {
for (i = 0; i < cp->noL; i++) {
nd = cp->in_node[i];
for(node = ckt->CKTnodes;node; node = node->next) {
if (strcmp(nd->name->id, node->name) == 0) {
cp->dc1[i] = ckt->CKTrhsOld[node->number];
cp2->dc1[i] = nd->V = cp->dc1[i];
break;
}
}
nd = cp->out_node[i];
for(node = ckt->CKTnodes;node; node = node->next) {
if (strcmp(nd->name->id, node->name) == 0) {
cp->dc2[i] = ckt->CKTrhsOld[node->number];
cp2->dc2[i] = nd->V = cp->dc2[i];
break;
}
}
}
here->CPLdcGiven = 1;
vi = new_vi();
vi->time = 0;
{
int i, j, k, l;
for (i = 0; i < cp->noL; i++) {
for (j = 0; j < cp->noL; j++) {
TMS *tms;
double a, b;
tms = cp->h1t[i][j];
if (tms->ifImg) {
tms->tm[0].cnv_i = - cp->dc1[j] *
tms->tm[0].c / tms->tm[0].x;
tms->tm[0].cnv_o = - cp->dc2[j] *
tms->tm[0].c / tms->tm[0].x;
divC(tms->tm[1].c, tms->tm[2].c,
tms->tm[1].x, tms->tm[2].x, &a, &b);
tms->tm[1].cnv_i = - cp->dc1[j] * a;
tms->tm[1].cnv_o = - cp->dc2[j] * a;
tms->tm[2].cnv_i = - cp->dc1[j] * b;
tms->tm[2].cnv_o = - cp->dc2[j] * b;
} else
for (k = 0; k < 3; k++) {
tms->tm[k].cnv_i = - cp->dc1[j] *
tms->tm[k].c / tms->tm[k].x;
tms->tm[k].cnv_o = - cp->dc2[j] *
tms->tm[k].c / tms->tm[k].x;
}
for (l = 0; l < cp->noL; l++) {
tms = cp->h2t[i][j][l];
for (k = 0; k < 3; k++) {
tms->tm[k].cnv_i = 0.0;
tms->tm[k].cnv_o = 0.0;
}
}
for (l = 0; l < cp->noL; l++) {
tms = cp->h3t[i][j][l];
if (tms->ifImg) {
tms->tm[0].cnv_i = - cp->dc1[j] *
tms->tm[0].c / tms->tm[0].x;
tms->tm[0].cnv_o = - cp->dc2[j] *
tms->tm[0].c / tms->tm[0].x;
divC(tms->tm[1].c, tms->tm[2].c,
tms->tm[1].x, tms->tm[2].x, &a, &b);
tms->tm[1].cnv_i = - cp->dc1[j] * a;
tms->tm[1].cnv_o = - cp->dc2[j] * a;
tms->tm[2].cnv_i = - cp->dc1[j] * b;
tms->tm[2].cnv_o = - cp->dc2[j] * b;
} else
for (k = 0; k < 3; k++) {
tms->tm[k].cnv_i = - cp->dc1[j] *
tms->tm[k].c / tms->tm[k].x;
tms->tm[k].cnv_o = - cp->dc2[j] *
tms->tm[k].c / tms->tm[k].x;
}
}
}
for (i = 0; i < cp->noL; i++) {
vi->i_i[i] = vi->i_o[i] = 0.0;
vi->v_i[i] = cp->dc1[i];
vi->v_o[i] = cp->dc2[i];
}
}
vi->next = NULL;
cp->vi_tail = vi;
cp->vi_head = vi;
cp2->vi_tail = vi;
cp2->vi_head = vi;
}
}
for (m = 0; m < noL; m++) {
*(here->CPLibr1Ibr1[m]) = -1.0;
*(here->CPLibr2Ibr2[m]) = -1.0;
}
for (m = 0; m < noL; m++) {
*(here->CPLposIbr1[m]) = 1.0;
*(here->CPLnegIbr2[m]) = 1.0;
}
for (m = 0; m < noL; m++) {
for (p = 0; p < noL; p++) {
*(here->CPLibr1Pos[m][p]) =
cp->h1t[m][p]->aten + h1 * cp->h1C[m][p];
*(here->CPLibr2Neg[m][p]) =
cp->h1t[m][p]->aten + h1 * cp->h1C[m][p];
}
}
k = here->CPLibr1;
l = here->CPLibr2;
copy_cp(cp2, cp);
if (right_consts(here,cp2, time,time2,h,h1,k,l,ckt)) {
cp2->ext = 1;
for (q = 0; q < noL; q++) {
cp->ratio[q] = ratio[q];
if (ratio[q] > 0.0) {
for (m = 0; m < noL; m++) {
for (p = 0; p < noL; p++) {
if (cp->h3t[m][p][q]) {
f = ratio[q] * (h1 * cp->h3C[m][p][q] +
cp->h3t[m][p][q]->aten);
*(here->CPLibr1Neg[m][p]) = -f;
*(here->CPLibr2Pos[m][p]) = -f;
}
if (cp->h2t[m][p][q]) {
f = ratio[q] * (h1 * cp->h2C[m][p][q] +
cp->h2t[m][p][q]->aten);
*(here->CPLibr1Ibr2[m][p]) = -f;
*(here->CPLibr2Ibr1[m][p]) = -f;
}
}
}
}
}
}
else cp->ext = 0;
}
}
return(OK);
}
static void
copy_cp(new, old)
CPLine *new, *old;
{
int i, j, k, l, m;
VI_list *temp;
new->noL = m = old->noL;
new->ext = old->ext;
for (i = 0; i < m; i++) {
new->ratio[i] = old->ratio[i];
new->taul[i] = old->taul[i];
for (j = 0; j < m; j++) {
if (new->h1t[i][j] == NULL)
new->h1t[i][j] = (TMS *) malloc(sizeof (TMS));
new->h1t[i][j]->ifImg = old->h1t[i][j]->ifImg;
new->h1t[i][j]->aten = old->h1t[i][j]->aten;
new->h1C[i][j] = old->h1C[i][j];
for (k = 0; k < 3; k++) {
new->h1t[i][j]->tm[k].c = old->h1t[i][j]->tm[k].c;
new->h1t[i][j]->tm[k].x = old->h1t[i][j]->tm[k].x;
new->h1t[i][j]->tm[k].cnv_i = old->h1t[i][j]->tm[k].cnv_i;
new->h1t[i][j]->tm[k].cnv_o = old->h1t[i][j]->tm[k].cnv_o;
new->h1e[i][j][k] = old->h1e[i][j][k];
}
for (l = 0; l < m; l++) {
if (new->h2t[i][j][l] == NULL)
new->h2t[i][j][l] = (TMS *) malloc(sizeof (TMS));
new->h2t[i][j][l]->ifImg = old->h2t[i][j][l]->ifImg;
new->h2t[i][j][l]->aten = old->h2t[i][j][l]->aten;
new->h2C[i][j][l] = old->h2C[i][j][l];
new->h3C[i][j][l] = old->h3C[i][j][l];
for (k = 0; k < 3; k++) {
new->h2t[i][j][l]->tm[k].c = old->h2t[i][j][l]->tm[k].c;
new->h2t[i][j][l]->tm[k].x = old->h2t[i][j][l]->tm[k].x;
new->h2t[i][j][l]->tm[k].cnv_i
= old->h2t[i][j][l]->tm[k].cnv_i;
new->h2t[i][j][l]->tm[k].cnv_o
= old->h2t[i][j][l]->tm[k].cnv_o;
}
if (new->h3t[i][j][l] == NULL)
new->h3t[i][j][l] = (TMS *) malloc(sizeof (TMS));
new->h3t[i][j][l]->ifImg = old->h3t[i][j][l]->ifImg;
new->h3t[i][j][l]->aten = old->h3t[i][j][l]->aten;
for (k = 0; k < 3; k++) {
new->h3t[i][j][l]->tm[k].c = old->h3t[i][j][l]->tm[k].c;
new->h3t[i][j][l]->tm[k].x = old->h3t[i][j][l]->tm[k].x;
new->h3t[i][j][l]->tm[k].cnv_i
= old->h3t[i][j][l]->tm[k].cnv_i;
new->h3t[i][j][l]->tm[k].cnv_o
= old->h3t[i][j][l]->tm[k].cnv_o;
}
}
}
}
while (new->vi_head->time < old->vi_head->time) {
temp = new->vi_head;
new->vi_head = new->vi_head->next;
free_vi(temp);
}
}
static int
right_consts(here, cp, t, time, h, h1, l1, l2, ckt)
CPLinstance *here;
CPLine *cp;
int t, time;
double h, h1;
int *l1, *l2;
CKTcircuit *ckt;
{
int i, j, k, l;
double e;
double ff[MAX_CP_TX_LINES], gg[MAX_CP_TX_LINES];
double v1_i[MAX_CP_TX_LINES][MAX_CP_TX_LINES];
double v2_i[MAX_CP_TX_LINES][MAX_CP_TX_LINES];
double i1_i[MAX_CP_TX_LINES][MAX_CP_TX_LINES];
double i2_i[MAX_CP_TX_LINES][MAX_CP_TX_LINES];
double v1_o[MAX_CP_TX_LINES][MAX_CP_TX_LINES];
double v2_o[MAX_CP_TX_LINES][MAX_CP_TX_LINES];
double i1_o[MAX_CP_TX_LINES][MAX_CP_TX_LINES];
double i2_o[MAX_CP_TX_LINES][MAX_CP_TX_LINES];
int ext;
register int noL;
noL = cp->noL;
for (j = 0; j < noL; j++) {
register double ff1;
ff[j] = 0.0;
gg[j] = 0.0;
for (k = 0; k < noL; k++)
if (cp->h1t[j][k]) {
if (cp->h1t[j][k]->ifImg) {
double er, ei, a, b, a1, b1;
TMS *tms;
tms = cp->h1t[j][k];
cp->h1e[j][k][0] = e = exp((double) tms->tm[0].x * h);
expC(tms->tm[1].x, tms->tm[2].x, h, &er, &ei);
cp->h1e[j][k][1] = er;
cp->h1e[j][k][2] = ei;
ff1 = tms->tm[0].c * e * h1;
ff[j] -= tms->tm[0].cnv_i * e;
gg[j] -= tms->tm[0].cnv_o * e;
ff[j] -= ff1 * cp->in_node[k]->V;
gg[j] -= ff1 * cp->out_node[k]->V;
multC(tms->tm[1].c, tms->tm[2].c, er, ei, &a1, &b1);
multC(tms->tm[1].cnv_i, tms->tm[2].cnv_i, er, ei, &a, &b);
ff[j] -= 2.0 * (a1 * h1 * cp->in_node[k]->V + a);
multC(tms->tm[1].cnv_o, tms->tm[2].cnv_o, er, ei, &a, &b);
gg[j] -= 2.0 * (a1 * h1 * cp->out_node[k]->V + a);
} else {
ff1 = 0.0;
for (i = 0; i < 3; i++) {
cp->h1e[j][k][i] = e = exp((double) cp->h1t[j][k]->tm[i].x * h);
ff1 -= cp->h1t[j][k]->tm[i].c * e;
ff[j] -= cp->h1t[j][k]->tm[i].cnv_i * e;
gg[j] -= cp->h1t[j][k]->tm[i].cnv_o * e;
}
ff[j] += ff1 * h1 * cp->in_node[k]->V;
gg[j] += ff1 * h1 * cp->out_node[k]->V;
}
}
}
ext = get_pvs_vi(t, time, cp, v1_i, v2_i, i1_i, i2_i,
v1_o, v2_o, i1_o, i2_o);
for (j = 0; j < noL; j++) { /** current eqn **/
register TERM *tm;
for (k = 0; k < noL; k++) /** node voltage **/
for (l = 0; l < noL; l++) /** different mode **/
if (cp->h3t[j][k][l]) {
if (cp->h3t[j][k][l]->ifImg) {
double er, ei, a, b, a1, b1, a2, b2;
register TMS *tms;
tms = cp->h3t[j][k][l];
expC(tms->tm[1].x, tms->tm[2].x, h, &er, &ei);
a2 = h1 * tms->tm[1].c;
b2 = h1 * tms->tm[2].c;
a = tms->tm[1].cnv_i;
b = tms->tm[2].cnv_i;
multC(a, b, er, ei, &a, &b);
multC(a2, b2, (double) v1_i[l][k] * er + v2_i[l][k], (double) v1_i[l][k] * ei, &a1, &b1);
tms->tm[1].cnv_i = a + a1;
tms->tm[2].cnv_i = b + b1;
a = tms->tm[1].cnv_o;
b = tms->tm[2].cnv_o;
multC(a, b, er, ei, &a, &b);
multC(a2, b2, (double) v1_o[l][k] * er + v2_o[l][k], (double) v1_o[l][k] * ei, &a1, &b1);
tms->tm[1].cnv_o = a + a1;
tms->tm[2].cnv_o = b + b1;
tm = &(tms->tm[0]);
e = exp((double) tm->x * h);
tm->cnv_i = tm->cnv_i * e + h1 * tm->c *
(v1_i[l][k] * e + v2_i[l][k]);
tm->cnv_o = tm->cnv_o * e + h1 * tm->c *
(v1_o[l][k] * e + v2_o[l][k]);
ff[j] += tms->aten * v2_o[l][k] + tm->cnv_o +
2.0 * tms->tm[1].cnv_o;
gg[j] += tms->aten * v2_i[l][k] + tm->cnv_i +
2.0 * tms->tm[1].cnv_i;
} else {
for (i = 0; i < 3; i++) { /** 3 poles **/
tm = &(cp->h3t[j][k][l]->tm[i]);
e = exp((double) tm->x * h);
tm->cnv_i = tm->cnv_i * e + h1 * tm->c * (v1_i[l][k] * e + v2_i[l][k]);
tm->cnv_o = tm->cnv_o * e + h1 * tm->c * (v1_o[l][k] * e + v2_o[l][k]);
ff[j] += tm->cnv_o;
gg[j] += tm->cnv_i;
}
ff[j] += cp->h3t[j][k][l]->aten * v2_o[l][k];
gg[j] += cp->h3t[j][k][l]->aten * v2_i[l][k];
}
}
for (k = 0; k < noL; k++) /** line current **/
for (l = 0; l < noL; l++) /** different mode **/
if (cp->h2t[j][k][l]) {
if (cp->h2t[j][k][l]->ifImg) {
double er, ei, a, b, a1, b1, a2, b2;
register TMS *tms;
tms = cp->h2t[j][k][l];
expC(tms->tm[1].x, tms->tm[2].x, h, &er, &ei);
a2 = h1 * tms->tm[1].c;
b2 = h1 * tms->tm[2].c;
a = tms->tm[1].cnv_i;
b = tms->tm[2].cnv_i;
multC(a, b, er, ei, &a, &b);
multC(a2, b2, (double) i1_i[l][k] * er + i2_i[l][k], (double) i1_i[l][k] * ei, &a1, &b1);
tms->tm[1].cnv_i = a + a1;
tms->tm[2].cnv_i = b + b1;
a = tms->tm[1].cnv_o;
b = tms->tm[2].cnv_o;
multC(a, b, er, ei, &a, &b);
multC(a2, b2, (double) i1_o[l][k] * er + i2_o[l][k], (double) i1_o[l][k] * ei, &a1, &b1);
tms->tm[1].cnv_o = a + a1;
tms->tm[2].cnv_o = b + b1;
tm = &(tms->tm[0]);
e = exp((double) tm->x * h);
tm->cnv_i = tm->cnv_i * e + h1 * tm->c *
(i1_i[l][k] * e + i2_i[l][k]);
tm->cnv_o = tm->cnv_o * e + h1 * tm->c *
(i1_o[l][k] * e + i2_o[l][k]);
ff[j] += tms->aten * i2_o[l][k] + tm->cnv_o +
2.0 * tms->tm[1].cnv_o;
gg[j] += tms->aten * i2_i[l][k] + tm->cnv_i +
2.0 * tms->tm[1].cnv_i;
} else {
for (i = 0; i < 3; i++) { /** 3 poles **/
tm = &(cp->h2t[j][k][l]->tm[i]);
e = exp((double) tm->x * h);
tm->cnv_i = tm->cnv_i * e + h1 * tm->c * (i1_i[l][k] * e + i2_i[l][k]);
tm->cnv_o = tm->cnv_o * e + h1 * tm->c * (i1_o[l][k] * e + i2_o[l][k]);
ff[j] += tm->cnv_o;
gg[j] += tm->cnv_i;
}
ff[j] += cp->h2t[j][k][l]->aten * i2_o[l][k];
gg[j] += cp->h2t[j][k][l]->aten * i2_i[l][k];
}
}
}
for (i = 0; i < noL; i++) {
*(ckt->CKTrhs + l1[i]) = ff[i];
*(ckt->CKTrhs + l2[i]) = gg[i];
}
return(ext);
}
static int
update_cnv(cp, h)
CPLine *cp;
float h;
{
int i, j, k;
register int noL;
double ai, bi, ao, bo;
double e, t;
register TMS *tms;
register TERM *tm;
noL = cp->noL;
for (j = 0; j < noL; j++)
for (k = 0; k < noL; k++) {
ai = cp->in_node[k]->V;
ao = cp->out_node[k]->V;
bi = cp->in_node[k]->dv;
bo = cp->out_node[k]->dv;
if (cp->h1t[j][k]) {
if (cp->h1t[j][k]->ifImg) {
tms = cp->h1t[j][k];
if (tms == NULL)
continue;
tm = &(tms->tm[0]);
e = cp->h1e[j][k][0];
t = tm->c / tm->x;
update_cnv_a(tms, h, ai, ao, ai - bi * h, ao - bo * h,
cp->h1e[j][k][1], cp->h1e[j][k][2]);
bi *= t;
bo *= t;
tm->cnv_i = (tm->cnv_i - bi*h) * e + (e - 1.0)*(ai*t +
1.0e+12*bi/tm->x);
tm->cnv_o = (tm->cnv_o - bo*h) * e + (e - 1.0)*(ao*t +
1.0e+12*bo/tm->x);
} else
for (i = 0; i < 3; i++) {
tm = &(cp->h1t[j][k]->tm[i]);
e = cp->h1e[j][k][i];
t = tm->c / tm->x;
bi *= t;
bo *= t;
tm->cnv_i = (tm->cnv_i - bi*h) * e + (e - 1.0)*(ai*t + 1.0e+12*bi/tm->x);
tm->cnv_o = (tm->cnv_o - bo*h) * e + (e - 1.0)*(ao*t + 1.0e+12*bo/tm->x);
}
}
}
return 0;
}
static VI_list
*new_vi()
{
VI_list *q;
if (pool_vi) {
q = pool_vi;
pool_vi = pool_vi->pool;
return(q);
} else return((VI_list *) malloc (sizeof (VI_list)));
}
static void
free_vi(q)
VI_list *q;
{
q->pool = pool_vi;
pool_vi = q;
}
static int
add_new_vi(here, ckt, time)
CPLinstance *here;
CKTcircuit *ckt;
int time;
{
VI_list *vi;
register int i, noL;
CPLine *cp, *cp2;
cp = here->cplines;
cp2 = here->cplines2;
vi = new_vi();
vi->time = time;
noL = cp->noL;
for (i = 0; i < noL; i++) {
/*
vi->v_i[i] = cp->in_node[i]->V;
vi->v_o[i] = cp->out_node[i]->V;
*/
vi->v_i[i] = *(ckt->CKTrhsOld + here->CPLposNodes[i]);
vi->v_o[i] = *(ckt->CKTrhsOld + here->CPLnegNodes[i]);
vi->i_i[i] = *(ckt->CKTrhsOld + here->CPLibr1[i]);
vi->i_o[i] = *(ckt->CKTrhsOld + here->CPLibr2[i]);
}
cp->vi_tail->next = vi;
cp2->vi_tail->next = vi;
vi->next = NULL;
cp->vi_tail = vi;
cp2->vi_tail = vi;
return(1);
}
static int
get_pvs_vi(t1, t2, cp, v1_i, v2_i, i1_i, i2_i, v1_o, v2_o, i1_o, i2_o)
CPLine *cp;
int t1, t2;
double v1_i[MAX_CP_TX_LINES][MAX_CP_TX_LINES];
double v2_i[MAX_CP_TX_LINES][MAX_CP_TX_LINES];
double i1_i[MAX_CP_TX_LINES][MAX_CP_TX_LINES];
double i2_i[MAX_CP_TX_LINES][MAX_CP_TX_LINES];
double v1_o[MAX_CP_TX_LINES][MAX_CP_TX_LINES];
double v2_o[MAX_CP_TX_LINES][MAX_CP_TX_LINES];
double i1_o[MAX_CP_TX_LINES][MAX_CP_TX_LINES];
double i2_o[MAX_CP_TX_LINES][MAX_CP_TX_LINES];
{
double ta[MAX_CP_TX_LINES], tb[MAX_CP_TX_LINES];
register VI_list *vi, *vi1;
register double f;
register int i, j;
int mini = -1;
double minta = 123456789.0;
int ext = 0;
register int noL;
noL = cp->noL;
for (i = 0; i < noL; i++) {
ta[i] = t1 - cp->taul[i];
tb[i] = t2 - cp->taul[i];
if (ta[i] < minta) {
minta = ta[i];
mini = i;
}
}
for (i = 0; i < noL; i++) {
ratio[i] = 0.0;
if (tb[i] <= 0) {
for (j = 0; j < noL; j++) {
i1_i[i][j] = i2_i[i][j] = i1_o[i][j] = i2_o[i][j] = 0.0;
v1_i[i][j] = v2_i[i][j] = cp->dc1[j];
v1_o[i][j] = v2_o[i][j] = cp->dc2[j];
}
} else {
if (ta[i] <= 0) {
for (j = 0; j < noL; j++) {
i1_i[i][j] = i1_o[i][j] = 0.0;
v1_i[i][j] = cp->dc1[j];
v1_o[i][j] = cp->dc2[j];
}
vi1 = cp->vi_head;
vi = vi1->next;
} else {
vi1 = cp->vi_head;
for (vi = vi1->next; vi->time < ta[i]; ) {
/* if (i == mini)
free_vi(vi1); */
vi1 = vi;
/* new */
vi = vi->next;
if (vi == NULL) goto errordetect;
}
f = (ta[i] - vi1->time) / (vi->time - vi1->time);
for (j = 0; j < noL; j++) {
v1_i[i][j] = vi1->v_i[j] + f * (vi->v_i[j] - vi1->v_i[j]);
v1_o[i][j] = vi1->v_o[j] + f * (vi->v_o[j] - vi1->v_o[j]);
i1_i[i][j] = vi1->i_i[j] + f * (vi->i_i[j] - vi1->i_i[j]);
i1_o[i][j] = vi1->i_o[j] + f * (vi->i_o[j] - vi1->i_o[j]);
}
if (i == mini)
cp->vi_head = vi1;
}
if (tb[i] > t1) {
/*
fprintf(stderr, "pvs: time = %d\n", t2);
*/
ext = 1;
ratio[i] = f = (tb[i] - t1) / (t2 - t1);
if (vi)
for (; vi->next; vi = vi->next);
else
vi = vi1;
f = 1 - f;
for (j = 0; j < noL; j++) {
v2_i[i][j] = vi->v_i[j] * f;
v2_o[i][j] = vi->v_o[j] * f;
i2_i[i][j] = vi->i_i[j] * f;
i2_o[i][j] = vi->i_o[j] * f;
}
} else {
for (; vi->time < tb[i];) {
vi1 = vi;
/* new */
vi = vi->next;
if (vi == NULL) goto errordetect;
}
f = (tb[i] - vi1->time) / (vi->time - vi1->time);
for (j = 0; j < noL; j++) {
v2_i[i][j] = vi1->v_i[j] + f * (vi->v_i[j] - vi1->v_i[j]);
v2_o[i][j] = vi1->v_o[j] + f * (vi->v_o[j] - vi1->v_o[j]);
i2_i[i][j] = vi1->i_i[j] + f * (vi->i_i[j] - vi1->i_i[j]);
i2_o[i][j] = vi1->i_o[j] + f * (vi->i_o[j] - vi1->i_o[j]);
}
}
}
}
return(ext);
errordetect:
fprintf(stderr, "your maximum time step is too large for tau.\n");
fprintf(stderr, "decrease max time step in .tran card and try again\n");
exit(0);
}
static int
update_delayed_cnv(cp, h)
CPLine *cp;
float h;
{
int i, j, k;
float *ratio;
register double f;
register VI_list *vi;
register TMS *tms;
register int noL;
h *= 0.5e-12;
ratio = cp->ratio;
vi = cp->vi_tail;
noL = cp->noL;
for (k = 0; k < noL; k++) /* mode */
if (ratio[k] > 0.0)
for (i = 0; i < noL; i++) /* current eqn */
for (j = 0; j < noL; j++) {
tms = cp->h3t[i][j][k];
if (tms == NULL)
continue;
f = h * ratio[k] * vi->v_i[j];
tms->tm[0].cnv_i += f * tms->tm[0].c;
tms->tm[1].cnv_i += f * tms->tm[1].c;
tms->tm[2].cnv_i += f * tms->tm[2].c;
f = h * ratio[k] * vi->v_o[j];
tms->tm[0].cnv_o += f * tms->tm[0].c;
tms->tm[1].cnv_o += f * tms->tm[1].c;
tms->tm[2].cnv_o += f * tms->tm[2].c;
tms = cp->h2t[i][j][k];
f = h * ratio[k] * vi->i_i[j];
tms->tm[0].cnv_i += f * tms->tm[0].c;
tms->tm[1].cnv_i += f * tms->tm[1].c;
tms->tm[2].cnv_i += f * tms->tm[2].c;
f = h * ratio[k] * vi->i_o[j];
tms->tm[0].cnv_o += f * tms->tm[0].c;
tms->tm[1].cnv_o += f * tms->tm[1].c;
tms->tm[2].cnv_o += f * tms->tm[2].c;
}
return(1);
}
static int expC(ar, ai, h, cr, ci)
double ar, ai, *cr, *ci;
double h;
{
double e, cs, si;
e = exp((double) ar * h);
cs = cos((double) ai * h);
si = sin((double) ai * h);
*cr = e * cs;
*ci = e * si;
return(1);
}
static int multC(ar, ai, br, bi, cr, ci)
double ar, ai, br, bi;
double *cr, *ci;
{
register double tp;
tp = ar*br - ai*bi;
*ci = ar*bi+ai*br;
*cr = tp;
return (1);
}
static void
update_cnv_a(tms, h, ai, ao, bi, bo, er, ei)
TMS *tms;
float h;
double ai, bi, ao, bo;
double er, ei;
{
double a, b, a1, b1;
h *= 0.5e-12;
multC(tms->tm[1].c, tms->tm[2].c, er, ei, &a1, &b1);
multC(tms->tm[1].cnv_i, tms->tm[2].cnv_i, er, ei, &a, &b);
tms->tm[1].cnv_i = a + h * (a1 * bi + ai * tms->tm[1].c);
tms->tm[2].cnv_i = b + h * (b1 * bi + ai * tms->tm[2].c);
multC(tms->tm[1].cnv_o, tms->tm[2].cnv_o, er, ei, &a, &b);
tms->tm[1].cnv_o = a + h * (a1 * bo + ao * tms->tm[1].c);
tms->tm[2].cnv_o = b + h * (b1 * bo + ao * tms->tm[2].c);
}
static int divC(ar, ai, br, bi, cr, ci)
double ar, ai, br, bi;
double *cr, *ci;
{
double t;
t = br*br + bi*bi;
*cr = (ar*br + ai*bi) / t;
*ci = (ai*br - ar*bi) / t;
return(1);
}

View File

@ -0,0 +1,45 @@
/**********
Copyright 1992 Regents of the University of California. All rights
reserved.
Author: 1992 Charles Hough
**********/
#include "ngspice.h"
#include <stdio.h>
#include "cpldefs.h"
#include "sperror.h"
#include "suffix.h"
int
CPLmDelete(inModel,modname,kill)
GENmodel **inModel;
IFuid modname;
GENmodel *kill;
{
CPLmodel **model = (CPLmodel **)inModel;
CPLmodel *modfast = (CPLmodel *)kill;
CPLinstance *here;
CPLinstance *prev = NULL;
CPLmodel **oldmod;
oldmod = model;
for( ; *model ; model = &((*model)->CPLnextModel)) {
if( (*model)->CPLmodName == modname ||
(modfast && *model == modfast) ) goto delgot;
oldmod = model;
}
return(E_NOMOD);
delgot:
*oldmod = (*model)->CPLnextModel; /* cut deleted device out of list */
for(here = (*model)->CPLinstances ; here ; here = here->CPLnextInstance) {
if(prev) FREE(prev);
prev = here;
}
if(prev) FREE(prev);
FREE(*model);
return(OK);
}

View File

@ -0,0 +1,51 @@
/**********
Copyright 1992 Regents of the University of California. All rights
reserved.
Author: 1992 Charles Hough
**********/
#include "ngspice.h"
#include <stdio.h>
#include "const.h"
#include "ifsim.h"
#include "cpldefs.h"
#include "sperror.h"
#include "suffix.h"
int
CPLmParam(param,value,inModel)
int param;
IFvalue *value;
GENmodel *inModel;
{
register CPLmodel *model = (CPLmodel *)inModel;
switch(param) {
case CPL_R:
model->Rm = value->v.vec.rVec;
model->Rmgiven = TRUE;
break;
case CPL_L:
model->Lm = value->v.vec.rVec;
model->Lmgiven = TRUE;
break;
case CPL_G:
model->Gm = value->v.vec.rVec;
model->Gmgiven = TRUE;
break;
case CPL_C:
model->Cm = value->v.vec.rVec;
model->Cmgiven = TRUE;
break;
case CPL_length:
model->length = value->rValue;
model->lengthgiven = TRUE;
break;
case CPL_MOD_R:
break;
default:
return(E_BADPARM);
}
return(OK);
}

View File

@ -0,0 +1,45 @@
/**********
Copyright 1992 Regents of the University of California. All rights
reserved.
Author: 1992 Charles Hough
**********/
#include "ngspice.h"
#include <stdio.h>
#include "const.h"
#include "ifsim.h"
#include "cpldefs.h"
#include "sperror.h"
#include "suffix.h"
/* ARGSUSED */
int
CPLparam(param,value,inst,select)
int param;
IFvalue *value;
GENinstance *inst;
IFvalue *select;
{
CPLinstance *here = (CPLinstance *)inst;
switch(param) {
case CPL_POS_NODE:
here->in_node_names = value->v.vec.sVec;
break;
case CPL_NEG_NODE:
here->out_node_names = value->v.vec.sVec;
break;
case CPL_DIM:
here->dimension = value->iValue;
break;
case CPL_LENGTH:
here->CPLlength = value->rValue;
here->CPLlengthgiven = TRUE;
break;
default:
return(E_BADPARM);
}
return(OK);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,21 @@
## Process this file with automake to produce Makefile.in
noinst_LIBRARIES = libtxl.a
libtxl_a_SOURCES = \
txl.c \
txlask.c \
txldest.c \
txlload.c \
txlmdel.c \
txlparam.c \
txlacct.c \
txldel.c \
txlmask.c \
txlmpar.c \
txlsetup.c \
txlinit.c
INCLUDES = -I$(top_srcdir)/src/include
MAINTAINERCLEANFILES = Makefile.in

View File

@ -0,0 +1,38 @@
/**********
Copyright 1992 Regents of the University of California. All rights
reserved.
Author: 1992 Charles Hough
**********/
#include "ngspice.h"
#include <stdio.h>
#include "txldefs.h"
#include "devdefs.h"
#include "ifsim.h"
#include "suffix.h"
IFparm TXLpTable[] = {
IP("pos_node", TXL_IN_NODE, IF_INTEGER,"Positive node of txl"),
IP("neg_node", TXL_OUT_NODE, IF_INTEGER,"Negative node of txl"),
IOP("length", TXL_LENGTH, IF_REAL,"length of line"),
};
IFparm TXLmPTable[] = { /* model parameters */
IOP( "r", TXL_R, IF_REAL,"resistance per length"),
IOP( "l", TXL_L, IF_REAL,"inductance per length"),
IOP( "c", TXL_C, IF_REAL,"capacitance per length"),
IOP( "g", TXL_G, IF_REAL,"conductance per length"),
IOP( "length", TXL_length, IF_REAL,"length"),
IP( "txl", TXL_MOD_R, IF_FLAG,"Device is a txl model"),
};
char *TXLnames[] = {
"Y+",
"Y-"
};
int TXLnSize = NUMELEMS(TXLnames);
int TXLiSize = sizeof(TXLinstance);
int TXLmSize = sizeof(TXLmodel);
int TXLmPTSize = NUMELEMS(TXLmPTable);
int TXLpTSize = NUMELEMS(TXLpTable);

View File

@ -0,0 +1,76 @@
/**********
Copyright 1992 Regents of the University of California. All rights
reserved.
Author: 1992 Charles Hough
**********/
#include "ngspice.h"
#include <stdio.h>
#include <math.h>
#include "cktdefs.h"
#include "txldefs.h"
#include "sperror.h"
#include "suffix.h"
int
TXLaccept(ckt,inModel)
register CKTcircuit *ckt;
GENmodel *inModel;
/* set up the breakpoint table.
*/
{
register TXLmodel *model = (TXLmodel *)inModel;
register TXLinstance *here;
int hint;
double h, v, v1;
NODE *nd;
TXLine *tx;
/* loop through all the voltage source models */
for( ; model != NULL; model = model->TXLnextModel ) {
/* loop through all the instances of the model */
for (here = model->TXLinstances; here != NULL ;
here=here->TXLnextInstance) {
h = ckt->CKTdelta;
hint = (int) (h * 1e12);
if (hint != 0) {
tx = here->txline;
nd = tx->in_node;
if (nd->dvtag == 0) {
v = nd->V;
v1 = nd->V = *(ckt->CKTrhs + here->TXLposNode);
nd->dv = (v1 - v) / hint;
nd->dvtag = 1;
}
nd = tx->out_node;
if (nd->dvtag == 0) {
v = nd->V;
v1 = nd->V = *(ckt->CKTrhs + here->TXLnegNode);
nd->dv = (v1 - v) / hint;
nd->dvtag = 1;
}
}
else {
/* can't happen. */
printf("zero h detected\n");
exit(1);
}
}
}
model = (TXLmodel *)inModel;
for( ; model != NULL; model = model->TXLnextModel ) {
for (here = model->TXLinstances; here != NULL ;
here=here->TXLnextInstance) {
nd = here->txline->in_node;
nd->dvtag = 0;
nd = here->txline->out_node;
nd->dvtag = 0;
}
}
return(OK);
}

View File

@ -0,0 +1,43 @@
/**********
Copyright 1992 Regents of the University of California. All rights
reserved.
Author: 1992 Charles Hough
**********/
#include "ngspice.h"
#include <stdio.h>
#include <math.h>
#include "const.h"
#include "txldefs.h"
#include "ifsim.h"
#include "cktdefs.h"
#include "sperror.h"
#include "suffix.h"
/*ARGSUSED*/
int
TXLask(ckt,inst,which,value,select)
CKTcircuit *ckt;
GENinstance *inst;
int which;
IFvalue *value;
IFvalue *select;
{
TXLinstance *fast = (TXLinstance *)inst;
switch(which) {
case TXL_OUT_NODE:
value->iValue = fast->TXLnegNode;
return(OK);
case TXL_IN_NODE:
value->iValue = fast->TXLposNode;
return(OK);
case TXL_LENGTH:
value->rValue = fast->TXLlength;
return(OK);
default:
return(E_BADPARM);
}
/* NOTREACHED */
}

View File

@ -0,0 +1,92 @@
#ifndef TXL
#define TXL
#include "ifsim.h"
#include "cktdefs.h"
#include "gendefs.h"
#include "complex.h"
#include "noisedef.h"
#include "swec.h"
/* information used to describe a single instance */
typedef struct sTXLinstance {
struct sTXLmodel *TXLmodPtr; /* backpointer to model */
struct sTXLinstance *TXLnextInstance; /* pointer to next instance of
* current model*/
IFuid TXLname; /* pointer to character string naming this instance */
int TXLposNode;
int TXLnegNode;
double TXLlength;
int TXLibr1;
int TXLibr2;
TXLine *txline; /* pointer to SWEC txline type */
TXLine *txline2; /* pointer to SWEC txline type. temporary storage */
char *in_node_name;
char *out_node_name;
double *TXLposPosptr;
double *TXLposNegptr;
double *TXLnegPosptr;
double *TXLnegNegptr;
double *TXLibr1Posptr;
double *TXLibr2Negptr;
double *TXLposIbr1ptr;
double *TXLnegIbr2ptr;
double *TXLibr1Negptr;
double *TXLibr2Posptr;
double *TXLibr1Ibr1ptr;
double *TXLibr2Ibr2ptr;
double *TXLibr1Ibr2ptr;
double *TXLibr2Ibr1ptr;
unsigned TXLibr1Given : 1;
unsigned TXLibr2Given : 1;
unsigned TXLdcGiven : 1;
unsigned TXLlengthgiven : 1; /* flag to indicate C was specified */
} TXLinstance ;
/* per model data */
typedef struct sTXLmodel { /* model structure for a txl */
int TXLmodType; /* type index of this device type */
struct sTXLmodel *TXLnextModel; /* pointer to next possible model in
* linked list */
TXLinstance * TXLinstances; /* pointer to list of instances that have this
* model */
IFuid TXLmodName; /* pointer to character string naming this model */
double R;
double L;
double G;
double C;
double length;
unsigned Rgiven : 1; /* flag to indicate R was specified */
unsigned Lgiven : 1; /* flag to indicate L was specified */
unsigned Ggiven : 1; /* flag to indicate G was specified */
unsigned Cgiven : 1; /* flag to indicate C was specified */
unsigned lengthgiven : 1; /* flag to indicate C was specified */
} TXLmodel;
/* instance parameters */
#define TXL_IN_NODE 1
#define TXL_OUT_NODE 2
#define TXL_LENGTH 3
/* model parameters */
#define TXL_R 101
#define TXL_C 102
#define TXL_G 103
#define TXL_L 104
#define TXL_length 105
#define TXL_MOD_R 106
#include "txlext.h"
extern VI_list_txl *pool_vi_txl;
#endif /*TXL*/

View File

@ -0,0 +1,38 @@
/**********
Copyright 1992 Regents of the University of California. All rights
reserved.
Author: 1992 Charles Hough
**********/
#include "ngspice.h"
#include <stdio.h>
#include "txldefs.h"
#include "sperror.h"
#include "suffix.h"
int
TXLdelete(inModel,name,inst)
GENmodel *inModel;
IFuid name;
GENinstance **inst;
{
TXLmodel *model = (TXLmodel *)inModel;
TXLinstance **fast = (TXLinstance **)inst;
TXLinstance **prev = NULL;
TXLinstance *here;
for( ; model ; model = model->TXLnextModel) {
prev = &(model->TXLinstances);
for(here = *prev; here ; here = *prev) {
if(here->TXLname == name || (fast && here==*fast) ) {
*prev= here->TXLnextInstance;
FREE(here);
return(OK);
}
prev = &(here->TXLnextInstance);
}
}
return(E_NODEV);
}

View File

@ -0,0 +1,36 @@
/**********
Copyright 1992 Regents of the University of California. All rights
reserved.
Author: 1992 Charles Hough
**********/
#include "ngspice.h"
#include <stdio.h>
#include "txldefs.h"
#include "suffix.h"
void
TXLdestroy(inModel)
GENmodel **inModel;
{
TXLmodel **model = (TXLmodel **)inModel;
TXLinstance *here;
TXLinstance *prev = NULL;
TXLmodel *mod = *model;
TXLmodel *oldmod = NULL;
for( ; mod ; mod = mod->TXLnextModel) {
if(oldmod) FREE(oldmod);
oldmod = mod;
prev = (TXLinstance *)NULL;
for(here = mod->TXLinstances ; here ; here = here->TXLnextInstance) {
if(prev) FREE(prev);
prev = here;
}
if(prev) FREE(prev);
}
if(oldmod) FREE(oldmod);
*model = NULL;
}

View File

@ -0,0 +1,19 @@
#ifdef __STDC__
/* extern int TXLaccept(CKTcircuit*,GENmodel*); */
extern int TXLdelete(GENmodel*,IFuid,GENinstance**);
extern void TXLdestroy(GENmodel**);
extern int TXLload(GENmodel*,CKTcircuit*);
extern int TXLmDelete(GENmodel**,IFuid,GENmodel*);
extern int TXLmParam(int,IFvalue*,GENmodel*);
extern int TXLparam(int,IFvalue*,GENinstance*,IFvalue*);
extern int TXLsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
#else /* stdc */
/* extern int TXLaccept(); */
extern int TXLdelete();
extern void TXLdestroy();
extern int TXLload();
extern int TXLmDelete();
extern int TXLmParam();
extern int TXLparam();
extern int TXLsetup();
#endif /* stdc */

View File

@ -0,0 +1,41 @@
/**********
Copyright 1992 Regents of the University of California. All rights
reserved.
Author: 1992 Charles Hough
**********/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "txldefs.h"
#include "sperror.h"
#include "suffix.h"
int
TXLfindBr(ckt,inModel,name)
register CKTcircuit *ckt;
GENmodel *inModel;
register IFuid name;
{
register TXLmodel *model = (TXLmodel *)inModel;
register TXLinstance *here;
int error;
CKTnode *tmp;
for( ; model != NULL; model = model->TXLnextModel) {
for (here = model->TXLinstances; here != NULL;
here = here->TXLnextInstance) {
if(here->TXLname == name) {
if(here->TXLbranch == 0) {
error = CKTmkCur(ckt,&tmp,here->TXLname,"branch");
if(error) return(error);
here->TXLbranch = tmp->number;
}
return(here->TXLbranch);
}
}
}
return(0);
}

View File

@ -0,0 +1,90 @@
/**********
Copyright 1992 Regents of the University of California. All rights
reserved.
Author: 1992 Charles Hough
**********/
#include <config.h>
#include <devdefs.h>
#include "txlitf.h"
#include "txlext.h"
#include "txlinit.h"
SPICEdev TXLinfo = {
{
"TransLine",
"Simple Lossy Transmission Line",
&TXLnSize,
&TXLnSize,
TXLnames,
&TXLpTSize,
TXLpTable,
&TXLmPTSize,
TXLmPTable,
#ifdef XSPICE
/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/
NULL, /* This is a SPICE device, it has no MIF info data */
0, /* This is a SPICE device, it has no MIF info data */
NULL, /* This is a SPICE device, it has no MIF info data */
0, /* This is a SPICE device, it has no MIF info data */
NULL, /* This is a SPICE device, it has no MIF info data */
0, /* This is a SPICE device, it has no MIF info data */
NULL, /* This is a SPICE device, it has no MIF info data */
/*--------------------------- End of SDB fix -------------------------*/
#endif
0
},
TXLparam,
TXLmParam,
TXLload,
TXLsetup,
NULL,
NULL,
NULL,
NULL,
NULL, /* TXLfindBranch, */
TXLload, /* ac load */
NULL,
TXLdestroy,
#ifdef DELETES
TXLmDelete,
TXLdelete,
#else /* DELETES */
NULL,
NULL,
#endif /* DELETES */
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
&TXLiSize,
&TXLmSize
};
SPICEdev *
get_txl_info(void)
{
return &TXLinfo;
}

View File

@ -0,0 +1,18 @@
/**********
Copyright 1992 Regents of the University of California. All rights
reserved.
Author: 1992 Charles Hough
**********/
#ifndef _TXLINIT_H
#define _TXLINIT_H
extern IFparm TXLpTable[ ];
extern IFparm TXLmPTable[ ];
extern int TXLmPTSize;
extern int TXLpTSize;
extern char *TXLnames[ ];
extern int TXLiSize;
extern int TXLmSize;
extern int TXLnSize;
#endif

View File

@ -0,0 +1,12 @@
/**********
Copyright 1992 Regents of the University of California. All rights
reserved.
Author: 1992 Charles Hough
**********/
#ifndef DEV_TXL
#define DEV_TXL
SPICEdev *get_txl_info(void);
#endif

View File

@ -0,0 +1,689 @@
/**********
Copyright 1992 Regents of the University of California. All rights
reserved.
Author: 1992 Charles Hough
**********/
#include "ngspice.h"
#include <stdio.h>
#include "txldefs.h"
#include "sperror.h"
#include "suffix.h"
static double ratio[MAX_CP_TX_LINES];
static int update_cnv_txl();
static VI_list_txl *new_vi_txl();
static void free_vi_txl();
static int add_new_vi_txl();
static int get_pvs_vi_txl();
static int right_consts_txl();
static int update_delayed_cnv_txl();
static int multC();
static int expC();
static void copy_tx();
/*static char *message = "tau of txl line is larger than max time step";*/
/*ARGSUSED*/
int
TXLload(inModel,ckt)
GENmodel *inModel;
CKTcircuit *ckt;
{
register TXLmodel *model = (TXLmodel *)inModel;
register TXLinstance *here;
TXLine *tx, *tx2;
int k, l;
int time, time2;
double h, h1, f;
int hint;
float hf;
NODE *nd;
double v, v1, g;
int cond1;
CKTnode *node;
VI_list_txl *vi, *vi_before;
int i, before, delta;
/* debug
printf("before txlload\n");
SMPprint(ckt->CKTmatrix, stdout);
*/
h = ckt->CKTdelta;
h1 = 0.5 * h;
time2 = (int) (ckt->CKTtime * 1e12);
hint = (int)(h * 1e12);
hf = (float)(h * 1e12);
time = (int) ((ckt->CKTtime - ckt->CKTdelta) * 1e12);
cond1= ckt->CKTmode & MODEDC;
for( ; model != NULL; model = model->TXLnextModel ) {
for (here = model->TXLinstances; here != NULL ;
here=here->TXLnextInstance) {
tx = here->txline;
if (cond1 || tx->vi_head == NULL) continue;
if (time < tx->vi_tail->time) {
time = tx->vi_tail->time;
hint = time2 - time;
}
vi_before = tx->vi_tail;
before = tx->vi_tail->time;
if (time > tx->vi_tail->time) {
copy_tx(tx, here->txline2);
add_new_vi_txl(here, ckt, time);
delta = time - before;
nd = tx->in_node;
v = vi_before->v_i;
nd->V = tx->vi_tail->v_i;
v1 = nd->V;
nd->dv = (v1 - v) / delta;
nd = tx->out_node;
v = vi_before->v_o;
v1 = nd->V = tx->vi_tail->v_o;
nd->dv = (v1 - v) / delta;
if (tx->lsl) continue;
update_cnv_txl(tx, (float) delta);
if (tx->ext) update_delayed_cnv_txl(tx, (float) delta);
}
}
}
model = (TXLmodel *)inModel;
for( ; model != NULL; model = model->TXLnextModel ) {
for (here = model->TXLinstances; here != NULL ;
here=here->TXLnextInstance) {
tx = here->txline;
tx2 = here->txline2;
if (!tx->lsl && hf > tx->taul) {
fprintf(stderr, "your time step is too large for tau.\n");
fprintf(stderr, "please decrease max time step in .tran card.\n");
fprintf(stderr, ".tran tstep tstop tstart tmax.\n");
fprintf(stderr, "make tmax smaller than %e and try again.\n",
tx->taul * 1e-12);
return (1111);
}
if (cond1) {
if (here->TXLlengthgiven)
g = model->R * here->TXLlength;
else g = model->R * here->TXLmodPtr->length;
*(here->TXLposIbr1ptr) += 1.0;
*(here->TXLnegIbr2ptr) += 1.0;
*(here->TXLibr1Ibr1ptr) += 1.0;
*(here->TXLibr1Ibr2ptr) += 1.0;
*(here->TXLibr2Posptr) += 1.0;
*(here->TXLibr2Negptr) -= 1.0;
*(here->TXLibr2Ibr1ptr) -= g;
continue;
}
/* dc setup */
if (here->TXLdcGiven == 0 && !cond1) {
nd = tx->in_node;
for (node = ckt->CKTnodes;node; node = node->next) {
if (strcmp(nd->name->id, node->name) == 0) {
tx->dc1 = tx2->dc1 = ckt->CKTrhsOld[node->number];
nd->V = tx->dc1;
break;
}
}
nd = tx->out_node;
for (node = ckt->CKTnodes;node; node = node->next) {
if (strcmp(nd->name->id, node->name) == 0) {
tx->dc2 = tx2->dc2 = ckt->CKTrhsOld[node->number];
nd->V = tx->dc2;
break;
}
}
here->TXLdcGiven = 1;
vi = new_vi_txl();
vi->time = 0;
vi->i_i = *(ckt->CKTrhsOld + here->TXLibr1);
vi->i_o = *(ckt->CKTrhsOld + here->TXLibr2);
vi->v_i = tx->dc1;
vi->v_o = tx->dc2;
for (i = 0; i < 3; i++) {
tx->h1_term[i].cnv_i =
- tx->dc1 * tx->h1_term[i].c / tx->h1_term[i].x;
tx->h1_term[i].cnv_o =
- tx->dc2 * tx->h1_term[i].c / tx->h1_term[i].x;
}
for (i = 0; i < 3; i++) {
tx->h2_term[i].cnv_i = 0.0;
tx->h2_term[i].cnv_o = 0.0;
}
for (i = 0; i < 6; i++) {
tx->h3_term[i].cnv_i =
- tx->dc1 * tx->h3_term[i].c / tx->h3_term[i].x;
tx->h3_term[i].cnv_o =
- tx->dc2 * tx->h3_term[i].c / tx->h3_term[i].x;
}
vi->next = NULL;
tx->vi_tail = vi;
tx->vi_head = vi;
here->txline2->vi_tail = vi;
here->txline2->vi_head = vi;
}
/* change 6,6 1/18/93
*(here->TXLibr1Ibr1ptr) -= 1.0;
*(here->TXLibr2Ibr2ptr) -= 1.0;
*(here->TXLposIbr1ptr) += 1.0;
*(here->TXLnegIbr2ptr) += 1.0;
*(here->TXLibr1Posptr) += tx->sqtCdL + h1 * tx->h1C;
*(here->TXLibr2Negptr) += tx->sqtCdL + h1 * tx->h1C;
*/
*(here->TXLibr1Ibr1ptr) = -1.0;
*(here->TXLibr2Ibr2ptr) = -1.0;
*(here->TXLposIbr1ptr) = 1.0;
*(here->TXLnegIbr2ptr) = 1.0;
*(here->TXLibr1Posptr) = tx->sqtCdL + h1 * tx->h1C;
*(here->TXLibr2Negptr) = tx->sqtCdL + h1 * tx->h1C;
k = here->TXLibr1;
l = here->TXLibr2;
copy_tx(tx2, tx);
if (right_consts_txl(tx2, time, time2, h, h1, k, l, ckt)) {
if (tx->lsl) {
f = ratio[0] * tx->h3_aten;
*(here->TXLibr1Negptr) = -f;
*(here->TXLibr2Posptr) = -f;
f = ratio[0] * tx->h2_aten;
*(here->TXLibr1Ibr2ptr) = -f;
*(here->TXLibr2Ibr1ptr) = -f;
}
else {
tx->ext = 1;
tx->ratio = ratio[0];
if (ratio[0] > 0.0) {
f = ratio[0] * (h1 * (tx->h3_term[0].c
+ tx->h3_term[1].c + tx->h3_term[2].c
+ tx->h3_term[3].c + tx->h3_term[4].c
+ tx->h3_term[5].c ) + tx->h3_aten);
*(here->TXLibr1Negptr) = -f;
*(here->TXLibr2Posptr) = -f;
f = ratio[0] * (h1 * ( tx->h2_term[0].c
+ tx->h2_term[1].c + tx->h2_term[2].c )
+ tx->h2_aten);
*(here->TXLibr1Ibr2ptr) = -f;
*(here->TXLibr2Ibr1ptr) = -f;
}
}
}
else tx->ext = 0;
}
}
if (cond1) return (OK);
/* debug
printf("after txlload\n");
SMPprint(ckt->CKTmatrix, stdout);
*/
return(OK);
}
static void copy_tx(new, old)
TXLine *new, *old;
{
int i;
VI_list_txl *temp;
new->lsl = old->lsl;
new->ext = old->ext;
new->ratio = old->ratio;
new->taul = old->taul;
new->sqtCdL = old->sqtCdL;
new->h2_aten = old->h2_aten;
new->h3_aten = old->h3_aten;
new->h1C = old->h1C;
for (i= 0; i < 3; i++) {
new->h1e[i] = old->h1e[i];
new->h1_term[i].c = old->h1_term[i].c;
new->h1_term[i].x = old->h1_term[i].x;
new->h1_term[i].cnv_i = old->h1_term[i].cnv_i;
new->h1_term[i].cnv_o = old->h1_term[i].cnv_o;
new->h2_term[i].c = old->h2_term[i].c;
new->h2_term[i].x = old->h2_term[i].x;
new->h2_term[i].cnv_i = old->h2_term[i].cnv_i;
new->h2_term[i].cnv_o = old->h2_term[i].cnv_o;
}
for (i= 0; i < 6; i++) {
new->h3_term[i].c = old->h3_term[i].c;
new->h3_term[i].x = old->h3_term[i].x;
new->h3_term[i].cnv_i = old->h3_term[i].cnv_i;
new->h3_term[i].cnv_o = old->h3_term[i].cnv_o;
}
new->ifImg = old->ifImg;
if (new->vi_tail != old->vi_tail) {
/* someting wrong */
exit (0);
}
while (new->vi_head->time < old->vi_head->time) {
temp = new->vi_head;
new->vi_head = new->vi_head->next;
free_vi_txl(temp);
}
}
static int update_cnv_txl(tx, h)
TXLine *tx;
float h;
{
int i;
double ai, bi, ao, bo;
register double e, t;
ai = tx->in_node->V;
ao = tx->out_node->V;
bi = tx->in_node->dv;
bo = tx->out_node->dv;
for (i = 0; i < 3; i++) {
register TERM *tm;
tm = &(tx->h1_term[i]);
e = tx->h1e[i];
t = tm->c / tm->x;
bi *= t;
bo *= t;
tm->cnv_i = (tm->cnv_i - bi*h) * e + (e - 1.0)*(ai*t + 1.0e+12*bi/tm->x);
tm->cnv_o = (tm->cnv_o - bo*h) * e + (e - 1.0)*(ao*t + 1.0e+12*bo/tm->x);
}
return (1);
}
static VI_list_txl
*new_vi_txl()
{
VI_list_txl *q;
if (pool_vi_txl) {
q = pool_vi_txl;
pool_vi_txl = pool_vi_txl->pool;
return(q);
} else
return((VI_list_txl *) malloc (sizeof (VI_list_txl)));
}
static void
free_vi_txl(q)
VI_list_txl *q;
{
q->pool = pool_vi_txl;
pool_vi_txl = q;
}
static int add_new_vi_txl(here, ckt, time)
TXLinstance *here;
CKTcircuit *ckt;
int time;
{
VI_list_txl *vi;
TXLine *tx, *tx2;
tx = here->txline;
tx2 = here->txline2;
vi = new_vi_txl();
vi->time = time;
tx->vi_tail->next = vi;
tx2->vi_tail->next = vi;
vi->next = NULL;
tx->vi_tail = vi;
tx2->vi_tail = vi;
vi->v_i = *(ckt->CKTrhsOld + here->TXLposNode);
vi->v_o = *(ckt->CKTrhsOld + here->TXLnegNode);
vi->i_i = *(ckt->CKTrhsOld + here->TXLibr1);
vi->i_o = *(ckt->CKTrhsOld + here->TXLibr2);
return(1);
}
static int
get_pvs_vi_txl(t1, t2, tx, v1_i, v2_i, i1_i, i2_i, v1_o, v2_o, i1_o, i2_o)
TXLine *tx;
int t1, t2;
double *v1_i, *v2_i, *i1_i, *i2_i, *v1_o, *v2_o, *i1_o, *i2_o;
{
double ta, tb;
register VI_list_txl *vi, *vi1;
register double f;
int ext = 0;
ta = t1 - tx->taul;
tb = t2 - tx->taul;
if (tb <= 0) {
*v1_i = *v2_i = tx->dc1;
*v2_o = *v1_o = tx->dc2;
*i1_i = *i2_i = *i1_o = *i2_o = 0;
return(ext);
}
if (ta <= 0) {
*i1_i = *i1_o = 0.0;
*v1_i = tx->dc1;
*v1_o = tx->dc2;
vi1 = tx->vi_head;
vi = vi1->next;
} else {
vi1 = tx->vi_head;
for (vi = vi1->next; vi->time < ta; vi = vi->next) {
/* free_vi_txl(vi1); */
vi1 = vi;
}
f = (ta - vi1->time) / (vi->time - vi1->time);
*v1_i = vi1->v_i + f * (vi->v_i - vi1->v_i);
*v1_o = vi1->v_o + f * (vi->v_o - vi1->v_o);
*i1_i = vi1->i_i + f * (vi->i_i - vi1->i_i);
*i1_o = vi1->i_o + f * (vi->i_o - vi1->i_o);
tx->vi_head = vi1;
}
if (tb > t1) {
/* fprintf(stderr, "pvs: time = %d\n", t2); */
ext = 1;
/*
f = tb - t1;
*v2_i = tx->in_node->V + tx->in_node->dv * f;
*v2_o = tx->out_node->V + tx->out_node->dv * f;
if (vi) {
for (; vi->time != t1; vi = vi->next)
vi1 = vi;
f /= (double) (t1 - vi1->time);
*i2_i = vi->i_i + f * (vi->i_i - vi1->i_i);
*i2_o = vi->i_o + f * (vi->i_o - vi1->i_o);
} else {
*i2_i = vi1->i_i;
*i2_o = vi1->i_o;
}
*/
ratio[0] = f = (tb - t1) / (t2 - t1);
if (vi)
for (; vi->time != t1; vi = vi->next);
else
vi = vi1;
f = 1 - f;
*v2_i = vi->v_i * f;
*v2_o = vi->v_o * f;
*i2_i = vi->i_i * f;
*i2_o = vi->i_o * f;
} else {
for (; vi->time < tb; vi = vi->next)
vi1 = vi;
f = (tb - vi1->time) / (vi->time - vi1->time);
*v2_i = vi1->v_i + f * (vi->v_i - vi1->v_i);
*v2_o = vi1->v_o + f * (vi->v_o - vi1->v_o);
*i2_i = vi1->i_i + f * (vi->i_i - vi1->i_i);
*i2_o = vi1->i_o + f * (vi->i_o - vi1->i_o);
}
return(ext);
}
static int
right_consts_txl(tx, t, time, h, h1, l1, l2, ckt)
TXLine *tx;
int t, time;
double h, h1; /*** h1 = 0.5 * h ***/
int l1, l2;
CKTcircuit *ckt;
{
int i;
register double ff=0.0, gg=0.0, e;
double v1_i, v2_i, i1_i, i2_i;
double v1_o, v2_o, i1_o, i2_o;
int ext;
if (! tx->lsl) {
register double ff1=0.0;
for (i = 0; i < 3; i++) {
tx->h1e[i] = e = exp((double) tx->h1_term[i].x * h);
ff1 -= tx->h1_term[i].c * e;
ff -= tx->h1_term[i].cnv_i * e;
gg -= tx->h1_term[i].cnv_o * e;
}
ff += ff1 * h1 * tx->in_node->V;
gg += ff1 * h1 * tx->out_node->V;
}
ext = get_pvs_vi_txl(t, time, tx, &v1_i, &v2_i, &i1_i, &i2_i, &v1_o, &v2_o, &i1_o, &i2_o);
if (tx->lsl) {
ff = tx->h3_aten * v2_o + tx->h2_aten * i2_o;
gg = tx->h3_aten * v2_i + tx->h2_aten * i2_i;
} else {
if (tx->ifImg) {
double a, b, er, ei, a1, b1, a2, b2;
for (i = 0; i < 4; i++) {
register TERM *tm;
tm = &(tx->h3_term[i]);
e = exp((double) tm->x * h);
tm->cnv_i = tm->cnv_i * e + h1 * tm->c * (v1_i * e + v2_i);
tm->cnv_o = tm->cnv_o * e + h1 * tm->c * (v1_o * e + v2_o);
}
expC(tx->h3_term[4].x, tx->h3_term[5].x, h, &er, &ei);
a2 = h1 * tx->h3_term[4].c;
b2 = h1 * tx->h3_term[5].c;
a = tx->h3_term[4].cnv_i;
b = tx->h3_term[5].cnv_i;
multC(a, b, er, ei, &a, &b);
multC(a2, b2, v1_i * er + v2_i, v1_i * ei, &a1, &b1);
tx->h3_term[4].cnv_i = a + a1;
tx->h3_term[5].cnv_i = b + b1;
a = tx->h3_term[4].cnv_o;
b = tx->h3_term[5].cnv_o;
multC(a, b, er, ei, &a, &b);
multC(a2, b2, v1_o * er + v2_o, v1_o * ei, &a1, &b1);
tx->h3_term[4].cnv_o = a + a1;
tx->h3_term[5].cnv_o = b + b1;
ff += tx->h3_aten * v2_o;
gg += tx->h3_aten * v2_i;
for (i = 0; i < 5; i++) {
ff += tx->h3_term[i].cnv_o;
gg += tx->h3_term[i].cnv_i;
}
ff += tx->h3_term[4].cnv_o;
gg += tx->h3_term[4].cnv_i;
{
register TERM *tm;
tm = &(tx->h2_term[0]);
e = exp((double) tm->x * h);
tm->cnv_i = tm->cnv_i * e + h1 * tm->c * (i1_i * e + i2_i);
tm->cnv_o = tm->cnv_o * e + h1 * tm->c * (i1_o * e + i2_o);
}
expC(tx->h2_term[1].x, tx->h2_term[2].x, h, &er, &ei);
a2 = h1 * tx->h2_term[1].c;
b2 = h1 * tx->h2_term[2].c;
a = tx->h2_term[1].cnv_i;
b = tx->h2_term[2].cnv_i;
multC(a, b, er, ei, &a, &b);
multC(a2, b2, i1_i * er + i2_i, i1_i * ei, &a1, &b1);
tx->h2_term[1].cnv_i = a + a1;
tx->h2_term[2].cnv_i = b + b1;
a = tx->h2_term[1].cnv_o;
b = tx->h2_term[2].cnv_o;
multC(a, b, er, ei, &a, &b);
multC(a2, b2, i1_o * er + i2_o, i1_o * ei, &a1, &b1);
tx->h2_term[1].cnv_o = a + a1;
tx->h2_term[2].cnv_o = b + b1;
ff += tx->h2_aten * i2_o + tx->h2_term[0].cnv_o +
2.0 * tx->h2_term[1].cnv_o;
gg += tx->h2_aten * i2_i + tx->h2_term[0].cnv_i +
2.0 * tx->h2_term[1].cnv_i;
} else {
for (i = 0; i < 6; i++) {
register TERM *tm;
tm = &(tx->h3_term[i]);
e = exp((double) tm->x * h);
tm->cnv_i = tm->cnv_i * e + h1 * tm->c * (v1_i * e + v2_i);
tm->cnv_o = tm->cnv_o * e + h1 * tm->c * (v1_o * e + v2_o);
}
ff += tx->h3_aten * v2_o;
gg += tx->h3_aten * v2_i;
for (i = 0; i < 6; i++) {
ff += tx->h3_term[i].cnv_o;
gg += tx->h3_term[i].cnv_i;
}
for (i = 0; i < 3; i++) {
register TERM *tm;
tm = &(tx->h2_term[i]);
e = exp((double) tm->x * h);
tm->cnv_i = tm->cnv_i * e + h1 * tm->c * (i1_i * e + i2_i);
tm->cnv_o = tm->cnv_o * e + h1 * tm->c * (i1_o * e + i2_o);
}
ff += tx->h2_aten * i2_o;
gg += tx->h2_aten * i2_i;
for (i = 0; i < 3; i++) {
ff += tx->h2_term[i].cnv_o;
gg += tx->h2_term[i].cnv_i;
}
}
}
*(ckt->CKTrhs + l1) = ff;
*(ckt->CKTrhs + l2) = gg;
return(ext);
}
static int
update_delayed_cnv_txl(tx, h)
TXLine *tx;
float h;
{
float ratio;
register double f;
register VI_list_txl *vi;
register TERM *tms;
h *= 0.5e-12;
ratio = tx->ratio;
vi = tx->vi_tail;
if (ratio > 0.0) {
tms = tx->h3_term;
f = h * ratio * vi->v_i;
tms[0].cnv_i += f * tms[0].c;
tms[1].cnv_i += f * tms[1].c;
tms[2].cnv_i += f * tms[2].c;
tms[3].cnv_i += f * tms[3].c;
tms[4].cnv_i += f * tms[4].c;
tms[5].cnv_i += f * tms[5].c;
f = h * ratio * vi->v_o;
tms[0].cnv_o += f * tms[0].c;
tms[1].cnv_o += f * tms[1].c;
tms[2].cnv_o += f * tms[2].c;
tms[3].cnv_o += f * tms[3].c;
tms[4].cnv_o += f * tms[4].c;
tms[5].cnv_o += f * tms[5].c;
tms = tx->h2_term;
f = h * ratio * vi->i_i;
tms[0].cnv_i += f * tms[0].c;
tms[1].cnv_i += f * tms[1].c;
tms[2].cnv_i += f * tms[2].c;
f = h * ratio * vi->i_o;
tms[0].cnv_o += f * tms[0].c;
tms[1].cnv_o += f * tms[1].c;
tms[2].cnv_o += f * tms[2].c;
}
return(1);
}
static int expC(ar, ai, h, cr, ci)
double ar, ai, *cr, *ci;
float h;
{
double e, cs, si;
e = exp((double) ar * h);
cs = cos((double) ai * h);
si = sin((double) ai * h);
*cr = e * cs;
*ci = e * si;
return(1);
}
static int multC(ar, ai, br, bi, cr, ci)
double ar, ai, br, bi;
double *cr, *ci;
{
register double tp;
tp = ar*br - ai*bi;
*ci = ar*bi + ai*br;
*cr = tp;
return (1);
}

View File

@ -0,0 +1,49 @@
/**********
Copyright 1992 Regents of the University of California. All rights
reserved.
Author: 1992 Charles Hough
**********/
#include "ngspice.h"
#include <stdio.h>
#include "const.h"
#include "cktdefs.h"
#include "ifsim.h"
#include "txldefs.h"
#include "sperror.h"
#include "devdefs.h"
#include "suffix.h"
#include "swec.h"
/* ARGSUSED */
int
TXLmodAsk(ckt,inModel,which,value)
CKTcircuit *ckt;
GENmodel *inModel;
int which;
IFvalue *value;
{
TXLmodel *model = (TXLmodel *)inModel;
switch(which) {
case TXL_R:
value->rValue = model->R;
return(OK);
case TXL_C:
value->rValue = model->C;
return(OK);
case TXL_G:
value->rValue = model->G;
return(OK);
case TXL_L:
value->rValue = model->L;
return(OK);
case TXL_length:
value->rValue = model->length;
return(OK);
default:
return(E_BADPARM);
}
}

View File

@ -0,0 +1,45 @@
/**********
Copyright 1992 Regents of the University of California. All rights
reserved.
Author: 1992 Charles Hough
**********/
#include "ngspice.h"
#include <stdio.h>
#include "txldefs.h"
#include "sperror.h"
#include "suffix.h"
int
TXLmDelete(inModel,modname,kill)
GENmodel **inModel;
IFuid modname;
GENmodel *kill;
{
TXLmodel **model = (TXLmodel **)inModel;
TXLmodel *modfast = (TXLmodel *)kill;
TXLinstance *here;
TXLinstance *prev = NULL;
TXLmodel **oldmod;
oldmod = model;
for( ; *model ; model = &((*model)->TXLnextModel)) {
if( (*model)->TXLmodName == modname ||
(modfast && *model == modfast) ) goto delgot;
oldmod = model;
}
return(E_NOMOD);
delgot:
*oldmod = (*model)->TXLnextModel; /* cut deleted device out of list */
for(here = (*model)->TXLinstances ; here ; here = here->TXLnextInstance) {
if(prev) FREE(prev);
prev = here;
}
if(prev) FREE(prev);
FREE(*model);
return(OK);
}

View File

@ -0,0 +1,51 @@
/**********
Copyright 1992 Regents of the University of California. All rights
reserved.
Author: 1992 Charles Hough
**********/
#include "ngspice.h"
#include <stdio.h>
#include "const.h"
#include "ifsim.h"
#include "txldefs.h"
#include "sperror.h"
#include "suffix.h"
int
TXLmParam(param,value,inModel)
int param;
IFvalue *value;
GENmodel *inModel;
{
register TXLmodel *model = (TXLmodel *)inModel;
switch(param) {
case TXL_R:
model->R = value->rValue;
model->Rgiven = TRUE;
break;
case TXL_L:
model->L = value->rValue;
model->Lgiven = TRUE;
break;
case TXL_G:
model->G = value->rValue;
model->Ggiven = TRUE;
break;
case TXL_C:
model->C = value->rValue;
model->Cgiven = TRUE;
break;
case TXL_length:
model->length = value->rValue;
model->lengthgiven = TRUE;
break;
case TXL_MOD_R:
break;
default:
return(E_BADPARM);
}
return(OK);
}

View File

@ -0,0 +1,40 @@
/**********
Copyright 1992 Regents of the University of California. All rights
reserved.
Author: 1992 Charles Hough
**********/
#include "ngspice.h"
#include <stdio.h>
#include "const.h"
#include "ifsim.h"
#include "txldefs.h"
#include "sperror.h"
#include "suffix.h"
/* ARGSUSED */
int
TXLparam(param,value,inst,select)
int param;
IFvalue *value;
GENinstance *inst;
IFvalue *select;
{
TXLinstance *here = (TXLinstance *)inst;
switch(param) {
case TXL_IN_NODE:
here->TXLposNode = value->iValue;
break;
case TXL_OUT_NODE:
here->TXLnegNode = value->iValue;
break;
case TXL_LENGTH:
here->TXLlength = value->rValue;
here->TXLlengthgiven = TRUE;
break;
default:
return(E_BADPARM);
}
return(OK);
}

File diff suppressed because it is too large Load Diff