Second batch of added files.
This commit is contained in:
parent
9317355c0c
commit
758bedc716
|
|
@ -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);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue