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