14 #define DIAG_PIVOTING 1 28 extern int optind, opterr;
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;
35 double **matrix, **inverse;
36 double *tpeigenvalues, *gammaj;
40 while ((ch = getopt (argc, argv,
"ul:c:r:g:k:n:o:x:L:")) != EOF)
43 name = (
char *)
malloc((
unsigned) (strlen(optarg)*
sizeof(char)));
44 (void)
strcpy(name,optarg);
48 sscanf(optarg,
"%lf",&l);
52 sscanf(optarg,
"%lf",&c);
56 sscanf(optarg,
"%lf",&r);
60 sscanf(optarg,
"%lf",&
g);
64 sscanf(optarg,
"%lf",&k);
68 sscanf(optarg,
"%lf",&cm);
72 sscanf(optarg,
"%lf",&len);
76 sscanf(optarg,
"%d",&num);
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]);
98 if ( (k<0.0?-k:k) >=1.0 ) {
99 fprintf(stderr,
"Error: |k| must be less than 1.0\n");
105 fprintf(stdout,
"* single conductor line\n");
113 case 1: ctot =
c;
break;
114 case 2: ctot = c + cm;
break;
115 default: ctot = c + 2*cm;
break;
118 comments(r,l,
g,c,ctot,cm,lm,k,name,num,len);
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)));
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)));
129 for (i=1;i<=num;i++) {
130 tpeigenvalues[i] = -2.0 *
cos(
M_PI*i/(num+1));
133 for (i=1;i<=num;i++) {
134 for (j=1;j<=num;j++) {
135 matrix[i][j] =
phi(i-1,tpeigenvalues[j]);
138 gammaj = (
double *)
malloc((
unsigned) (
sizeof(double)*(num+1)));
140 for (j=1;j<=num;j++) {
142 for (i=1;i<=num;i++) {
143 gammaj[j] += matrix[i][j] * matrix[i][j];
145 gammaj[j] = sqrt(gammaj[j]);
148 for (j=1;j<=num;j++) {
149 for (i=1;i<=num; i++) {
150 matrix[i][j] /= gammaj[j];
160 double *rhs, *solution;
161 double *irhs, *isolution;
162 int errflg,
err, singular_row, singular_col;
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)));
170 othermatrix =
spCreate(num,0,&errflg);
172 for (i=1;i<=num;i++) {
173 for (j=1; j<=num; j++) {
175 *elptr = matrix[i][j];
180 (void)
spPrint(othermatrix,0,1,0);
183 for (i=1;i<=num;i++) rhs[i] = 0.0;
189 spErrorMessage(othermatrix,stderr,
NULL);
194 fprintf(stderr,
"No memory in spOrderAndFactor\n");
200 fprintf(stderr,
"Singular matrix: problem in row %d and col %d\n", singular_row, singular_col);
204 fprintf(stderr,
"* Warning: matrix is illconditioned.\n");
210 for (i=1;i<=num;i++) {
211 for (j=1;j<=num;j++) {
212 rhs[j] = (j==i?1.0:0.0);
216 for (j=1;j<=num;j++) {
217 inverse[i][j] = solution[j];
226 fprintf(stdout,
"\n");
227 fprintf(stdout,
"* Lossy line models\n");
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);
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);
244 fprintf(stdout,
"\n");
245 for (j=1;j<=num;j++) fprintf(stdout,
"v%d %d 0 0v\n",j,j+2*num);
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]);
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]);
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]);
264 fprintf(stdout,
"e%d %d %d %d 0 %0.12g\n", j*num,j,node-1,
265 2*num,matrix[j][num]);
267 fprintf(stdout,
".ends m_%s\n",name);
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);
275 fprintf(stdout,
"\n");
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);
283 fprintf(stdout,
"o%d %d 0 %d 0 mod%d_%s\n",i,2*num+i,3*num+i,i,name);
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);
290 fprintf(stdout,
".ends %s\n",name);
293 for (i=1;i<=num;i++) {
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]);
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");
324 comments(
r,
l,
g,
c,ctot,cm,lm,k,name,num,len)
325 double
r,
l,
g,
c,ctot,cm,lm,k,len;
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");
378 rval = arg*
phi(i-1,arg) -
phi(i-2,arg);
main(int argc, char **argv)