Jspice3
multidec.c File Reference
#include "spice.h"
#include <stdio.h>
#include <math.h>
#include "misc.h"
#include "spmatrix.h"
Include dependency graph for multidec.c:

Go to the source code of this file.

Macros

#define THRSH   0.01
 
#define ABS_THRSH   0
 
#define DIAG_PIVOTING   1
 

Functions

void usage ()
 
void comments ()
 
double phi ()
 
 main (int argc, char **argv)
 
void usage (char **argv)
 
void comments (double r, double l, double g, double c, double ctot, double cm, double lm, double k, char *name, int num, double len)
 
double phi (int i, double arg)
 

Macro Definition Documentation

#define ABS_THRSH   0

Definition at line 13 of file multidec.c.

#define DIAG_PIVOTING   1

Definition at line 14 of file multidec.c.

#define THRSH   0.01

Definition at line 12 of file multidec.c.

Function Documentation

void comments ( )
void comments ( double  r,
double  l,
double  g,
double  c,
double  ctot,
double  cm,
double  lm,
double  k,
char *  name,
int  num,
double  len 
)

Definition at line 324 of file multidec.c.

328 {
329 
330 fprintf(stdout,"* Subcircuit %s\n",name);
331 fprintf(stdout,"* %s is a subcircuit that models a %d-conductor transmission line with\n",name,num);
332 fprintf(stdout,"* the following parameters: l=%g, c=%g, r=%g, g=%g,\n",l,c,r,g);
333 fprintf(stdout,"* inductive_coeff_of_coupling k=%g, inter-line capacitance cm=%g,\n",k,cm);
334 fprintf(stdout,"* length=%g. Derived parameters are: lm=%g, ctot=%g.\n",len,lm,ctot);
335 fprintf(stdout,"* \n");
336 fprintf(stdout,"* It is important to note that the model is a simplified one - the\n");
337 fprintf(stdout,"* following assumptions are made: 1. The self-inductance l, the\n");
338 fprintf(stdout,"* self-capacitance ctot (note: not c), the series resistance r and the\n");
339 fprintf(stdout,"* parallel capacitance g are the same for all lines, and 2. Each line\n");
340 fprintf(stdout,"* is coupled only to the two lines adjacent to it, with the same\n");
341 fprintf(stdout,"* coupling parameters cm and lm. The first assumption implies that edge\n");
342 fprintf(stdout,"* effects have to be neglected. The utility of these assumptions is\n");
343 fprintf(stdout,"* that they make the sL+R and sC+G matrices symmetric, tridiagonal and\n");
344 fprintf(stdout,"* Toeplitz, with useful consequences (see \"Efficient Transient\n");
345 fprintf(stdout,"* Simulation of Lossy Interconnect\", by J.S. Roychowdhury and\n");
346 fprintf(stdout,"* D.O Pederson, Proc. DAC 91).\n\n");
347 fprintf(stdout,"* It may be noted that a symmetric two-conductor line is\n");
348 fprintf(stdout,"* represented accurately by this model.\n\n");
349 fprintf(stdout,"* Subckt node convention:\n");
350 fprintf(stdout,"* \n");
351 fprintf(stdout,"* |--------------------------|\n");
352 fprintf(stdout,"* 1-----| |-----n+1\n");
353 fprintf(stdout,"* 2-----| |-----n+2\n");
354 fprintf(stdout,"* : | n-wire multiconductor | :\n");
355 fprintf(stdout,"* : | line | :\n");
356 fprintf(stdout,"* n-1-----|(node 0=common gnd plane) |-----2n-1\n");
357 fprintf(stdout,"* n-----| |-----2n\n");
358 fprintf(stdout,"* |--------------------------|\n\n");
359 fflush(stdout);
360 }
Definition: cddefs.h:312
Definition: cddefs.h:177
Definition: cddefs.h:162
Definition: cddefs.h:227
main ( int  argc,
char **  argv 
)

Definition at line 23 of file multidec.c.

26  {
27 int ch;
28 extern int optind, opterr;
29 extern char *optarg;
30 int errflg=0,i,j;
31 double l,c,ctot,r=0.0,g=0.0,k=0.0,lm=0.0,cm=0.0,len;
32 unsigned gotl=0,gotc=0,gotr=0,gotg=0,gotk=0,gotcm=0,gotlen=0;
33 unsigned gotname=0, gotnum=0;
34 char *name;
35 double **matrix, **inverse;
36 double *tpeigenvalues, *gammaj;
37 char *options;
38 int num, node;
39 
40 while ((ch = getopt (argc, argv, "ul:c:r:g:k:n:o:x:L:")) != EOF)
41  switch (ch) {
42  case 'o':
43  name = (char *) malloc((unsigned) (strlen(optarg)*sizeof(char)));
44  (void) strcpy(name,optarg);
45  gotname=1;
46  break;
47  case 'l':
48  sscanf(optarg,"%lf",&l);
49  gotl=1;
50  break;
51  case 'c':
52  sscanf(optarg,"%lf",&c);
53  gotc=1;
54  break;
55  case 'r':
56  sscanf(optarg,"%lf",&r);
57  gotr=1;
58  break;
59  case 'g':
60  sscanf(optarg,"%lf",&g);
61  gotg=1;
62  break;
63  case 'k':
64  sscanf(optarg,"%lf",&k);
65  gotk=1;
66  break;
67  case 'x':
68  sscanf(optarg,"%lf",&cm);
69  gotcm=1;
70  break;
71  case 'L':
72  sscanf(optarg,"%lf",&len);
73  gotlen=1;
74  break;
75  case 'n':
76  sscanf(optarg,"%d",&num);
77  gotnum=1;
78  break;
79  case 'u':
80  usage(argv);
81  exit(1);
82  break;
83  case '?':
84  errflg++;
85  }
86 if (errflg) {
87 usage(argv);
88  exit (2);
89 }
90 
91 if (gotl + gotc + gotname + gotnum + gotlen < 5) {
92 fprintf(stderr,"l, c, model_name, number_of_conductors and length must be specified.\n");
93 fprintf(stderr,"%s -u for details.\n",argv[0]);
94 fflush(stdout);
95 exit(1);
96 }
97 
98 if ( (k<0.0?-k:k) >=1.0 ) {
99 fprintf(stderr,"Error: |k| must be less than 1.0\n");
100 fflush(stderr);
101 exit(1);
102 }
103 
104 if (num == 1) {
105 fprintf(stdout,"* single conductor line\n");
106 fflush(stdout);
107 exit(1);
108 }
109 
110 lm = l*k;
111 switch(num) {
112 
113 case 1: ctot = c; break;
114 case 2: ctot = c + cm; break;
115 default: ctot = c + 2*cm; break;
116 }
117 
118 comments(r,l,g,c,ctot,cm,lm,k,name,num,len);
119 
120 matrix = (double **) malloc((unsigned) (sizeof(double*)*(num+1)));
121 inverse = (double **) malloc((unsigned) (sizeof(double*)*(num+1)));
122 tpeigenvalues = (double *) malloc((unsigned) (sizeof(double)*(num+1)));
123 
124 for (i=1;i<=num;i++) {
125 matrix[i] = (double *) malloc((unsigned) (sizeof(double)*(num+1)));
126 inverse[i] = (double *) malloc((unsigned) (sizeof(double)*(num+1)));
127 }
128 
129 for (i=1;i<=num;i++) {
130 tpeigenvalues[i] = -2.0 * cos(M_PI*i/(num+1));
131 }
132 
133 for (i=1;i<=num;i++) {
134  for (j=1;j<=num;j++) {
135  matrix[i][j] = phi(i-1,tpeigenvalues[j]);
136  }
137 }
138 gammaj = (double *) malloc((unsigned) (sizeof(double)*(num+1)));
139 
140 for (j=1;j<=num;j++) {
141  gammaj[j] = 0.0;
142  for (i=1;i<=num;i++) {
143  gammaj[j] += matrix[i][j] * matrix[i][j];
144  }
145  gammaj[j] = sqrt(gammaj[j]);
146 }
147 
148 for (j=1;j<=num;j++) {
149  for (i=1;i<=num; i++) {
150  matrix[i][j] /= gammaj[j];
151  }
152 }
153 
154 free(gammaj);
155 
156 /* matrix = M set up */
157 
158 {
159 char *othermatrix;
160 double *rhs, *solution;
161 double *irhs, *isolution;
162 int errflg, err, singular_row, singular_col;
163 double *elptr;
164 
165 rhs = (double *) malloc((unsigned) (sizeof(double)*(num+1)));
166 irhs = (double *) malloc((unsigned) (sizeof(double)*(num+1)));
167 solution = (double *) malloc((unsigned) (sizeof(double)*(num+1)));
168 isolution = (double *) malloc((unsigned) (sizeof(double)*(num+1)));
169 
170 othermatrix = spCreate(num,0,&errflg);
171 
172 for (i=1;i<=num;i++) {
173  for (j=1; j<=num; j++) {
174  elptr = spGetElement(othermatrix,i,j);
175  *elptr = matrix[i][j];
176  }
177 }
178 
179 #ifdef DEBUG_LEVEL1
180 (void) spPrint(othermatrix,0,1,0);
181 #endif
182 
183 for (i=1;i<=num;i++) rhs[i] = 0.0;
184 rhs[1]=1.0;
185 
186 err =
188 
189 spErrorMessage(othermatrix,stderr,NULL);
190 
191 switch(err) {
192 
193 case spNO_MEMORY:
194  fprintf(stderr,"No memory in spOrderAndFactor\n");
195  fflush(stderr);
196  exit(1);
197 case spSINGULAR:
198  (void)
199  spWhereSingular(othermatrix,&singular_row,&singular_col);
200  fprintf(stderr,"Singular matrix: problem in row %d and col %d\n", singular_row, singular_col);
201  fflush(stderr);
202  exit(1);
203 case spSMALL_PIVOT:
204  fprintf(stderr,"* Warning: matrix is illconditioned.\n");
205  fflush(stderr);
206  break;
207 default: break;
208 }
209 
210 for (i=1;i<=num;i++) {
211  for (j=1;j<=num;j++) {
212  rhs[j] = (j==i?1.0:0.0);
213  irhs[j] = 0.0;
214  }
215  (void) spSolveTransposed(othermatrix,rhs,solution, irhs, isolution);
216  for (j=1;j<=num;j++) {
217  inverse[i][j] = solution[j];
218  }
219 }
220 
221 free(rhs); free(solution);
222 }
223 
224 /* inverse = M^{-1} set up */
225 
226 fprintf(stdout,"\n");
227 fprintf(stdout,"* Lossy line models\n");
228 
229 options = (char *) malloc((unsigned) 256);
230 (void) strcpy(options,"rel=1.2 nocontrol");
231 for (i=1;i<=num;i++) {
232 fprintf(stdout,".model mod%d_%s ltra %s r=%0.12g l=%0.12g g=%0.12g c=%0.12g len=%0.12g\n",
233  i,name,options,r,l+tpeigenvalues[i]*lm,g,ctot-tpeigenvalues[i]*cm,len);
234  /*i,name,options,r,l+tpeigenvalues[i]*lm,g,ctot+tpeigenvalues[i]*cm,len);*/
235 }
236 
237 
238 fprintf(stdout,"\n");
239 fprintf(stdout,"* subcircuit m_%s - modal transformation network for %s\n",name,name);
240 fprintf(stdout,".subckt m_%s", name);
241 for (i=1;i<= 2*num; i++) {
242  fprintf(stdout," %d",i);
243 }
244 fprintf(stdout,"\n");
245 for (j=1;j<=num;j++) fprintf(stdout,"v%d %d 0 0v\n",j,j+2*num);
246 
247 for (j=1;j<=num;j++) {
248  for (i=1; i<=num; i++) {
249  fprintf(stdout,"f%d 0 %d v%d %0.12g\n",
250  (j-1)*num+i,num+j,i,inverse[j][i]);
251  }
252 }
253 
254 node = 3*num+1;
255 for (j=1;j<=num;j++) {
256  fprintf(stdout,"e%d %d %d %d 0 %0.12g\n", (j-1)*num+1,
257  node, 2*num+j, num+1, matrix[j][1]);
258  node++;
259  for (i=2; i<num; i++) {
260  fprintf(stdout,"e%d %d %d %d 0 %0.12g\n", (j-1)*num+i,
261  node,node-1,num+i,matrix[j][i]);
262  node++;
263  }
264  fprintf(stdout,"e%d %d %d %d 0 %0.12g\n", j*num,j,node-1,
265  2*num,matrix[j][num]);
266 }
267 fprintf(stdout,".ends m_%s\n",name);
268 
269 fprintf(stdout,"\n");
270 fprintf(stdout,"* Subckt %s\n", name);
271 fprintf(stdout,".subckt %s",name);
272 for (i=1;i<=2*num;i++) {
273  fprintf(stdout," %d",i);
274 }
275 fprintf(stdout,"\n");
276 
277 fprintf(stdout,"x1");
278 for (i=1;i<=num;i++) fprintf(stdout," %d", i);
279 for (i=1;i<=num;i++) fprintf(stdout," %d", 2*num+i);
280 fprintf(stdout," m_%s\n",name);
281 
282 for (i=1;i<=num;i++)
283 fprintf(stdout,"o%d %d 0 %d 0 mod%d_%s\n",i,2*num+i,3*num+i,i,name);
284 
285 fprintf(stdout,"x2");
286 for (i=1;i<=num;i++) fprintf(stdout," %d", num+i);
287 for (i=1;i<=num;i++) fprintf(stdout," %d", 3*num+i);
288 fprintf(stdout," m_%s\n",name);
289 
290 fprintf(stdout,".ends %s\n",name);
291 
292 free(tpeigenvalues);
293 for (i=1;i<=num;i++) {
294 free(matrix[i]);
295 free(inverse[i]);
296 }
297 free(matrix);
298 free(inverse);
299 free(name);
300 free(options);
301 
302 }
#define ABS_THRSH
Definition: multidec.c:13
double phi()
void spPrint()
char * strcpy()
#define M_PI
Definition: spice.h:132
#define spSINGULAR
Definition: spmatrix.h:104
char * malloc()
Definition: cddefs.h:312
#define spSMALL_PIVOT
Definition: spmatrix.h:102
#define NULL
Definition: spdefs.h:121
double cos()
static double c
Definition: vectors.c:16
void comments()
void usage()
void spSolveTransposed()
spREAL * spGetElement()
int spOrderAndFactor()
char * spCreate()
Definition: cddefs.h:162
#define DIAG_PIVOTING
Definition: multidec.c:14
#define THRSH
Definition: multidec.c:12
Definition: mfb.h:383
Definition: cddefs.h:227
void spWhereSingular()
#define spNO_MEMORY
Definition: spmatrix.h:105
void free()
double phi ( )
double phi ( int  i,
double  arg 
)

Definition at line 363 of file multidec.c.

366 {
367  double rval;
368 
369  switch (i) {
370 
371  case 0:
372  rval = 1.0;
373  break;
374  case 1:
375  rval = arg;
376  break;
377  default:
378  rval = arg*phi(i-1,arg) - phi(i-2,arg);
379  }
380  return rval;
381 }
double phi()
void usage ( )
void usage ( char **  argv)

Definition at line 305 of file multidec.c.

307 {
308 
309 fprintf(stderr,"Purpose: make subckt. for coupled lines using uncoupled simple lossy lines\n");
310 fprintf(stderr,"Usage: %s -l<line-inductance> -c<line-capacitance>\n",argv[0]);
311 fprintf(stderr," -r<line-resistance> -g<line-conductance> \n");
312 fprintf(stderr," -k<inductive coeff. of coupling> \n");
313 fprintf(stderr," -x<line-to-line capacitance> -o<subckt-name> \n");
314 fprintf(stderr," -n<number of conductors> -L<length> -u\n");
315 fprintf(stderr,"Example: %s -n4 -l9e-9 -c20e-12 -r5.3 -x5e-12 -k0.7 -otest -L5.4\n\n",argv[0]);
316 
317 fprintf(stderr,"See \"Efficient Transient Simulation of Lossy Interconnect\",\n");
318 fprintf(stderr,"J.S. Roychowdhury and D.O. Pederson, Proc. DAC 91 for details\n");
319 fprintf(stderr,"\n");
320 fflush(stderr);
321 }