56 changed files with 9277 additions and 0 deletions
-
24src/frontend/com_dl.c
-
12src/frontend/com_dl.h
-
315src/frontend/hpgl.c
-
24src/include/cluster.h
-
49src/include/cm.h
-
57src/include/cmconstants.h
-
95src/include/cmproto.h
-
71src/include/cmtypes.h
-
79src/include/dllitf.h
-
109src/include/enh.h
-
371src/include/evt.h
-
124src/include/evtproto.h
-
123src/include/evtudn.h
-
122src/include/ipc.h
-
52src/include/ipcproto.h
-
96src/include/ipctiein.h
-
87src/include/mif.h
-
373src/include/mifcmdat.h
-
111src/include/mifdefs.h
-
120src/include/mifparse.h
-
157src/include/mifproto.h
-
226src/include/miftypes.h
-
66src/include/multi_line.h
-
396src/include/swec.h
-
18src/spicelib/devices/cpl/Makefile.am
-
39src/spicelib/devices/cpl/cpl.c
-
97src/spicelib/devices/cpl/cpldefs.h
-
38src/spicelib/devices/cpl/cpldel.c
-
34src/spicelib/devices/cpl/cpldest.c
-
19src/spicelib/devices/cpl/cplext.h
-
84src/spicelib/devices/cpl/cplinit.c
-
13src/spicelib/devices/cpl/cplinit.h
-
6src/spicelib/devices/cpl/cplitf.h
-
890src/spicelib/devices/cpl/cplload.c
-
45src/spicelib/devices/cpl/cplmdel.c
-
51src/spicelib/devices/cpl/cplmpar.c
-
45src/spicelib/devices/cpl/cplparam.c
-
2101src/spicelib/devices/cpl/cplsetup.c
-
21src/spicelib/devices/txl/Makefile.am
-
38src/spicelib/devices/txl/txl.c
-
76src/spicelib/devices/txl/txlacct.c
-
43src/spicelib/devices/txl/txlask.c
-
92src/spicelib/devices/txl/txldefs.h
-
38src/spicelib/devices/txl/txldel.c
-
36src/spicelib/devices/txl/txldest.c
-
19src/spicelib/devices/txl/txlext.h
-
41src/spicelib/devices/txl/txlfbr.c
-
90src/spicelib/devices/txl/txlinit.c
-
18src/spicelib/devices/txl/txlinit.h
-
12src/spicelib/devices/txl/txlitf.h
-
689src/spicelib/devices/txl/txlload.c
-
49src/spicelib/devices/txl/txlmask.c
-
45src/spicelib/devices/txl/txlmdel.c
-
51src/spicelib/devices/txl/txlmpar.c
-
40src/spicelib/devices/txl/txlparam.c
-
1140src/spicelib/devices/txl/txlsetup.c
@ -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 |
||||
|
|
||||
@ -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 |
||||
@ -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; |
||||
|
} |
||||
@ -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 |
||||
@ -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 */ |
||||
@ -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 */ |
||||
@ -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 */ |
||||
@ -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 */ |
||||
@ -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 |
||||
@ -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 */ |
||||
@ -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 */ |
||||
@ -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 */ |
||||
@ -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 */ |
||||
@ -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 */ |
||||
@ -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 ); |
||||
|
|
||||
@ -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 */ |
||||
|
|
||||
@ -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 */ |
||||
@ -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 */ |
||||
@ -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 */ |
||||
@ -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 */ |
||||
@ -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 */ |
||||
@ -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 */ |
||||
@ -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; |
||||
@ -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 |
||||
@ -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 |
||||
@ -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); |
||||
@ -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*/ |
||||
@ -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); |
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
@ -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 */ |
||||
@ -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; |
||||
|
} |
||||
@ -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 |
||||
@ -0,0 +1,6 @@ |
|||||
|
#ifndef DEV_CPL |
||||
|
#define DEV_CPL |
||||
|
|
||||
|
SPICEdev *get_cpl_info(void); |
||||
|
|
||||
|
#endif |
||||
@ -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); |
||||
|
} |
||||
|
|
||||
@ -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); |
||||
|
|
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
2101
src/spicelib/devices/cpl/cplsetup.c
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
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 |
||||
@ -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); |
||||
@ -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); |
||||
|
} |
||||
@ -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 */ |
||||
|
} |
||||
@ -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*/ |
||||
@ -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); |
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
@ -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 */ |
||||
@ -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); |
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
@ -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 |
||||
@ -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 |
||||
@ -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); |
||||
|
|
||||
|
} |
||||
|
|
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -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); |
||||
|
|
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
1140
src/spicelib/devices/txl/txlsetup.c
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
Write
Preview
Loading…
Cancel
Save
Reference in new issue