1 /**********
2 Copyright 1992 Regents of the University of California.  All rights
3 reserved.
4 Author: 1992 Charles Hough
5 **********/
6 
7 #include "ngspice/ngspice.h"
8 #include "ngspice/ifsim.h"
9 #include "ngspice/inpdefs.h"
10 #include "ngspice/inpmacs.h"
11 #include "ngspice/fteext.h"
12 #include "inpxx.h"
13 
14 void
INP2Y(CKTcircuit * ckt,INPtables * tab,struct card * current)15 INP2Y(
16     CKTcircuit *ckt,
17     INPtables *tab,
18     struct card *current)
19 
20 {
21 /* parse a txl card */
22 /* Yxxxx node1 gnode node2 gnode name */
23 
24 int mytype; /* the type to determine txl */
25 int mytype2; /* the type to determine cpl */
26 int type;   /* the type the model says it is */
27 char *line; /* the part of the current line left to parse */
28 char *name; /* the resistor's name */
29 char *buf; /* temporary buffer for parsing */
30 char *model;    /* the name of the resistor's model */
31 char *nname1;   /* the first node's name */
32 char *nname2;   /* the second node's name */
33 char *rname1, *rname2, *rname3;
34 char *cname1, *cname2, *cname3, *cname4;
35 char *internal1, *internal2;
36 char *ground1, *ground2;
37 CKTnode *node1; /* the first node's node pointer */
38 CKTnode *node2; /* the second node's node pointer */
39 CKTnode *gnode1, *gnode2, *inode1, *inode2;
40 int error;      /* error code temporary */
41 int error1=0;   /* secondary error code temporary */
42 INPmodel *thismodel;    /* pointer to model structure describing our model */
43 GENmodel *mdfast;    /* pointer to the actual model */
44 GENinstance *fast;  /* pointer to the actual instance */
45 GENmodel *mdfast2, *mdfast3, *mdfast4, *mdfast5, *mdfast6;
46 GENinstance *fast2, *fast3, *fast4, *fast5, *fast6;
47 IFuid uid;      /* uid for default model */
48 GENinstance *txl;
49 IFvalue ptemp;  /* a value structure to package into */
50 double lval=0, rval=0, cval=0, lenval=0;
51 int lenvalgiven = 0;
52 
53     mytype = INPtypelook("TransLine");
54     mytype2 = INPtypelook("CplLines");
55 
56     if(mytype < 0 ) {
57         LITERR("Device type TransLine not supported by this binary\n");
58         return;
59     }
60     line = current->line;
61     INPgetNetTok(&line,&name,1);
62     INPinsert(&name,tab);
63     INPgetNetTok(&line,&nname1,1);
64     INPtermInsert(ckt,&nname1,tab,&node1);
65     INPgetNetTok(&line,&ground1,1);
66     INPtermInsert(ckt,&ground1,tab,&gnode1);
67     INPgetNetTok(&line,&nname2,1);
68     INPtermInsert(ckt,&nname2,tab,&node2);
69     INPgetNetTok(&line,&ground2,1);
70     INPtermInsert(ckt,&ground2,tab,&gnode2);
71 
72     INPgetNetTok(&line, &model, 1);
73     if(*model) { /* token isn't null */
74             INPinsert(&model,tab);
75             current->error = INPgetMod(ckt,model,&thismodel,tab);
76             INPgetTok(&line,&model,1);
77             if (strcmp(model, "len") == 0) {
78                lenval = INPevaluate(&line,&error1,1);
79                lenvalgiven = 1;
80             }
81             if(thismodel != NULL) {
82                     if (thismodel->INPmodType == mytype2) {
83                             INP2P(ckt,tab,current);
84                             return;
85                     }
86                     else if (mytype != thismodel->INPmodType) {
87                             LITERR("incorrect model type");
88                             return;
89                     }
90                     line = thismodel->INPmodLine->line;
91                     INPgetTok(&line,&buf,1);  /* throw out .model */
92                     INPgetTok(&line,&buf,1);  /* throw out model name */
93                     INPgetTok(&line,&buf,1);  /* throw out txl */
94                     INPgetTok(&line,&buf,1);
95                     while (*line != '\0') {
96                             if (*buf == 'R' || *buf == 'r') {
97                                     INPgetTok(&line,&buf,1);
98                                     rval = INPevaluate(&buf, &error1, 1);
99                             }
100                             if ((strcmp(buf,"L") == 0)  || (strcmp(buf,"l") == 0)) {
101                                     INPgetTok(&line,&buf,1);
102                                     lval = INPevaluate(&buf, &error1, 1);
103                             }
104                             if ((strcmp(buf,"C") == 0)  || (strcmp(buf,"c") == 0)) {
105                                     INPgetTok(&line,&buf,1);
106                                     cval = INPevaluate(&buf, &error1, 1);
107                             }
108                             if (lenvalgiven == 0) {
109                                     if (strcmp(buf,"length")== 0) {
110                                             INPgetTok(&line,&buf,1);
111                                             lenval = INPevaluate(&buf, &error1, 1);
112                                     }
113                             }
114                             INPgetTok(&line,&buf,1);
115                     }
116                     if (lenval && rval && lval && rval/lval > 1.6e10) {
117                             /* use 3-pi model for high resistance as fall back */
118                             rval = 3.0 / (rval * lenval);
119                             cval = cval * lenval / 6.0;
120 
121                             type = INPtypelook("Resistor");
122 
123                             /* resistor between node1 and internal1 */
124                             internal1 = TMALLOC(char, 10 + strlen(name));
125                             strcpy(internal1, "txlnd1");
126                             strcat(internal1, name);
127                             INPtermInsert(ckt, &internal1, tab, &inode1);
128                             if(!tab->defRmod) {
129                                     /* create default R model */
130                                     IFnewUid(ckt, &uid, NULL, "R", UID_MODEL, NULL);
131                                     IFC(newModel, (ckt,type,&(tab->defRmod),uid));
132                             }
133                             mdfast = tab->defRmod;
134                             rname1 = TMALLOC(char, 10 + strlen(name));
135                             strcpy(rname1, "txlres1");
136                             strcat(rname1, name);
137                             INPinsert(&rname1, tab);
138                             IFC(newInstance,(ckt,mdfast,&fast,rname1));
139                             IFC(bindNode,(ckt,fast,1,node1));
140                             IFC(bindNode,(ckt,fast,2,inode1));
141                             ptemp.rValue = rval;
142                             GCA(INPpName,("resistance",&ptemp,ckt,type,fast));
143 
144                             /* resistor between internal1 and internal2 */
145                             internal2 = TMALLOC(char, 10 + strlen(name));
146                             strcpy(internal2, "txlnd2");
147                             strcat(internal2, name);
148                             INPtermInsert(ckt, &internal2, tab, &inode2);
149                             rname2 = TMALLOC(char, 10 + strlen(name));
150                             strcpy(rname2, "txlres2");
151                             strcat(rname2, name);
152                             INPinsert(&rname2, tab);
153                             mdfast2 = tab->defRmod;
154                             IFC(newInstance,(ckt,mdfast2,&fast2,rname2));
155                             IFC(bindNode,(ckt,fast2,1,inode1));
156                             IFC(bindNode,(ckt,fast2,2,inode2));
157                             ptemp.rValue = rval;
158                             GCA(INPpName,("resistance",&ptemp,ckt,type,fast2));
159 
160                             /* resistor between internal2 and node2 */
161                             rname3 = TMALLOC(char, 10 + strlen(name));
162                             strcpy(rname3, "txlres3");
163                             strcat(rname3, name);
164                             INPinsert(&rname3, tab);
165                             mdfast3 = tab->defRmod;
166                             IFC(newInstance,(ckt,mdfast3,&fast3,rname3));
167                             IFC(bindNode,(ckt,fast3,1,inode2));
168                             IFC(bindNode,(ckt,fast3,2,node2));
169                             ptemp.rValue = rval;
170                             GCA(INPpName,("resistance",&ptemp,ckt,type,fast3));
171 
172                             /* capacitor on node1 */
173                             type = INPtypelook("Capacitor");
174                             if(!tab->defCmod) {
175                                     IFnewUid(ckt, &uid, NULL, "C", UID_MODEL, NULL);
176                                     IFC(newModel,(ckt,type,&(tab->defCmod),uid));
177                             }
178                             mdfast4 = tab->defCmod;
179                             cname1 = TMALLOC(char, 10 + strlen(name));
180                             strcpy(cname1, "txlcap1");
181                             strcat(cname1, name);
182                             INPinsert(&cname1, tab);
183                             IFC(newInstance,(ckt,mdfast4,&fast4,cname1));
184                             IFC(bindNode,(ckt,fast4,1,node1));
185                             IFC(bindNode,(ckt,fast4,2,gnode1));
186                             ptemp.rValue = cval;
187                             GCA(INPpName,("capacitance",&ptemp,ckt,type,fast4));
188 
189                             /* capacitor on internal1 */
190                             cname2 = TMALLOC(char, 10 + strlen(name));
191                             strcpy(cname2, "txlcap2");
192                             strcat(cname2, name);
193                             INPinsert(&cname2, tab);
194                             mdfast4 = tab->defCmod;
195                             IFC(newInstance,(ckt,mdfast4,&fast4,cname2));
196                             IFC(bindNode,(ckt,fast4,1,inode1));
197                             IFC(bindNode,(ckt,fast4,2,gnode1));
198                             ptemp.rValue = cval * 2;
199                             GCA(INPpName,("capacitance",&ptemp,ckt,type,fast4));
200 
201                             /* capacitor on internal2 */
202                             cname3 = TMALLOC(char, 10 + strlen(name));
203                             strcpy(cname3, "txlcap3");
204                             strcat(cname3, name);
205                             INPinsert(&cname3, tab);
206                             mdfast5 = tab->defCmod;
207                             IFC(newInstance,(ckt,mdfast5,&fast5,cname3));
208                             IFC(bindNode,(ckt,fast5,1,inode2));
209                             IFC(bindNode,(ckt,fast5,2,gnode1));
210                             ptemp.rValue = cval * 2;
211                             GCA(INPpName,("capacitance",&ptemp,ckt,type,fast5));
212 
213                             /* capacitor on node2 */
214                             cname4 = TMALLOC(char, 10 + strlen(name));
215                             strcpy(cname4, "txlcap4");
216                             strcat(cname4, name);
217                             INPinsert(&cname4, tab);
218                             mdfast6 = tab->defCmod;
219                             IFC(newInstance,(ckt,mdfast6,&fast6,cname4));
220                             IFC(bindNode,(ckt,fast6,1,node2));
221                             IFC(bindNode,(ckt,fast6,2,gnode1));
222                             ptemp.rValue = cval;
223                             GCA(INPpName,("capacitance",&ptemp,ckt,type,fast6));
224                             return;
225 
226                     }
227 
228                     /* use regular txl model */
229                     mdfast = thismodel->INPmodfast;
230                     type = thismodel->INPmodType;
231             } else {
232                     type = mytype;
233                     if(!tab->defYmod) {
234                             /* create default Y model */
235                             IFnewUid(ckt, &uid, NULL, "Y", UID_MODEL, NULL);
236                             IFC(newModel, (ckt,type,&(tab->defYmod),uid));
237                     }
238                     mdfast = tab->defYmod;
239             }
240             IFC(newInstance,(ckt,mdfast,&fast,name));
241     } else  {
242             LITERR("model name is not found");
243             return;
244     }
245 
246     if (error1 == 0 && lenvalgiven) {
247             ptemp.rValue = lenval;
248             GCA(INPpName,("length",&ptemp,ckt,type,fast));
249     }
250 
251     IFC(bindNode,(ckt,fast,1,node1));
252     IFC(bindNode,(ckt,fast,2,node2));
253 
254     txl = /*fixme*/ fast;
255 
256     return;
257 }
258