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