|
|
1.1 root 1: subroutine errchk
2: implicit double precision (a-h,o-z)
3: c
4: c
5: c this routine drives the pre-processing and general error-checking
6: c of input performed by spice.
7: c
8: common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem,
9: 1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize,
10: 2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr,
11: 3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1,
12: 4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd,
13: 5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval
14: common /miscel/ atime,aprog(3),adate,atitle(10),defl,defw,defad,
15: 1 defas,rstats(50),iwidth,lwidth,nopage
16: common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop,
17: 1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs
18: common /cje/ maxtim,itime,icost
19: common /status/ omega,time,delta,delold(7),ag(7),vt,xni,egfet,
20: 1 xmu,mode,modedc,icalc,initf,method,iord,maxord,noncon,iterno,
21: 2 itemno,nosolv,ipostp,iscrch
22: common /flags/ iprnta,iprntl,iprntm,iprntn,iprnto,limtim,limpts,
23: 1 lvlcod,lvltim,itl1,itl2,itl3,itl4,itl5,igoof,nogo,keof
24: common /knstnt/ twopi,xlog2,xlog10,root2,rad,boltz,charge,ctok,
25: 1 gmin,reltol,abstol,vntol,trtol,chgtol,eps0,epssil,epsox
26: common /dc/ tcstar(2),tcstop(2),tcincr(2),icvflg,itcelm(2),kssop,
27: 1 kinel,kidin,kovar,kidout
28: common /ac/ fstart,fstop,fincr,skw2,refprl,spw2,jacflg,idfreq,
29: 1 inoise,nosprt,nosout,nosin,idist,idprt
30: common /tran/ tstep,tstop,tstart,delmax,tdmax,forfre,jtrflg
31: common /outinf/ xincr,string(15),xstart,yvar(8),itab(8),itype(8),
32: 1 ilogy(8),npoint,numout,kntr,numdgt
33: common /blank/ value(1000)
34: integer nodplc(64)
35: complex*16 cvalue(32)
36: equivalence (value(1),nodplc(1),cvalue(1))
37: c
38: c
39: dimension titlop(4)
40: dimension nnods(50),aname(2)
41: data aname / 4htrap, 4hgear /
42: data titlop / 8hoption s, 8hummary , 8h , 8h /
43: data ndefin / 2h.u /
44: data nnods / 2, 2, 2, 0, 2, 2, 2, 2, 2, 2,
45: 1 2, 4, 3, 4, 0, 0, 4, 0, 1, 0,
46: 2 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
47: 3 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
48: 4 2, 2, 2, 0, 0, 0, 0, 0, 0, 0 /
49: data aelmt,amodel,aoutpt /7helement,5hmodel,6houtput/
50: data alsdc,alstr,alsac / 2hdc, 4htran, 2hac /
51: c
52: c
53: call second(t1)
54: do 60 id=1,50
55: loc=locate(id)
56: 10 if (loc.eq.0) go to 60
57: if (nodplc(loc+2).ne.ndefin) go to 50
58: nogo=1
59: locv=nodplc(loc+1)
60: if (id.ge.21) go to 20
61: anam=aelmt
62: go to 40
63: 20 if (id.ge.31) go to 30
64: anam=amodel
65: go to 40
66: 30 anam=aoutpt
67: 40 write (6,41) anam,value(locv)
68: 41 format('0*error*: ',2a8,' has been referenced but not defined'/)
69: 50 loc=nodplc(loc)
70: go to 10
71: 60 continue
72: if (nogo.ne.0) go to 2000
73: c
74: c construct ordered list of user specified nodes
75: c
76: call getm4(junode,1)
77: nodplc(junode+1)=0
78: nunods=1
79: do 180 id=1,50
80: if (nnods(id).eq.0) go to 180
81: loc=locate(id)
82: 110 if (loc.eq.0) go to 180
83: if (id.le.4) go to 120
84: if (id.le.8) go to 150
85: if (id.eq.19) go to 165
86: if (id.le.40) go to 120
87: if (id.le.43) go to 170
88: 120 jstop=loc+nnods(id)-1
89: do 130 j=loc,jstop
90: call putnod(nodplc(j+2))
91: 130 continue
92: go to 170
93: 150 call putnod(nodplc(loc+2))
94: call putnod(nodplc(loc+3))
95: if (id.ge.7) go to 170
96: locp=nodplc(loc+id+1)
97: nssnod=2*nodplc(loc+4)
98: 155 do 160 j=1,nssnod
99: call putnod(nodplc(locp+j))
100: 160 continue
101: go to 170
102: 165 locp=nodplc(loc+2)
103: call sizmem(nodplc(loc+2),nssnod)
104: go to 155
105: 170 loc=nodplc(loc)
106: go to 110
107: 180 continue
108: if (nogo.ne.0) go to 2000
109: ncnods=nunods
110: c
111: c assign program nodes
112: c
113: 200 do 280 id=1,50
114: if (nnods(id).eq.0) go to 280
115: loc=locate(id)
116: 210 if (loc.eq.0) go to 280
117: if (id.le.4) go to 220
118: if (id.le.8) go to 250
119: if (id.eq.19) go to 265
120: if (id.le.40) go to 220
121: if (id.le.43) go to 240
122: 220 jstop=loc+nnods(id)-1
123: do 230 j=loc,jstop
124: call getnod(nodplc(j+2))
125: 230 continue
126: go to 270
127: 240 if (nodplc(loc+5).eq.0) go to 220
128: go to 270
129: 250 call getnod(nodplc(loc+2))
130: call getnod(nodplc(loc+3))
131: if (id.ge.7) go to 270
132: locp=nodplc(loc+id+1)
133: nssnod=2*nodplc(loc+4)
134: 255 do 260 j=1,nssnod
135: call getnod(nodplc(locp+j))
136: 260 continue
137: go to 270
138: 265 locp=nodplc(loc+2)
139: call sizmem(nodplc(loc+2),nssnod)
140: go to 255
141: 270 loc=nodplc(loc)
142: go to 210
143: 280 continue
144: c
145: c check and set .nodeset nodes to their internal values
146: c
147: call sizmem(nsnod,nic)
148: if(nic.eq.0) go to 300
149: do 290 i=1,nic
150: call getnod(nodplc(nsnod+i))
151: 290 continue
152: c
153: c check and set .ic nodes to their internal values
154: c
155: 300 call sizmem(icnod,nic)
156: if(nic.eq.0) go to 320
157: do 310 i=1,nic
158: call getnod(nodplc(icnod+i))
159: 310 continue
160: 320 if (nogo.ne.0) go to 2000
161: c
162: c expand subcircuit calls
163: c
164: call subckt
165: if (nogo.ne.0) go to 2000
166: if (ncnods.ge.2) go to 400
167: write (6,321)
168: 321 format('0*error*: circuit has no nodes'/)
169: nogo=1
170: go to 2000
171: 400 numnod=ncnods
172: c
173: c link unsatisfied references
174: c
175: call lnkref
176: if (nogo.ne.0) go to 2000
177: c
178: c generate subcircuit element names
179: c
180: if (jelcnt(19).eq.0) go to 530
181: do 520 id=1,24
182: loc=locate(id)
183: 510 if (loc.eq.0) go to 520
184: call subnam(loc)
185: loc=nodplc(loc)
186: go to 510
187: 520 continue
188: c
189: c translate node initial conditions to device initial conditions
190: c (capacitance, diode, bjt, and mosfet only
191: c
192: 530 call sizmem(icnod,nic)
193: if(nic.eq.0) go to 600
194: call getm8(lvnim1,numnod)
195: call zero8(value(lvnim1+1),numnod)
196: do 535 i=1,nic
197: node=nodplc(icnod+i)
198: 535 value(lvnim1+node)=value(icval+i)
199: loc=locate(2)
200: 540 if(loc.eq.0) go to 550
201: locv=nodplc(loc+1)
202: if(value(locv+2).ne.0.0d0) go to 545
203: node1=nodplc(loc+2)
204: node2=nodplc(loc+3)
205: value(locv+2)=value(lvnim1+node1)-value(lvnim1+node2)
206: 545 loc=nodplc(loc)
207: go to 540
208: 550 loc=locate(11)
209: 555 if(loc.eq.0) go to 565
210: locv=nodplc(loc+1)
211: if(value(locv+2).ne.0.0d0) go to 560
212: node1=nodplc(loc+2)
213: node2=nodplc(loc+3)
214: value(locv+2)=value(lvnim1+node1)-value(lvnim1+node2)
215: 560 loc=nodplc(loc)
216: go to 555
217: 565 loc=locate(12)
218: 570 if(loc.eq.0) go to 580
219: locv=nodplc(loc+1)
220: node1=nodplc(loc+2)
221: node2=nodplc(loc+3)
222: node3=nodplc(loc+4)
223: if(value(locv+2).eq.0.0d0) value(locv+2)=value(lvnim1+node2)-
224: 1 value(lvnim1+node3)
225: if(value(locv+3).eq.0.0d0) value(locv+3)=value(lvnim1+node1)-
226: 1 value(lvnim1+node3)
227: loc=nodplc(loc)
228: go to 570
229: 580 loc=locate(13)
230: 585 if(loc.eq.0) go to 590
231: locv=nodplc(loc+1)
232: node1=nodplc(loc+2)
233: node2=nodplc(loc+3)
234: node3=nodplc(loc+4)
235: if(value(locv+2).eq.0.0d0) value(locv+2)=value(lvnim1+node1)-
236: 1 value(lvnim1+node3)
237: if(value(locv+3).eq.0.0d0) value(locv+3)=value(lvnim1+node2)-
238: 1 value(lvnim1+node3)
239: loc=nodplc(loc)
240: go to 585
241: 590 loc=locate(14)
242: 595 if(loc.eq.0) go to 598
243: locv=nodplc(loc+1)
244: node1=nodplc(loc+2)
245: node2=nodplc(loc+3)
246: node3=nodplc(loc+4)
247: node4=nodplc(loc+5)
248: if(value(locv+5).eq.0.0d0) value(locv+5)=value(lvnim1+node1)-
249: 1 value(lvnim1+node3)
250: if(value(locv+6).eq.0.0d0) value(locv+6)=value(lvnim1+node2)-
251: 1 value(lvnim1+node3)
252: if(value(locv+7).eq.0.0d0) value(locv+7)=value(lvnim1+node4)-
253: 1 value(lvnim1+node3)
254: loc=nodplc(loc)
255: go to 595
256: 598 call clrmem(lvnim1)
257: c
258: c process sources
259: c
260: 600 if (jtrflg.eq.0) go to 700
261: do 690 id=9,10
262: loc=locate(id)
263: 610 if (loc.eq.0) go to 690
264: locv=nodplc(loc+1)
265: locp=nodplc(loc+5)
266: jtype=nodplc(loc+4)+1
267: go to (680,620,630,640,650,675), jtype
268: 620 value(locp+3)=dmax1(value(locp+3),0.0d0)
269: if (value(locp+4).le.0.0d0) value(locp+4)=tstep
270: if (value(locp+5).le.0.0d0) value(locp+5)=tstep
271: if (value(locp+6).le.0.0d0) value(locp+6)=tstop
272: if (value(locp+7).le.0.0d0) value(locp+7)=tstop
273: temp=value(locp+4)+value(locp+5)+value(locp+6)
274: value(locp+7)=dmax1(value(locp+7),temp)
275: value(locv+1)=value(locp+1)
276: go to 680
277: 630 if (value(locp+3).le.0.0d0) value(locp+3)=1.0d0/tstop
278: value(locp+4)=dmax1(value(locp+4),0.0d0)
279: value(locv+1)=value(locp+1)
280: go to 680
281: 640 value(locp+3)=dmax1(value(locp+3),0.0d0)
282: if (value(locp+4).le.0.0d0) value(locp+4)=tstep
283: if (value(locp+5).le.value(locp+3))
284: 1 value(locp+5)=value(locp+3)+tstep
285: if (value(locp+6).le.0.0d0) value(locp+6)=tstep
286: value(locv+1)=value(locp+1)
287: go to 680
288: 650 value(locp+1)=dmin1(dmax1(value(locp+1),0.0d0),tstop)
289: iknt=1
290: call sizmem(nodplc(loc+5),nump)
291: 660 temp=value(locp+iknt)
292: if (value(locp+iknt+2).eq.0.0d0) go to 670
293: if (value(locp+iknt+2).ge.tstop) go to 670
294: value(locp+iknt+2)=dmax1(value(locp+iknt+2),temp)
295: if(temp.ne.value(locp+iknt+2)) go to 665
296: write(6,661) value(locv)
297: 661 format('0*error*: element ',a8,' piecewise linear source table no
298: 1t increasing in time')
299: nogo=1
300: 665 iknt=iknt+2
301: if (iknt.lt.nump) go to 660
302: 670 value(locp+iknt+2)=tstop
303: value(locv+1)=value(locp+2)
304: call relmem(nodplc(loc+5),nump-iknt-3)
305: go to 680
306: 675 if (value(locp+3).le.0.0d0) value(locp+3)=1.0d0/tstop
307: if (value(locp+5).le.0.0d0) value(locp+5)=1.0d0/tstop
308: value(locv+1)=value(locp+1)
309: 680 loc=nodplc(loc)
310: go to 610
311: 690 continue
312: c
313: c use default values for mos device geometries if not specified
314: c
315: 700 loc=locate(14)
316: 710 if(loc.eq.0) go to 720
317: locv=nodplc(loc+1)
318: if(value(locv+1).le.0.0d0) value(locv+1)=defl
319: if(value(locv+2).le.0.0d0) value(locv+2)=defw
320: if(value(locv+3).le.0.0d0) value(locv+3)=defad
321: if(value(locv+4).le.0.0d0) value(locv+4)=defas
322: loc=nodplc(loc)
323: go to 710
324: c
325: c print listing of elements, process device models,
326: c and check topology
327: c
328: 720 if (iprntl.eq.0) go to 730
329: call elprnt
330: 730 call topchk
331: call modchk
332: if (nogo.ne.0) go to 2000
333: c
334: c invert resistance values
335: c
336: 800 loc=locate(1)
337: 810 if (loc.eq.0) go to 900
338: locv=nodplc(loc+1)
339: value(locv+1)=1.0d0/value(locv+2)
340: loc=nodplc(loc)
341: go to 810
342: c
343: c process mutual inductors
344: c
345: 900 loc=locate(4)
346: 910 if (loc.eq.0) go to 940
347: locv=nodplc(loc+1)
348: nl1=nodplc(loc+2)
349: call sizmem(nodplc(nl1+10),nparam)
350: if (nparam.ne.1) go to 920
351: ispot1=nodplc(nl1+1)
352: jspot=nodplc(nl1+10)
353: value(ispot1+1)=value(jspot+1)
354: if (value(ispot1+1).lt.0.0d0) go to 920
355: nl2=nodplc(loc+3)
356: call sizmem(nodplc(nl2+10),nparam)
357: if (nparam.ne.1) go to 920
358: ispot2=nodplc(nl2+1)
359: jspot=nodplc(nl2+10)
360: value(ispot2+1)=value(jspot+1)
361: if (value(ispot2+1).lt.0.0d0) go to 920
362: value(locv+1)=value(locv+1)*dsqrt(value(ispot1+1)*value(ispot2+1))
363: go to 930
364: 920 write (6,921) value(locv)
365: 921 format('0*error*: inductors coupled by ',a8,' are negative or non
366: 1linear'/)
367: nogo=1
368: 930 loc=nodplc(loc)
369: go to 910
370: 940 if (nogo.ne.0) go to 2000
371: c
372: c limit delmax to minimum delay over 2 if transmission lines in circuit
373: c
374: if (jtrflg.eq.0) go to 1200
375: tdmax=0.0d0
376: loc=locate(17)
377: 1010 if (loc.eq.0) go to 1200
378: locv=nodplc(loc+1)
379: delmax=dmin1(delmax,value(locv+2)/2.0d0)
380: tdmax=dmax1(tdmax,value(locv+2))
381: loc=nodplc(loc)
382: go to 1010
383: c
384: c process source parameters
385: c
386: 1200 numbkp=0
387: if (jtrflg.eq.0) go to 1205
388: tol=1.0d-2*delmax
389: numbkp=2
390: call getm8(lsbkpt,numbkp)
391: value(lsbkpt+1)=0.0d0
392: value(lsbkpt+2)=tstop
393: 1205 do 1290 id=9,10
394: loc=locate(id)
395: 1210 if (loc.eq.0) go to 1290
396: locv=nodplc(loc+1)
397: locp=nodplc(loc+5)
398: temp=value(locv+3)/rad
399: value(locv+3)=value(locv+2)*dsin(temp)
400: value(locv+2)=value(locv+2)*dcos(temp)
401: if (jtrflg.eq.0) go to 1280
402: jtype=nodplc(loc+4)+1
403: go to (1280,1220,1230,1235,1240,1260), jtype
404: 1220 value(locp+4)=value(locp+4)+value(locp+3)
405: temp=value(locp+5)
406: value(locp+5)=value(locp+4)+value(locp+6)
407: value(locp+6)=value(locp+5)+temp
408: time=0.0d0
409: 1225 call extmem(lsbkpt,4)
410: value(lsbkpt+numbkp+1)=value(locp+3)+time
411: value(lsbkpt+numbkp+2)=value(locp+4)+time
412: value(lsbkpt+numbkp+3)=value(locp+5)+time
413: value(lsbkpt+numbkp+4)=value(locp+6)+time
414: numbkp=numbkp+4
415: time=time+value(locp+7)
416: if (time.ge.tstop) go to 1280
417: go to 1225
418: 1230 value(locp+3)=value(locp+3)*twopi
419: call extmem(lsbkpt,1)
420: 1231 value(lsbkpt+numbkp+1)=value(locp+4)
421: numbkp=numbkp+1
422: go to 1280
423: 1235 call extmem(lsbkpt,2)
424: value(lsbkpt+numbkp+1)=value(locp+3)
425: value(lsbkpt+numbkp+2)=value(locp+5)
426: numbkp=numbkp+2
427: go to 1280
428: 1240 iknt=1
429: call sizmem(nodplc(loc+5),nump)
430: 1250 call extmem(lsbkpt,1)
431: value(lsbkpt+numbkp+1)=value(locp+iknt)
432: numbkp=numbkp+1
433: iknt=iknt+2
434: if (iknt.le.nump) go to 1250
435: go to 1280
436: 1260 value(locp+3)=value(locp+3)*twopi
437: value(locp+5)=value(locp+5)*twopi
438: 1280 loc=nodplc(loc)
439: go to 1210
440: 1290 continue
441: 1300 if (jtrflg.eq.0) go to 1600
442: call extmem(lsbkpt,1)
443: value(lsbkpt+numbkp+1)=tstop
444: numbkp=numbkp+1
445: call shlsrt(value(lsbkpt+1),numbkp)
446: nbkpt=1
447: do 1310 i=2,numbkp
448: if ((value(lsbkpt+i)-value(lsbkpt+nbkpt)).lt.tol) go to 1310
449: nbkpt=nbkpt+1
450: value(lsbkpt+nbkpt)=value(lsbkpt+i)
451: if (value(lsbkpt+nbkpt).ge.tstop) go to 1320
452: 1310 continue
453: 1320 call relmem(lsbkpt,numbkp-nbkpt)
454: numbkp=nbkpt
455: value(lsbkpt+numbkp)=dmax1(value(lsbkpt+numbkp),tstop)
456: c
457: c print option summary
458: c
459: 1600 if (iprnto.eq.0) go to 1700
460: call title(0,lwidth,1,titlop)
461: write (6,1601) gmin,reltol,abstol,vntol,lvlcod,itl1,itl2
462: 1601 format('0dc analysis -',/,
463: 1 '0 gmin = ',1pd10.3,/,
464: 2 ' reltol = ', d10.3,/,
465: 3 ' abstol = ', d10.3,/,
466: 4 ' vntol = ', d10.3,/,
467: 5 ' lvlcod = ', i6,/,
468: 6 ' itl1 = ', i6,/,
469: 7 ' itl2 = ', i6,/)
470: write (6,1611) aname(method),maxord,chgtol,trtol,lvltim,xmu,
471: 1 itl3,itl4,itl5
472: 1611 format('0transient analysis -',/,
473: 1 '0 method = ',a8,/,
474: 2 ' maxord = ', i6,/,
475: 3 ' chgtol = ',1pd10.3,/,
476: 4 ' trtol = ', d10.3,/,
477: 5 ' lvltim = ', i6,/,
478: 6 ' mu = ',0pf10.3,/,
479: 7 ' itl3 = ', i6,/,
480: 8 ' itl4 = ', i6,/,
481: 9 ' itl5 = ', i6,/)
482: write (6,1621) limpts,limtim,maxtim,numdgt,value(itemps+1),
483: 1 defl,defw,defad,defas
484: 1621 format('0miscellaneous -',/,
485: 1 '0 limpts = ', i6,/,
486: 2 ' limtim = ', i6,/,
487: 3 ' cptime = ', i6,/,
488: 4 ' numdgt = ', i6,/,
489: 5 ' tnom = ',0pf10.3,/,
490: 6 ' defl = ',1pe10.3,/,
491: 7 ' defw = ',e10.3,/,
492: 8 ' defad = ',e10.3,/,
493: 9 ' defas = ',e10.3)
494: c
495: c miscellaneous error checking
496: c
497: 1700 if (icvflg.eq.0) go to 1720
498: if (icvflg.le.limpts) go to 1710
499: icvflg=0
500: write (6,1701) limpts,alsdc
501: 1701 format('0warning: more than ',i5,' points for ',a4,' analysis,',/
502: 11x,'analysis omitted. this limit may be overridden using the ',/
503: 21x,'limpts parameter on the .option card'/)
504: go to 1720
505: 1710 if ((jelcnt(31)+jelcnt(36)).gt.0) go to 1720
506: if(ipostp.ne.0) go to 1720
507: icvflg=0
508: write (6,1711) alsdc
509: 1711 format('0warning: no ',a4,' outputs specified .',
510: 1 '.. analysis omitted'/)
511: 1720 if (jtrflg.eq.0) go to 1740
512: if (method.eq.1) maxord=2
513: if ((method.eq.2).and.(maxord.ge.3)) lvltim=2
514: if (jtrflg.le.limpts) go to 1730
515: jtrflg=0
516: write (6,1701) limpts,alstr
517: go to 1740
518: 1730 if ((jelcnt(32)+jelcnt(37)+nfour).gt.0) go to 1735
519: if(ipostp.ne.0) go to 1735
520: jtrflg=0
521: write (6,1711) alstr
522: go to 1740
523: 1735 if (nfour.eq.0) go to 1740
524: forprd=1.0d0/forfre
525: if ((tstop-forprd).ge.(tstart-1.0d-12)) go to 1740
526: nfour=0
527: call clrmem(ifour)
528: write (6,1736)
529: 1736 format('0warning: fourier analysis fundamental frequency is incom
530: 1patible with'/11x'transient analysis print interval ... fourier an
531: 2alysis omitted'/)
532: 1740 if (jacflg.eq.0) go to 1800
533: if (jacflg.le.limpts) go to 1750
534: jacflg=0
535: write (6,1701) limpts,alsac
536: go to 1800
537: 1750 if ((jelcnt(33)+jelcnt(34)+jelcnt(35)+jelcnt(38)+jelcnt(39)
538: 1 +jelcnt(40)+idist+inoise).gt.0) go to 1800
539: if(ipostp.ne.0) go to 1800
540: jacflg=0
541: write (6,1711) alsac
542: c
543: c sequence through the output lists
544: c
545: 1800 do 1820 id=41,45
546: if (id.le.43) numout=1
547: loc=locate(id)
548: 1810 if (loc.eq.0) go to 1820
549: numout=numout+1
550: nodplc(loc+4)=numout
551: loc=nodplc(loc)
552: go to 1810
553: 1820 continue
554: c
555: c increase number of .prints if too many outputs for output line-width
556: c
557: ifwdth=max0(numdgt-1,0)+9
558: noprln=min0(8,(lwidth-12)/ifwdth)
559: do 1860 id=31,35
560: loc=locate(id)
561: 1830 if(loc.eq.0) go to 1860
562: noprex=nodplc(loc+3)-noprln
563: if(noprex.le.0) go to 1850
564: nodplc(loc+3)=noprln
565: call find(dfloat(jelcnt(id)),id,locnew,1)
566: nodplc(locnew+2)=nodplc(loc+2)
567: nodplc(locnew+3)=noprex
568: call copy4(nodplc(loc+2*noprln+4),nodplc(locnew+4),2*noprex)
569: 1850 loc=nodplc(loc)
570: go to 1830
571: 1860 continue
572: c
573: c exit
574: c
575: 2000 call second(t2)
576: rstats(1)=rstats(1)+t2-t1
577: return
578: end
579: subroutine shlsrt(a,n)
580: implicit double precision (a-h,o-z)
581: c
582: c this routine sorts the array a using a shell sort algorithm.
583: c
584: dimension a(n)
585: integer h
586: c
587: c
588: c... compute best starting step size
589: h=1
590: 10 h=3*h+1
591: if (h.lt.n) go to 10
592: c... back off two times
593: h=(h-1)/3
594: h=(h-1)/3
595: h=max0(h,1)
596: c
597: c shell sort
598: c
599: 20 j=h+1
600: go to 60
601: 30 i=j-h
602: c... ak = record key; ar = record
603: ak=a(j)
604: ar=ak
605: 40 if (ak.ge.a(i)) go to 50
606: a(i+h)=a(i)
607: i=i-h
608: if (i.ge.1) go to 40
609: 50 a(i+h)=ar
610: j=j+1
611: 60 if (j.le.n) go to 30
612: h=(h-1)/3
613: if (h.ne.0) go to 20
614: return
615: end
616: subroutine putnod(node)
617: implicit double precision (a-h,o-z)
618: c
619: c this routine adds 'node' to the list of user input nodes in table
620: c junode.
621: c
622: common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem,
623: 1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize,
624: 2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr,
625: 3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1,
626: 4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd,
627: 5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval
628: common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop,
629: 1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs
630: common /blank/ value(1000)
631: integer nodplc(64)
632: complex*16 cvalue(32)
633: equivalence (value(1),nodplc(1),cvalue(1))
634: c
635: c
636: jknt=0
637: 10 jknt=jknt+1
638: if (jknt.gt.nunods) go to 20
639: if (node-nodplc(junode+jknt)) 20,100,10
640: 20 k=nunods+1
641: call extmem(junode,1)
642: if (k.le.jknt) go to 30
643: call copy4(nodplc(junode+jknt),nodplc(junode+jknt+1),k-jknt)
644: k=jknt
645: 30 nodplc(junode+k)=node
646: nunods=nunods+1
647: c
648: c finished
649: c
650: 100 return
651: end
652: subroutine getnod(node)
653: implicit double precision (a-h,o-z)
654: c
655: c this routine converts from the user node number to the internal
656: c (compact) node number.
657: c
658: common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem,
659: 1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize,
660: 2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr,
661: 3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1,
662: 4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd,
663: 5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval
664: common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop,
665: 1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs
666: common /flags/ iprnta,iprntl,iprntm,iprntn,iprnto,limtim,limpts,
667: 1 lvlcod,lvltim,itl1,itl2,itl3,itl4,itl5,igoof,nogo,keof
668: common /blank/ value(1000)
669: integer nodplc(64)
670: complex*16 cvalue(32)
671: equivalence (value(1),nodplc(1),cvalue(1))
672: c
673: c
674: if (nogo.ne.0) go to 100
675: jknt=0
676: 10 jknt=jknt+1
677: if (jknt.gt.nunods) go to 20
678: if (nodplc(junode+jknt).ne.node) go to 10
679: node=jknt
680: go to 100
681: c
682: c unknown node -- must be implied by .print and/or .plot
683: c
684: 20 if (node.eq.0) go to 30
685: write (6,21) node
686: 21 format('0warning: attempt to reference undefined node ',i5,
687: 1 ' -- node reset to 0'/)
688: 30 node=1
689: c
690: c finished
691: c
692: 100 return
693: end
694: subroutine subckt
695: implicit double precision (a-h,o-z)
696: c
697: c this routine drives the expansion of subcircuit calls.
698: c
699: common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem,
700: 1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize,
701: 2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr,
702: 3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1,
703: 4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd,
704: 5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval
705: common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop,
706: 1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs
707: common /flags/ iprnta,iprntl,iprntm,iprntn,iprnto,limtim,limpts,
708: 1 lvlcod,lvltim,itl1,itl2,itl3,itl4,itl5,igoof,nogo,keof
709: common /blank/ value(1000)
710: integer nodplc(64)
711: complex*16 cvalue(32)
712: equivalence (value(1),nodplc(1),cvalue(1))
713: c
714: c
715: c... avoid 'call by value' problems, make inodi, inodx arrays
716: c... in routines which receive them as parameters !!!
717: locx=locate(19)
718: 10 if (locx.eq.0) go to 300
719: locs=nodplc(locx+3)
720: asnam=value(iunsat+locs)
721: call fndnam(asnam,locx-1,locx+3,20)
722: if (nogo.ne.0) go to 300
723: locs=nodplc(locx+3)
724: c
725: c check for recursion
726: c
727: isbptr=nodplc(locx-1)
728: 20 if (isbptr.eq.0) go to 30
729: if (locs.eq.nodplc(isbptr+3)) go to 260
730: isbptr=nodplc(isbptr-1)
731: go to 20
732: c
733: c
734: 30 call sizmem(nodplc(locx+2),nxnod)
735: call sizmem(nodplc(locs+2),nssnod)
736: if (nxnod.ne.nssnod) go to 250
737: call getm4(inodx,nssnod)
738: call getm4(inodi,nssnod)
739: itemp=nodplc(locs+2)
740: call copy4(nodplc(itemp+1),nodplc(inodx+1),nssnod)
741: itemp=nodplc(locx+2)
742: call copy4(nodplc(itemp+1),nodplc(inodi+1),nxnod)
743: c
744: c add elements of subcircuit to nominal circuit
745: c
746: loc=nodplc(locs+3)
747: 100 if (loc.eq.0) go to 200
748: id=nodplc(loc-1)
749: if (id.eq.20) go to 110
750: call find(dfloat(jelcnt(id)),id,loce,1)
751: nodplc(loce-1)=locx
752: call addelt(loce,loc,id,inodx,inodi,nxnod)
753: 110 loc=nodplc(loc)
754: go to 100
755: c
756: c
757: 200 call clrmem(inodx)
758: call clrmem(inodi)
759: locx=nodplc(locx)
760: go to 10
761: c
762: c errors
763: c
764: 250 locv=nodplc(locx+1)
765: axnam=value(locv)
766: locv=nodplc(locs+1)
767: asnam=value(locv)
768: write (6,251) axnam,asnam
769: 251 format('0*error*: ',a8,' has different number of nodes than ',a8/
770: 1)
771: nogo=1
772: go to 300
773: 260 locsv=nodplc(locs+1)
774: asnam=value(locsv)
775: write (6,261) asnam
776: 261 format('0*error*: subcircuit ',a8,' is defined recursively'/)
777: nogo=1
778: c
779: c finished
780: c
781: 300 return
782: end
783: subroutine fndnam(anam,jsbptr,ispot,id)
784: implicit double precision (a-h,o-z)
785: c
786: c this routine searches for an element with id 'id' by tracing back
787: c up the subcircuit definition list. if the element is not found, the
788: c nominal element list is searched.
789: c
790: common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem,
791: 1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize,
792: 2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr,
793: 3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1,
794: 4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd,
795: 5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval
796: common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop,
797: 1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs
798: common /flags/ iprnta,iprntl,iprntm,iprntn,iprnto,limtim,limpts,
799: 1 lvlcod,lvltim,itl1,itl2,itl3,itl4,itl5,igoof,nogo,keof
800: common /blank/ value(1000)
801: integer nodplc(64)
802: complex*16 cvalue(32)
803: equivalence (value(1),nodplc(1),cvalue(1))
804: integer xxor
805: c
806: c
807: isbptr=nodplc(jsbptr)
808: 10 if (isbptr.eq.0) go to 50
809: isub=nodplc(isbptr+3)
810: loc=nodplc(isub+3)
811: 20 if (loc.eq.0) go to 40
812: if (id.ne.nodplc(loc-1)) go to 30
813: locv=nodplc(loc+1)
814: if (xxor(anam,value(locv)).ne.0) go to 30
815: if (id.ne.20) go to 50
816: go to 65
817: 30 loc=nodplc(loc)
818: go to 20
819: 40 isbptr=nodplc(isbptr-1)
820: go to 10
821: c
822: 50 loc=locate(id)
823: 60 if (loc.eq.0) go to 90
824: if (nodplc(loc-1).ne.isbptr) go to 70
825: locv=nodplc(loc+1)
826: if (xxor(anam,value(locv)).ne.0) go to 70
827: 65 nodplc(ispot)=loc
828: go to 100
829: 70 loc=nodplc(loc)
830: go to 60
831: 90 write (6,91) anam
832: 91 format('0*error*: unable to find ',a8/)
833: nogo=1
834: 100 return
835: end
836: subroutine newnod(nodold,nodnew,inodx,inodi,nnodi)
837: implicit double precision (a-h,o-z)
838: c
839: c this routine makes a new node number for an element which is about
840: c to be added to the circuit as a result of a subcircuit call.
841: c
842: common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem,
843: 1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize,
844: 2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr,
845: 3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1,
846: 4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd,
847: 5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval
848: common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop,
849: 1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs
850: common /blank/ value(1000)
851: integer nodplc(64)
852: complex*16 cvalue(32)
853: equivalence (value(1),nodplc(1),cvalue(1))
854: c
855: c... inodx, inodi are arrays (see subckt)
856: dimension inodx(1),inodi(1)
857: c
858: if (nodold.ne.0) go to 5
859: nodnew=1
860: go to 20
861: 5 do 10 i=1,nnodi
862: jnodx=inodx(1)
863: if (nodold.ne.nodplc(jnodx+i)) go to 10
864: jnodi=inodi(1)
865: nodnew=nodplc(jnodi+i)
866: go to 20
867: 10 continue
868: c
869: call extmem(inodx(1),1)
870: call extmem(inodi(1),1)
871: call extmem(junode,1)
872: nnodi=nnodi+1
873: ncnods=ncnods+1
874: jnodx=inodx(1)
875: nodplc(jnodx+nnodi)=nodold
876: jnodi=inodi(1)
877: nodplc(jnodi+nnodi)=ncnods
878: nodplc(junode+ncnods)=nodplc(junode+ncnods-1)+1
879: nodnew=ncnods
880: 20 return
881: end
882: subroutine addelt(loce,loc,id,inodx,inodi,nnodi)
883: implicit double precision (a-h,o-z)
884: c
885: c this routine adds an element to the nominal circuit definition
886: c lists.
887: c
888: common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem,
889: 1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize,
890: 2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr,
891: 3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1,
892: 4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd,
893: 5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval
894: common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop,
895: 1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs
896: common /flags/ iprnta,iprntl,iprntm,iprntn,iprnto,limtim,limpts,
897: 1 lvlcod,lvltim,itl1,itl2,itl3,itl4,itl5,igoof,nogo,keof
898: common /blank/ value(1000)
899: integer nodplc(64)
900: complex*16 cvalue(32)
901: equivalence (value(1),nodplc(1),cvalue(1))
902: c
903: c... inodx(1), inodi(1) are arrays (see subckt)
904: dimension inodx(1),inodi(1)
905: c
906: dimension lnod(50),lval(50),nnods(50)
907: data lnod / 9,13,15, 7,14,15,14,15,12, 7,
908: 1 17,37,26,34, 7, 7,34, 0, 5, 5,
909: 2 4, 4, 4, 4, 0, 0, 0, 0, 0, 0,
910: 3 21,21,21,21,21,21,21,21,21,21,
911: 4 8, 8, 8, 8, 8, 0, 0, 0, 0, 0 /
912: data lval / 5, 4, 4, 2, 1, 1, 1, 1, 4, 4,
913: 1 3, 4, 4,13, 1, 1, 9, 0, 1, 1,
914: 2 19,55,17,41, 0, 0, 0, 0, 0, 0,
915: 3 1, 1, 1, 1, 1,17,17,17,17,17,
916: 4 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 /
917: data nnods / 2, 2, 2, 0, 2, 2, 2, 2, 2, 2,
918: 1 2, 4, 3, 4, 4, 4, 4, 0, 1, 0,
919: 2 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
920: 3 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
921: 4 2, 2, 2, 0, 0, 0, 0, 0, 0, 0 /
922: c
923: c copy integer part
924: c
925: nword=lnod(id)-3
926: if (nword.le.0) go to 10
927: call copy4(nodplc(loc+2),nodplc(loce+2),nword)
928: c
929: c set nodes
930: c
931: 10 if (id.ge.21) go to 100
932: if (nnods(id).eq.0) go to 100
933: if (id.le.4) go to 20
934: if (id.le.8) go to 40
935: if (id.eq.19) go to 70
936: 20 jstop=nnods(id)
937: do 30 j=1,jstop
938: call newnod(nodplc(loc+j+1),nodplc(loce+j+1),inodx(1),
939: 1 inodi(1),nnodi)
940: 30 continue
941: go to 100
942: 40 call newnod(nodplc(loc+2),nodplc(loce+2),inodx(1),inodi(1),nnodi)
943: call newnod(nodplc(loc+3),nodplc(loce+3),inodx(1),inodi(1),nnodi)
944: if (id.ge.7) go to 100
945: nlocp=loc+id+1
946: nssnod=2*nodplc(loc+4)
947: call getm4(nodplc(loce+id+1),nssnod)
948: nlocpe=loce+id+1
949: 50 do 60 j=1,nssnod
950: locp=nodplc(nlocp)
951: nodold=nodplc(locp+j)
952: call newnod(nodold,nodnew,inodx(1),inodi(1),nnodi)
953: locpe=nodplc(nlocpe)
954: nodplc(locpe+j)=nodnew
955: 60 continue
956: go to 100
957: 70 nlocp=loc+2
958: call sizmem(nodplc(loc+2),nssnod)
959: call getm4(nodplc(loce+2),nssnod)
960: nlocpe=loce+2
961: go to 50
962: c
963: c copy real part
964: c
965: 100 if (nogo.ne.0) go to 300
966: locv=nodplc(loc+1)
967: locve=nodplc(loce+1)
968: call copy8(value(locv),value(locve),lval(id))
969: c
970: c treat non-node tables specially
971: c
972: 200 if (id.ge.11) go to 300
973: go to (300,210,220,300,230,240,230,240,260,260), id
974: 210 call cpytb8(loc+7,loce+7)
975: go to 300
976: 220 call cpytb8(loc+10,loce+10)
977: go to 300
978: 230 itab=5
979: go to 250
980: 240 itab=6
981: 250 if (id.le.6) go to 255
982: call cpytb4(loc+itab+1,loce+itab+1)
983: 255 call cpytb4(loc+itab+2,loce+itab+2)
984: call cpytb8(loc+itab+3,loce+itab+3)
985: call cpytb8(loc+itab+4,loce+itab+4)
986: call cpytb4(loc+itab+5,loce+itab+5)
987: call cpytb8(loc+itab+6,loce+itab+6)
988: go to 300
989: 260 call cpytb8(loc+5,loce+5)
990: c
991: c
992: 300 return
993: end
994: subroutine cpytb4(itabo,itabn)
995: implicit double precision (a-h,o-z)
996: c
997: c this routine copies a table. its use is made necessary by the
998: c fact that only one pointer is allowed per table.
999: c
1000: common /blank/ value(1000)
1001: integer nodplc(64)
1002: complex*16 cvalue(32)
1003: equivalence (value(1),nodplc(1),cvalue(1))
1004: c
1005: c
1006: call sizmem(nodplc(itabo),isize)
1007: call getm4(nodplc(itabn),isize)
1008: loco=nodplc(itabo)
1009: locn=nodplc(itabn)
1010: call copy4(nodplc(loco+1),nodplc(locn+1),isize)
1011: return
1012: end
1013: subroutine cpytb8(itabo,itabn)
1014: implicit double precision (a-h,o-z)
1015: c
1016: c this routine copies a table. its use is made necessary by the
1017: c fact that only one pointer is allowed per table.
1018: c
1019: common /blank/ value(1000)
1020: integer nodplc(64)
1021: complex*16 cvalue(32)
1022: equivalence (value(1),nodplc(1),cvalue(1))
1023: c
1024: c
1025: call sizmem(nodplc(itabo),isize)
1026: call getm8(nodplc(itabn),isize)
1027: loco=nodplc(itabo)
1028: locn=nodplc(itabn)
1029: call copy8(value(loco+1),value(locn+1),isize)
1030: return
1031: end
1032: subroutine lnkref
1033: implicit double precision (a-h,o-z)
1034: c
1035: c this routine resolves all unsatisfied name references.
1036: c
1037: common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem,
1038: 1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize,
1039: 2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr,
1040: 3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1,
1041: 4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd,
1042: 5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval
1043: common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop,
1044: 1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs
1045: common /flags/ iprnta,iprntl,iprntm,iprntn,iprnto,limtim,limpts,
1046: 1 lvlcod,lvltim,itl1,itl2,itl3,itl4,itl5,igoof,nogo,keof
1047: common /blank/ value(1000)
1048: integer nodplc(64)
1049: complex*16 cvalue(32)
1050: equivalence (value(1),nodplc(1),cvalue(1))
1051: c
1052: c mutual inductors
1053: c
1054: loc=locate(4)
1055: 100 if (loc.eq.0) go to 200
1056: iref=nodplc(loc+2)
1057: call fndnam(value(iunsat+iref),loc-1,loc+2,3)
1058: iref=nodplc(loc+3)
1059: call fndnam(value(iunsat+iref),loc-1,loc+3,3)
1060: loc=nodplc(loc)
1061: go to 100
1062: c
1063: c current-controlled current source
1064: c
1065: 200 loc=locate(7)
1066: 210 if (loc.eq.0) go to 300
1067: nump=nodplc(loc+4)
1068: locp=nodplc(loc+6)
1069: do 220 i=1,nump
1070: iref=nodplc(locp+i)
1071: call fndnam(value(iunsat+iref),loc-1,locp+i,9)
1072: 220 continue
1073: loc=nodplc(loc)
1074: go to 210
1075: c
1076: c current-controlled voltage sources
1077: c
1078: 300 loc=locate(8)
1079: 310 if (loc.eq.0) go to 400
1080: nump=nodplc(loc+4)
1081: locp=nodplc(loc+7)
1082: do 320 i=1,nump
1083: iref=nodplc(locp+i)
1084: call fndnam(value(iunsat+iref),loc-1,locp+i,9)
1085: 320 continue
1086: loc=nodplc(loc)
1087: go to 310
1088: c
1089: c diodes
1090: c
1091: 400 loc=locate(11)
1092: 410 if (loc.eq.0) go to 500
1093: iref=nodplc(loc+5)
1094: call fndnam(value(iunsat+iref),loc-1,loc+5,21)
1095: loc=nodplc(loc)
1096: go to 410
1097: c
1098: c bjts
1099: c
1100: 500 loc=locate(12)
1101: 510 if (loc.eq.0) go to 600
1102: iref=nodplc(loc+8)
1103: call fndnam(value(iunsat+iref),loc-1,loc+8,22)
1104: loc=nodplc(loc)
1105: go to 510
1106: c
1107: c jfets
1108: c
1109: 600 loc=locate(13)
1110: 610 if (loc.eq.0) go to 700
1111: iref=nodplc(loc+7)
1112: call fndnam(value(iunsat+iref),loc-1,loc+7,23)
1113: loc=nodplc(loc)
1114: go to 610
1115: c
1116: c mosfets
1117: c
1118: 700 loc=locate(14)
1119: 710 if (loc.eq.0) go to 1000
1120: iref=nodplc(loc+8)
1121: call fndnam(value(iunsat+iref),loc-1,loc+8,24)
1122: loc=nodplc(loc)
1123: go to 710
1124: c
1125: c finished
1126: c
1127: 1000 call clrmem(iunsat)
1128: return
1129: end
1130: subroutine subnam(loce)
1131: implicit double precision (a-h,o-z)
1132: c
1133: c this routine constructs the names of elements added as a result of
1134: c subcircuit expansion. the full element names are of the form
1135: c name.xn. --- xd.xc.xb.xa
1136: c where 'name' is the nominal element name, and the 'x'*s denote the
1137: c sequence of subcircuit calls (from top or circuit level down through
1138: c nested subcircuit calls) which caused the particular element to be
1139: c added. at present, spice restricts all element names to be 8 charac-
1140: c ters or less. therefore, the name used consists of the leftmost 8
1141: c characters of the full element name, with the rightmost character
1142: c replaced by an asterisk ('*') if the full element name is longer than
1143: c 8 characters.
1144: c
1145: common /blank/ value(1000)
1146: integer nodplc(64)
1147: complex*16 cvalue(32)
1148: equivalence (value(1),nodplc(1),cvalue(1))
1149: c
1150: c
1151: data ablank, aper, astk / 1h , 1h., 1h* /
1152: c
1153: c construct subcircuit element name
1154: c
1155: if (nodplc(loce-1).eq.0) go to 100
1156: locve=nodplc(loce+1)
1157: loc=loce
1158: nchar=0
1159: sname=ablank
1160: achar=ablank
1161: 10 locv=nodplc(loc+1)
1162: elname=value(locv)
1163: do 20 ichar=1,8
1164: call move(achar,1,elname,ichar,1)
1165: if (achar.eq.ablank) go to 30
1166: if (nchar.eq.8) go to 40
1167: nchar=nchar+1
1168: call move(sname,nchar,achar,1,1)
1169: 20 continue
1170: 30 loc=nodplc(loc-1)
1171: if (loc.eq.0) go to 60
1172: if (nchar.eq.8) go to 40
1173: nchar=nchar+1
1174: call move(sname,nchar,aper,1,1)
1175: go to 10
1176: c
1177: c name is longer than 8 characters: flag with asterisk
1178: c
1179: 40 call move(sname,8,astk,1,1)
1180: 60 value(locve)=sname
1181: c
1182: c finished
1183: c
1184: 100 return
1185: end
1186: subroutine elprnt
1187: implicit double precision (a-h,o-z)
1188: c
1189: c this routine prints a circuit element summary.
1190: c
1191: common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem,
1192: 1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize,
1193: 2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr,
1194: 3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1,
1195: 4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd,
1196: 5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval
1197: common /miscel/ atime,aprog(3),adate,atitle(10),defl,defw,defad,
1198: 1 defas,rstats(50),iwidth,lwidth,nopage
1199: common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop,
1200: 1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs
1201: common /flags/ iprnta,iprntl,iprntm,iprntn,iprnto,limtim,limpts,
1202: 1 lvlcod,lvltim,itl1,itl2,itl3,itl4,itl5,igoof,nogo,keof
1203: common /tran/ tstep,tstop,tstart,delmax,tdmax,forfre,jtrflg
1204: common /blank/ value(1000)
1205: integer nodplc(64)
1206: complex*16 cvalue(32)
1207: equivalence (value(1),nodplc(1),cvalue(1))
1208: c
1209: c
1210: dimension itab(25),astyp(6)
1211: dimension eltitl(4)
1212: data eltitl / 8hcircuit , 8helement , 8hsummary , 8h /
1213: data astyp / 1h , 5hpulse, 3hsin, 3hexp, 3hpwl, 4hsffm /
1214: data ablnk,aoff /1h ,3hoff/
1215: c
1216: c print listing of elements
1217: c
1218: call title(0,lwidth,1,eltitl)
1219: c
1220: c print resistors
1221: c
1222: if (jelcnt(1).eq.0) go to 50
1223: ititle=0
1224: 21 format(//'0**** resistors'/'0 name nodes value
1225: 1 tc1 tc2'//)
1226: loc=locate(1)
1227: 30 if (loc.eq.0) go to 50
1228: if (ititle.eq.0) write (6,21)
1229: ititle=1
1230: locv=nodplc(loc+1)
1231: node1=nodplc(loc+2)
1232: node2=nodplc(loc+3)
1233: write (6,31) value(locv),nodplc(junode+node1),
1234: 1 nodplc(junode+node2),value(locv+2),value(locv+3),value(locv+4)
1235: 31 format(6x,a8,2i5,1p3d11.2)
1236: 40 loc=nodplc(loc)
1237: go to 30
1238: c
1239: c print capacitors and inductors
1240: c
1241: 50 if ((jelcnt(2)+jelcnt(3)).eq.0) go to 80
1242: ititle=0
1243: 51 format(//'0**** capacitors and inductors'/'0 name nodes
1244: 1 in cond value'//)
1245: do 70 id=2,3
1246: loc=locate(id)
1247: 60 if (loc.eq.0) go to 70
1248: if (ititle.eq.0) write (6,51)
1249: ititle=1
1250: locv=nodplc(loc+1)
1251: node1=nodplc(loc+2)
1252: node2=nodplc(loc+3)
1253: ltab=7
1254: if (id.eq.3) ltab=10
1255: call sizmem(nodplc(loc+ltab),nparam)
1256: if (nparam.ge.2) go to 62
1257: ispot=nodplc(loc+ltab)+1
1258: write (6,31) value(locv),nodplc(junode+node1),
1259: 1 nodplc(junode+node2),value(locv+2),value(ispot)
1260: go to 65
1261: 62 write (6,63) value(locv),nodplc(junode+node1),
1262: 1 nodplc(junode+node2),value(locv+2)
1263: 63 format(6x,a8,2i5,1pd11.2,' variable')
1264: 65 loc=nodplc(loc)
1265: go to 60
1266: 70 continue
1267: c
1268: c print mutual inductors
1269: c
1270: 80 if (jelcnt(4).eq.0) go to 100
1271: ititle=0
1272: 81 format(//'0**** mutual inductors'/'0 name coupled induc
1273: 1tors value'//)
1274: loc=locate(4)
1275: 90 if (loc.eq.0) go to 110
1276: if (ititle.eq.0) write (6,81)
1277: ititle=1
1278: locv=nodplc(loc+1)
1279: nl1=nodplc(loc+2)
1280: nl1=nodplc(nl1+1)
1281: nl2=nodplc(loc+3)
1282: nl2=nodplc(nl2+1)
1283: write (6,91) value(locv),value(nl1),value(nl2),value(locv+1)
1284: 91 format(6x,a8,4x,a8,2x,a8,1pd10.2)
1285: 95 loc=nodplc(loc)
1286: go to 90
1287: c
1288: c print nonlinear voltage controlled sources
1289: c
1290: 100 if (jelcnt(5).eq.0) go to 120
1291: ititle=0
1292: 101 format(//'0**** voltage-controlled current sources'/'0 name
1293: 1 + - dimension function')
1294: loc=locate(5)
1295: 110 if (loc.eq.0) go to 120
1296: if (ititle.eq.0) write (6,101)
1297: ititle=1
1298: locv=nodplc(loc+1)
1299: node1=nodplc(loc+2)
1300: node2=nodplc(loc+3)
1301: write (6,111) value(locv),nodplc(junode+node1),
1302: 1 nodplc(junode+node2),nodplc(loc+4)
1303: 111 format(6x,a8,2i5,i8,9x,'poly')
1304: 115 loc=nodplc(loc)
1305: go to 110
1306: c
1307: c nonlinear voltage controlled voltage sources
1308: c
1309: 120 if (jelcnt(6).eq.0) go to 140
1310: ititle=0
1311: 121 format(//'0**** voltage-controlled voltage sources'/'0 name
1312: 1 + - dimension function')
1313: loc=locate(6)
1314: 130 if (loc.eq.0) go to 140
1315: if (ititle.eq.0) write (6,121)
1316: ititle=1
1317: locv=nodplc(loc+1)
1318: node1=nodplc(loc+2)
1319: node2=nodplc(loc+3)
1320: write (6,111) value(locv),nodplc(junode+node1),
1321: 1 nodplc(junode+node2),nodplc(loc+4)
1322: 135 loc=nodplc(loc)
1323: go to 130
1324: c
1325: c nonlinear current controlled current sources
1326: c
1327: 140 if (jelcnt(7).eq.0) go to 160
1328: ititle=0
1329: 141 format(//'0**** current-controlled current sources'/'0 name
1330: 1 + - dimension function')
1331: loc=locate(7)
1332: 150 if (loc.eq.0) go to 160
1333: if (ititle.eq.0) write (6,141)
1334: ititle=1
1335: locv=nodplc(loc+1)
1336: node1=nodplc(loc+2)
1337: node2=nodplc(loc+3)
1338: write (6,111) value(locv),nodplc(junode+node1),
1339: 1 nodplc(junode+node2),nodplc(loc+4)
1340: 155 loc=nodplc(loc)
1341: go to 150
1342: c
1343: c nonlinear current controlled voltage sources
1344: c
1345: 160 if (jelcnt(8).eq.0) go to 170
1346: ititle=0
1347: 161 format(//'0**** current-controlled voltage sources'/'0 name
1348: 1 + - dimension function')
1349: loc=locate(8)
1350: 165 if (loc.eq.0) go to 170
1351: if (ititle.eq.0) write (6,161)
1352: ititle=1
1353: locv=nodplc(loc+1)
1354: node1=nodplc(loc+2)
1355: node2=nodplc(loc+3)
1356: write (6,111) value(locv),nodplc(junode+node1),
1357: 1 nodplc(junode+node2),nodplc(loc+4)
1358: 167 loc=nodplc(loc)
1359: go to 165
1360: c
1361: c print independent sources
1362: c
1363: 170 if ((jelcnt(9)+jelcnt(10)).eq.0) go to 250
1364: ititle=0
1365: 171 format(//'0**** independent sources'/'0 name nodes dc
1366: 1 value ac value ac phase transient'//)
1367: do 245 id=9,10
1368: loc=locate(id)
1369: 180 if (loc.eq.0) go to 245
1370: if (ititle.eq.0) write (6,171)
1371: ititle=1
1372: locv=nodplc(loc+1)
1373: locp=nodplc(loc+5)
1374: node1=nodplc(loc+2)
1375: node2=nodplc(loc+3)
1376: itype=nodplc(loc+4)+1
1377: anam=astyp(itype)
1378: write (6,181) value(locv),nodplc(junode+node1),
1379: 1 nodplc(junode+node2),value(locv+1),value(locv+2),
1380: 2 value(locv+3),anam
1381: 181 format(6x,a8,2i5,1p3d11.2,2x,a8)
1382: if (jtrflg.eq.0) go to 240
1383: jstart=locp+1
1384: go to (240,190,200,210,220,230), itype
1385: 190 jstop=locp+7
1386: write (6,191) (value(j),j=jstart,jstop)
1387: 191 format(1h0,42x,'initial value',1pd11.2,/,
1388: 1 43x,'pulsed value.', d11.2,/,
1389: 2 43x,'delay time...', d11.2,/,
1390: 3 43x,'risetime.....', d11.2,/,
1391: 4 43x,'falltime.....', d11.2,/,
1392: 5 43x,'width........', d11.2,/,
1393: 6 43x,'period.......', d11.2,/)
1394: go to 240
1395: 200 jstop=locp+5
1396: write (6,201) (value(j),j=jstart,jstop)
1397: 201 format(1h0,42x,'offset.......',1pd11.2,/,
1398: 1 43x,'amplitude....', d11.2,/,
1399: 2 43x,'frequency....', d11.2,/,
1400: 3 43x,'delay........', d11.2,/,
1401: 4 43x,'theta........', d11.2,/)
1402: go to 240
1403: 210 jstop=locp+6
1404: write (6,211) (value(j),j=jstart,jstop)
1405: 211 format(1h0,42x,'initial value',1pd11.2,/,
1406: 1 43x,'pulsed value.', d11.2,/,
1407: 2 43x,'rise delay...', d11.2,/,
1408: 3 43x,'rise tau.....', d11.2,/,
1409: 4 43x,'fall delay...', d11.2,/,
1410: 5 43x,'fall tau.....', d11.2,/)
1411: go to 240
1412: 220 call sizmem(nodplc(loc+5),jstop)
1413: jstop=locp+jstop
1414: write (6,221) (value(j),j=jstart,jstop)
1415: 221 format(1h0,49x,'time value'//,(46x,1p2d11.2))
1416: write (6,226)
1417: 226 format(1x)
1418: go to 240
1419: 230 jstop=locp+5
1420: write (6,231) (value(j),j=jstart,jstop)
1421: 231 format(1h0,42x,'offset.......',1pd11.2,/,
1422: 1 43x,'amplitude....', d11.2,/,
1423: 2 43x,'carrier freq.', d11.2,/,
1424: 3 43x,'modn index...', d11.2,/,
1425: 4 43x,'signal freq..', d11.2,/)
1426: 240 loc=nodplc(loc)
1427: go to 180
1428: 245 continue
1429: c
1430: c print transmission lines
1431: c
1432: 250 if (jelcnt(17).eq.0) go to 260
1433: ititle=0
1434: 251 format(//'0**** transmission lines'/'0 name nodes
1435: 1 z0 td'//)
1436: loc=locate(17)
1437: 253 if (loc.eq.0) go to 260
1438: if (ititle.eq.0) write (6,251)
1439: ititle=1
1440: locv=nodplc(loc+1)
1441: node1=nodplc(loc+2)
1442: node2=nodplc(loc+3)
1443: node3=nodplc(loc+4)
1444: node4=nodplc(loc+5)
1445: write (6,256) value(locv),nodplc(junode+node1),
1446: 1 nodplc(junode+node2),nodplc(junode+node3),
1447: 2 nodplc(junode+node4),value(locv+1),value(locv+2)
1448: 256 format(6x,a8,4i5,1p2d11.2)
1449: 258 loc=nodplc(loc)
1450: go to 253
1451: c
1452: c print diodes
1453: c
1454: 260 if (jelcnt(11).eq.0) go to 290
1455: ititle=0
1456: 261 format(//'0**** diodes'/'0 name + - model are
1457: 1a'//)
1458: loc=locate(11)
1459: 270 if (loc.eq.0) go to 290
1460: if (ititle.eq.0) write (6,261)
1461: ititle=1
1462: locv=nodplc(loc+1)
1463: node1=nodplc(loc+2)
1464: node2=nodplc(loc+3)
1465: locm=nodplc(loc+5)
1466: locm=nodplc(locm+1)
1467: aic=ablnk
1468: if (nodplc(loc+6).eq.1) aic=aoff
1469: write (6,271) value(locv),nodplc(junode+node1),
1470: 1 nodplc(junode+node2),value(locm),value(locv+1),aic
1471: 271 format(6x,a8,2i5,2x,a8,f8.3,2x,a8)
1472: 280 loc=nodplc(loc)
1473: go to 270
1474: c
1475: c print transistors
1476: c
1477: 290 if (jelcnt(12).eq.0) go to 320
1478: ititle=0
1479: 291 format(//'0**** bipolar junction transistors'/'0 name c
1480: 1 b e s model area'//)
1481: loc=locate(12)
1482: 300 if (loc.eq.0) go to 320
1483: if (ititle.eq.0) write (6,291)
1484: ititle=1
1485: locv=nodplc(loc+1)
1486: node1=nodplc(loc+2)
1487: node2=nodplc(loc+3)
1488: node3=nodplc(loc+4)
1489: node4=nodplc(loc+5)
1490: locm=nodplc(loc+8)
1491: locm=nodplc(locm+1)
1492: aic=ablnk
1493: if (nodplc(loc+9).eq.1) aic=aoff
1494: write (6,301) value(locv),nodplc(junode+node1),
1495: 1 nodplc(junode+node2),nodplc(junode+node3),nodplc(junode+node4),
1496: 2 value(locm),value(locv+1),aic
1497: 301 format(6x,a8,4i5,2x,a8,f8.3,2x,a8)
1498: 310 loc=nodplc(loc)
1499: go to 300
1500: c
1501: c print jfets
1502: c
1503: 320 if (jelcnt(13).eq.0) go to 350
1504: ititle=0
1505: 321 format(//'0**** jfets'/'0 name d g s model
1506: 1 area'//)
1507: loc=locate(13)
1508: 330 if (loc.eq.0) go to 350
1509: if (ititle.eq.0) write (6,321)
1510: ititle=1
1511: locv=nodplc(loc+1)
1512: node1=nodplc(loc+2)
1513: node2=nodplc(loc+3)
1514: node3=nodplc(loc+4)
1515: locm=nodplc(loc+7)
1516: locm=nodplc(locm+1)
1517: aic=ablnk
1518: if (nodplc(loc+8).eq.1) aic=aoff
1519: write (6,331) value(locv),nodplc(junode+node1),
1520: 1 nodplc(junode+node2),nodplc(junode+node3),
1521: 2 value(locm),value(locv+1),aic
1522: 331 format(6x,a8,3i5,2x,a8,f8.3,2x,a8)
1523: 340 loc=nodplc(loc)
1524: go to 330
1525: c
1526: c print mosfets
1527: c
1528: 350 if (jelcnt(14).eq.0) go to 400
1529: ititle=0
1530: 351 format(//'0**** mosfets',/,'0name d g s b model l
1531: 1 w ad as rd rs',//)
1532: loc=locate(14)
1533: 360 if (loc.eq.0) go to 400
1534: if (ititle.eq.0) write (6,351)
1535: ititle=1
1536: locv=nodplc(loc+1)
1537: node1=nodplc(loc+2)
1538: node2=nodplc(loc+3)
1539: node3=nodplc(loc+4)
1540: node4=nodplc(loc+5)
1541: locm=nodplc(loc+8)
1542: locm=nodplc(locm+1)
1543: rd=value(locv+11)
1544: if(rd.eq.0.0d0) rd=value(locm+6)
1545: rs=value(locv+12)
1546: if(rs.eq.0.0d0) rs=value(locm+7)
1547: aic=ablnk
1548: if (nodplc(loc+9).eq.1) aic=aoff
1549: write (6,361) value(locv),nodplc(junode+node1),
1550: 1 nodplc(junode+node2),nodplc(junode+node3),
1551: 2 nodplc(junode+node4),value(locm),value(locv+1),value(locv+2),
1552: 3 value(locv+3),value(locv+4),rd,rs
1553: 361 format(1x,a8,4i4,1x,a8,1pd7.1,5d8.1)
1554: if(aic.ne.ablnk) write(6,362)
1555: 362 format(1x,'above device specified to be *off* to aid dc solution',
1556: 1 /)
1557: 370 loc=nodplc(loc)
1558: go to 360
1559: c
1560: c subcircuit calls
1561: c
1562: 400 if (jelcnt(19).eq.0) go to 500
1563: ititle=0
1564: 401 format(//'0**** subcircuit calls'/'0 name subcircuit ext
1565: 1ernal nodes'//)
1566: loc=locate(19)
1567: 410 if (loc.eq.0) go to 500
1568: if (ititle.eq.0) write (6,401)
1569: ititle=1
1570: locv=nodplc(loc+1)
1571: locn=nodplc(loc+2)
1572: call sizmem(nodplc(loc+2),nnodx)
1573: locs=nodplc(loc+3)
1574: locsv=nodplc(locs+1)
1575: jstart=1
1576: ndprln=(lwidth-28)/5
1577: 412 jstop=min0(nnodx,jstart+ndprln-1)
1578: do 414 j=jstart,jstop
1579: node=nodplc(locn+j)
1580: itab(j-jstart+1)=nodplc(junode+node)
1581: 414 continue
1582: if (jstart.eq.1)
1583: 1 write (6,416) value(locv),value(locsv),(itab(j),j=1,jstop)
1584: 416 format(6x,a8,2x,a8,4x,20i5)
1585: if (jstart.ne.1)
1586: 1 write (6,418) (itab(j-jstart+1),j=jstart,jstop)
1587: 418 format(28x,20i5)
1588: jstart=jstop+1
1589: if (jstart.le.nnodx) go to 412
1590: if (nnodx.le.ndprln) go to 420
1591: write (6,226)
1592: 420 loc=nodplc(loc)
1593: go to 410
1594: c
1595: c finished
1596: c
1597: 500 return
1598: end
1599: subroutine modchk
1600: implicit double precision (a-h,o-z)
1601: c
1602: c this routine performs one-time processing of device model para-
1603: c meters and prints out a device model summary. it also reserves the
1604: c additional nodes required by nonzero device extrinsic resistances.
1605: c
1606: common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem,
1607: 1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize,
1608: 2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr,
1609: 3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1,
1610: 4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd,
1611: 5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval
1612: common /miscel/ atime,aprog(3),adate,atitle(10),defl,defw,defad,
1613: 1 defas,rstats(50),iwidth,lwidth,nopage
1614: common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop,
1615: 1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs
1616: common /status/ omega,time,delta,delold(7),ag(7),vt,xni,egfet,
1617: 1 xmu,mode,modedc,icalc,initf,method,iord,maxord,noncon,iterno,
1618: 2 itemno,nosolv,ipostp,iscrch
1619: common /flags/ iprnta,iprntl,iprntm,iprntn,iprnto,limtim,limpts,
1620: 1 lvlcod,lvltim,itl1,itl2,itl3,itl4,itl5,igoof,nogo,keof
1621: common /knstnt/ twopi,xlog2,xlog10,root2,rad,boltz,charge,ctok,
1622: 1 gmin,reltol,abstol,vntol,trtol,chgtol,eps0,epssil,epsox
1623: common /blank/ value(1000)
1624: integer nodplc(64)
1625: complex*16 cvalue(32)
1626: equivalence (value(1),nodplc(1),cvalue(1))
1627: c
1628: c
1629: dimension itab(50),atable(10)
1630: dimension ifun(4)
1631: dimension antype(4),aptype(4)
1632: dimension ipar(6),ampar(120),defval(120),ifmt(120)
1633: dimension titled(4),titleb(4),titlej(4),titlem(4)
1634: data titled / 8hdiode mo, 8hdel para, 8hmeters , 8h /
1635: data titleb / 8hbjt mode, 8hl parame, 8hters , 8h /
1636: data titlej / 8hjfet mod, 8hel param, 8heters , 8h /
1637: data titlem / 8hmosfet m, 8hodel par, 8hameters , 8h /
1638: data ifun / 0, 0, 1, 1 /
1639: data antype /1h ,3hnpn,3hnjf,4hnmos/
1640: data aptype /1h ,3hpnp,3hpjf,4hpmos/
1641: data agaas /5hga-as/
1642: data ipar / 0, 14, 60, 72, 106, 119 /
1643: data hndrd,hndrd2 /1.0d+02,1.0d+04/
1644: data ampar /
1645: 1 6his ,6hrs ,6hn ,6htt ,6hcjo ,6hpb ,6hm ,
1646: 2 6heg ,6hpt ,6hkf ,6haf ,6hfc ,6hbv ,6hibv ,
1647: 1 6hjs ,6hbf ,6hnf ,6hvbf ,6hjbf ,6hjle ,6hnle ,
1648: 2 6hbr ,6hnr ,6hvbr ,6hjbr ,6hjlc ,6hnlc ,6h0 ,
1649: 3 6h0 ,6hrb ,6hjrb ,6hrbm ,6hre ,6hrc ,6hcje ,
1650: 4 6hvje ,6hmje ,6htf ,6hxtf ,6hvtf ,6hjtf ,6hptf ,
1651: 5 6hcjc ,6hvjc ,6hmjc ,6hcdis ,6htr ,6h0 ,6h0 ,
1652: 6 6h0 ,6h0 ,6hcjs ,6hvjs ,6hmjs ,6htb ,6heg ,
1653: 7 6hpt ,6hkf ,6haf ,6hfc ,
1654: 1 6hvto ,6hbeta ,6hlambda,6hrd ,6hrs ,6hcgs ,6hcgd ,
1655: 2 6hpb ,6his ,6hkf ,6haf ,6hfc ,
1656: 1 6hvto ,6hkp ,6hgamma ,6hphi ,6hlambda,6hrd ,6hrs ,
1657: 2 6hcgs ,6hcgd ,6hcgb ,6hcbd ,6hcbs ,6htox ,6hpb ,
1658: 3 6hjs ,6hnsub ,6hnss ,6hnfs ,6hxj ,6hld ,6hngate ,
1659: 4 6htps ,6huo ,6hucrit ,6huexp ,6hutra ,6hkf ,6haf ,
1660: 5 6hfc ,6hwd ,6hecrit ,6hetra ,6hvnorm ,6hdesat ,
1661: 1 6hvp ,6hvbr ,6hvbi ,6hvfwd ,6hnd ,6hkdso ,6hkdv ,
1662: 2 6hcdso ,6hczg ,6hgnoise,6hnexp ,6hkf ,6haf ,0.0d0 /
1663: data defval /
1664: 1 1.0d-14, 0.0d0, 1.0d0, 2*0.0d0, 1.0d0, 0.5d0, 1.11d0,
1665: 2 3.0d0, 0.0d0, 1.0d0, 0.5d0, 0.0d0, 1.0d-3,
1666: 1 1.0d-16, 100.0d0, 1.0d0, 3*0.0d0, 1.5d0, 2*1.0d0, 3*0.0d0,
1667: 2 2.0d0, 0.0d0, 1.0d0, 0.0d0, 0.0d0, 4*0.0d0, 0.75d0,
1668: 3 0.33d0, 2*0.0d0, 2*0.0d0, 2*0.0d0, 0.75d0, 0.33d0, 1.0d0,
1669: 4 2*0.0d0, 2*0.0d0, 2*0.0d0, 0.75d0, 0.0d0, 0.0d0, 1.11d0,
1670: 5 3.0d0, 0.0d0, 1.0d0, 0.5d0,
1671: 1 -2.0d0, 1.0d-4, 5*0.0d0, 1.0d0,1.0d-14, 0.0d0, 1.0d0,
1672: 2 0.5d0,
1673: 1 3*0.0d0, 0.0d0, 8*0.0d0, 1.0d-7, 0.8d0, 1.0d-4,6*0.0d0,
1674: 2 1.0d0,700.0d0, 1.0d+4, 3*0.0d0, 1.0d0, 0.5d0, 0.0d0,
1675: 3 3*0.0d0,1.5d+9,
1676: 1 -2.1d0, 0.0d0, 0.8d0, 0.6d0, 1.0d17, 5.8d0 ,0.01d0,
1677: 2 2.0d-10, 0.0d0, 0.0d0, 1.0d0, 0.0d0, 1.0d0, 0.0d0 /
1678: data ifmt /
1679: 1 2,1,1,2,2,1,1,1,1,2,1,1,2,2,
1680: 1 2,1,1,2,2,2,1,1,1,2,2,2,1,0,0,1,2,1,1,1,2,1,1,2,2,2,2,1,2,1,
1681: a 1,1,2,0,0,0,0,2,1,1,2,1,1,2,2,2,
1682: 3 1,2,1,1,1,2,2,1,2,2,1,1,
1683: 4 1,2,1,1,2,1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,1,2,1,1,2,1,1,2,
1684: a 2,2,2,2,
1685: 5 1,1,1,1,2,2,2,2,2,2,1,2,1,0/
1686: c
1687: c
1688: tnom=value(itemps+1)+ctok
1689: xkt=boltz*tnom
1690: vt=xkt/charge
1691: egfet=1.16d0-(7.02d-04*tnom**2/(tnom+1108.0d0))
1692: arg=-egfet/2.0d0/boltz/tnom+1.1151d0/boltz/2.0d0/(27.0d0+ctok)
1693: xni=1.45d10*(tnom/(27.0d0+ctok))**1.5d0*dexp(charge*arg)
1694: nummod=jelcnt(21)+jelcnt(22)+jelcnt(23)+jelcnt(24)
1695: if (nummod.eq.0) go to 1000
1696: c
1697: c assign default values
1698: c
1699: kntlim=lwidth/11
1700: do 390 id=1,4
1701: if (jelcnt(id+20).eq.0) go to 390
1702: iflag=ifun(id)
1703: loc=locate(id+20)
1704: 10 if (loc.eq.0) go to 20
1705: locv=nodplc(loc+1)
1706: id1=id
1707: c... special case of gaas
1708: if(id.eq.4.and.nodplc(loc+2).eq.0) id1=5
1709: locm=ipar(id1)
1710: nopar=ipar(id1+1)-locm
1711: do 18 i=1,nopar
1712: itab(i)=ifmt(locm+i)
1713: if (value(locv+i).eq.0.0d0) go to 16
1714: if (iflag.eq.0) go to 14
1715: if (i.eq.1) go to 18
1716: if(i.eq.2.and.id1.eq.5) go to 18
1717: 14 if (value(locv+i).gt.0.0d0) go to 18
1718: c.. let pt be negative for bjts (for now anyway!)
1719: if(i.eq.43.and.id.eq.2) go to 18
1720: c... nss, ld, wd, utra and tps for mosfet can be negative
1721: if((i.eq.22.or.i.eq.17.or.i.eq.20.or.i.eq.30.or.i.eq.26)
1722: 1 .and.id.eq.4) go to 18
1723: c... vbr for ga-as fets must be negative
1724: 16 value(locv+i)=defval(locm+i)
1725: 18 continue
1726: loc=nodplc(loc)
1727: go to 10
1728: c
1729: c limit model values
1730: c
1731: 20 go to (30,40,50,60), id
1732: c... diodes
1733: 30 loc=locate(21)
1734: 32 if (loc.eq.0) go to 100
1735: locv=nodplc(loc+1)
1736: value(locv+7)=dmin1(value(locv+7),0.9d0)
1737: value(locv+8)=dmax1(value(locv+8),0.1d0)
1738: value(locv+11)=dmax1(value(locv+11),0.1d0)
1739: value(locv+12)=dmin1(value(locv+12),0.95d0)
1740: loc=nodplc(loc)
1741: go to 32
1742: c... bipolar transistors
1743: 40 loc=locate(22)
1744: 42 if (loc.eq.0) go to 100
1745: locv=nodplc(loc+1)
1746: value(locv+23)=dmin1(value(locv+23),0.9d0)
1747: if(value(locv+24).eq.0.0d0) value(locv+28)=0.0d0
1748: value(locv+31)=dmin1(value(locv+31),0.9d0)
1749: value(locv+32)=dmin1(value(locv+32),1.0d0)
1750: value(locv+40)=dmin1(value(locv+40),0.9d0)
1751: value(locv+42)=dmax1(value(locv+42),0.1d0)
1752: value(locv+45)=dmax1(value(locv+45),0.1d0)
1753: value(locv+46)=dmin1(value(locv+46),0.9999d0)
1754: loc=nodplc(loc)
1755: if(value(locv+18).eq.0.0d0) value(locv+18)=value(locv+16)
1756: if(value(locv+16).ge.value(locv+18)) go to 42
1757: write(6,44) value(locv)
1758: 44 format('0warning: minimum base resistance (rbm) is less than '
1759: 1 ,'total (rb) for model ',a8,/10x' rbm set equal to rb',/)
1760: value(locv+18)=value(locv+16)
1761: go to 42
1762: c... jfets
1763: 50 loc=locate(23)
1764: 52 if (loc.eq.0) go to 100
1765: locv=nodplc(loc+1)
1766: value(locv+11)=dmax1(value(locv+11),0.1d0)
1767: value(locv+12)=dmin1(value(locv+12),0.95d0)
1768: loc=nodplc(loc)
1769: go to 52
1770: c... mosfets
1771: 60 loc=locate(24)
1772: 64 if (loc.eq.0) go to 100
1773: locv=nodplc(loc+1)
1774: if(nodplc(loc+2).eq.0) go to 70
1775: c
1776: c special preprocessing for mosfet models
1777: c
1778: type=nodplc(loc+2)
1779: cox=epsox/value(locv+13)/hndrd
1780: c... if kp not given, calculate it from cox and uo
1781: if(value(locv+2).eq.0.0d0)
1782: 1 value(locv+2)=value(locv+23)*cox
1783: value(locv+35)=0.0d0
1784: c... nsub nonzero => calculate gamma, vto, phi unless specified
1785: if (value(locv+16).le.0.0d0) go to 68
1786: xnsub=value(locv+16)
1787: if (xnsub.le.xni) go to 66
1788: if (value(locv+4).le.0.0d0) value(locv+4)=2.0d0*vt*dlog(xnsub/xni)
1789: if (value(locv+3).le.0.0d0)
1790: 1 value(locv+3)=dsqrt(2.0d0*epssil*charge*xnsub)/cox
1791: fermis=type*0.5d0*value(locv+4)
1792: wkfng=3.2d0
1793: c... polysilicon gate ... calculate appropriate work function
1794: if (value(locv+21).le.0.0d0) go to 65
1795: fermig=type*value(locv+22)*vt*dlog(value(locv+21)/xni)
1796: wkfng=3.25d0+0.5d0*egfet-fermig
1797: 65 wkfngs=wkfng-(3.25d0+0.5d0*egfet+fermis)
1798: if(value(locv+1).eq.0.0d0)
1799: 1 value(locv+1)= wkfngs-value(locv+17)*charge/cox+
1800: 2 type*(value(locv+4)+value(locv+3)*dsqrt(value(locv+4)))
1801: value(locv+35)=dsqrt((epssil+epssil)/(charge*xnsub))
1802: go to 68
1803: 66 value(locv+16)=0.0d0
1804: write (6,67) value(locv)
1805: 67 format('0*error*: nsub < ni in mosfet model ',a8,/)
1806: nogo=1
1807: c... set phi to default if still zero
1808: 68 if(value(locv+4).eq.0.0d0) value(locv+4)=0.6d0
1809: value(locv+4)=dmax1(value(locv+4),0.1d0)
1810: value(locv+28)=dmax1(value(locv+28),0.1d0)
1811: value(locv+29)=dmin1(value(locv+29),0.95d0)
1812: loc=nodplc(loc)
1813: go to 64
1814: c... ga-as fets
1815: 70 value(locv+1)=-dabs(value(locv+1))
1816: if(value(locv+2).ne.0.0d0) value(locv+2)=-dabs(value(locv+2))
1817: value(locv+2)=dmax1(value(locv+2),-200.0d0)
1818: if(value(locv+9).eq.0.0d0)
1819: 1 value(locv+9)=2.49d-12*dsqrt(value(locv+5)/value(locv+3))
1820: loc=nodplc(loc)
1821: go to 64
1822: c
1823: c print model parameters
1824: c
1825: 100 if (iprntm.eq.0) go to 390
1826: locs=locate(id+20)
1827: 110 kntr=0
1828: loc=locs
1829: go to (120,130,140,150),id
1830: 120 call title(0,lwidth,1,titled)
1831: go to 200
1832: 130 call title(0,lwidth,1,titleb)
1833: go to 200
1834: 140 call title(0,lwidth,1,titlej)
1835: go to 200
1836: 150 call title(0,lwidth,1,titlem)
1837: 200 if (loc.eq.0) go to 210
1838: if (kntr.lt.kntlim) go to 220
1839: 210 locn=loc
1840: go to 240
1841: 220 kntr=kntr+1
1842: locv=nodplc(loc+1)
1843: atable(kntr)=value(locv)
1844: 230 loc=nodplc(loc)
1845: go to 200
1846: 240 write (6,241) (atable(k),k=1,kntr)
1847: 241 format(//11x,12(2x,a8))
1848: if (id.eq.1) go to 300
1849: kntr=0
1850: loc=locs
1851: 250 if (loc.eq.0) go to 260
1852: if (kntr.ge.kntlim) go to 260
1853: kntr=kntr+1
1854: atable(kntr)=antype(id)
1855: if (nodplc(loc+2).eq.-1) atable(kntr)=aptype(id)
1856: c... special type for ga-as (do not mix ga-as and mos!)
1857: if(id.eq.4.and.nodplc(loc+2).eq.0) atable(kntr)=agaas
1858: loc=nodplc(loc)
1859: go to 250
1860: 260 write (6,261) (atable(k),k=1,kntr)
1861: 261 format('0type',4x,12(4x,a6))
1862: 300 do 340 i=1,nopar
1863: if (itab(i).eq.0) go to 340
1864: kntr=0
1865: loc=locs
1866: 310 if (loc.eq.0) go to 320
1867: if (kntr.ge.kntlim) go to 320
1868: locv=nodplc(loc+1)
1869: kntr=kntr+1
1870: atable(kntr)=value(locv+i)
1871: loc=nodplc(loc)
1872: go to 310
1873: 320 if (itab(i).eq.2) go to 330
1874: write (6,321) ampar(locm+i),(atable(k),k=1,kntr)
1875: 321 format(1h ,a8,12f10.3)
1876: go to 340
1877: 330 write (6,331) ampar(locm+i),(atable(k),k=1,kntr)
1878: 331 format(1h ,a8,1p12d10.2)
1879: 340 continue
1880: if (locn.eq.0) go to 390
1881: locs=locn
1882: go to 110
1883: 390 continue
1884: c
1885: c process model parameters
1886: c
1887: c diodes
1888: c
1889: 400 loc=locate(21)
1890: 410 if (loc.eq.0) go to 420
1891: locv=nodplc(loc+1)
1892: if (value(locv+2).ne.0.0d0) value(locv+2)=1.0d0/value(locv+2)
1893: pb=value(locv+6)
1894: xm=value(locv+7)
1895: fc=value(locv+12)
1896: value(locv+12)=fc*pb
1897: xfc=dlog(1.0d0-fc)
1898: value(locv+15)=pb*(1.0d0-dexp((1.0d0-xm)*xfc))/(1.0d0-xm)
1899: value(locv+16)=dexp((1.0d0+xm)*xfc)
1900: value(locv+17)=1.0d0-fc*(1.0d0+xm)
1901: csat=value(locv+1)
1902: vte=value(locv+3)*vt
1903: value(locv+18)=vte*dlog(vte/(root2*csat))
1904: bv=value(locv+13)
1905: if(bv.eq.0.0d0) go to 418
1906: cbv=value(locv+14)
1907: if(cbv.ge.csat*bv/vt) go to 412
1908: cbv=csat*bv/vt
1909: write(6,411) value(locv),cbv
1910: 411 format('0warning: in diode model ',a8,' ibv increased to ',
1911: 1 1pd10.3,/10x,'to resolve incompatibility with specified is',/)
1912: xbv=bv
1913: go to 416
1914: 412 tol=reltol*cbv
1915: xbv=bv-vt*dlog(1.0d0+cbv/csat)
1916: iter=0
1917: 413 xbv=bv-vt*dlog(cbv/csat+1.0d0-xbv/vt)
1918: xcbv=csat*(dexp((bv-xbv)/vt)-1.0d0+xbv/vt)
1919: if (dabs(xcbv-cbv).le.tol) go to 416
1920: iter=iter+1
1921: if (iter.lt.25) go to 413
1922: write (6,415) xbv,xcbv
1923: 415 format('0warning: unable to match forward and reverse diode regio
1924: 1ns',/,11x,'bv = ',1pd10.3,' and ibv = ',d10.3,/)
1925: 416 value(locv+13)=xbv
1926: 418 loc=nodplc(loc)
1927: go to 410
1928: c
1929: c bipolar transistor models
1930: c
1931: 420 loc=locate(22)
1932: 430 if (loc.eq.0) go to 440
1933: locv=nodplc(loc+1)
1934: if(value(locv+4).ne.0.0d0) value(locv+4)=1.0d0/value(locv+4)
1935: if(value(locv+5).ne.0.0d0) value(locv+5)=1.0d0/value(locv+5)
1936: if(value(locv+10).ne.0.0d0) value(locv+10)=1.0d0/value(locv+10)
1937: if(value(locv+11).ne.0.0d0) value(locv+11)=1.0d0/value(locv+11)
1938: if(value(locv+19).ne.0.0d0) value(locv+19)=1.0d0/value(locv+19)
1939: if(value(locv+20).ne.0.0d0) value(locv+20)=1.0d0/value(locv+20)
1940: if(value(locv+26).ne.0.0d0) value(locv+26)=1.0d0/value(locv+26)
1941: 1 /1.44d0
1942: value(locv+28)=value(locv+28)/rad*value(locv+24)
1943: if(value(locv+35).ne.0.0d0) value(locv+35)=1.0d0/value(locv+35)
1944: 1 /1.44d0
1945: pe=value(locv+22)
1946: xme=value(locv+23)
1947: pc=value(locv+30)
1948: xmc=value(locv+31)
1949: fc=value(locv+46)
1950: value(locv+46)=fc*pe
1951: xfc=dlog(1.0d0-fc)
1952: value(locv+47)=pe*(1.0d0-dexp((1.0d0-xme)*xfc))/(1.0d0-xme)
1953: value(locv+48)=dexp((1.0d0+xme)*xfc)
1954: value(locv+49)=1.0d0-fc*(1.0d0+xme)
1955: value(locv+50)=fc*pc
1956: value(locv+51)=pc*(1.0d0-dexp((1.0d0-xmc)*xfc))/(1.0d0-xmc)
1957: value(locv+52)=dexp((1.0d0+xmc)*xfc)
1958: value(locv+53)=1.0d0-fc*(1.0d0+xmc)
1959: csat=value(locv+1)
1960: value(locv+54)=vt*dlog(vt/(root2*csat))
1961: loc=nodplc(loc)
1962: go to 430
1963: c
1964: c jfet models
1965: c
1966: 440 loc=locate(23)
1967: 450 if (loc.eq.0) go to 460
1968: locv=nodplc(loc+1)
1969: if (value(locv+4).ne.0.0d0) value(locv+4)=1.0d0/value(locv+4)
1970: if (value(locv+5).ne.0.0d0) value(locv+5)=1.0d0/value(locv+5)
1971: pb=value(locv+8)
1972: xm=0.5d0
1973: fc=value(locv+12)
1974: value(locv+12)=fc*pb
1975: xfc=dlog(1.0d0-fc)
1976: value(locv+13)=pb*(1.0d0-dexp((1.0d0-xm)*xfc))/(1.0d0-xm)
1977: value(locv+14)=dexp((1.0d0+xm)*xfc)
1978: value(locv+15)=1.0d0-fc*(1.0d0+xm)
1979: csat=value(locv+9)
1980: value(locv+16)=vt*dlog(vt/(root2*csat))
1981: loc=nodplc(loc)
1982: go to 450
1983: c
1984: c mosfet models
1985: c
1986: 460 loc=locate(24)
1987: 470 if (loc.eq.0) go to 600
1988: locv=nodplc(loc+1)
1989: if(nodplc(loc+2).eq.0) go to 490
1990: type=nodplc(loc+2)
1991: c... check validiy of lambda
1992: if(value(locv+5).lt.5.0d-6) go to 472
1993: write(6,471) value(locv)
1994: 471 format('0warning: value for lambda unrealisticly large for model'
1995: 1 ,1x,a8,/'0this parameter has been re-defined. see latest users '
1996: 2 ,'guide.')
1997: 472 value(locv+5)=value(locv+5)*hndrd
1998: value(locv+8)=value(locv+8)/hndrd
1999: value(locv+9)=value(locv+9)/hndrd
2000: value(locv+10)=value(locv+10)/hndrd
2001: value(locv+11)=value(locv+11)/hndrd2
2002: value(locv+12)=value(locv+12)/hndrd2
2003: value(locv+13)=value(locv+13)*hndrd
2004: value(locv+15)=value(locv+15)/hndrd2
2005: value(locv+19)=value(locv+19)*hndrd
2006: value(locv+20)=value(locv+20)*hndrd
2007: c.. move the params wd-gleff out to positions 36-40
2008: value(locv+36)=value(locv+30)*hndrd
2009: value(locv+37)=value(locv+31)
2010: value(locv+38)=value(locv+32)
2011: value(locv+39)=value(locv+33)
2012: value(locv+40)=value(locv+34)
2013: if(value(locv+39).ne.0.0d0) value(locv+39)=1.0d0/value(locv+39)
2014: if (value(locv+6).ne.0.0d0) value(locv+6)=1.0d0/value(locv+6)
2015: if (value(locv+7).ne.0.0d0) value(locv+7)=1.0d0/value(locv+7)
2016: if (value(locv+13).ne.0.0d0) value(locv+13)=epsox/value(locv+13)
2017: value(locv+34)=value(locv+1)-
2018: 1 type*value(locv+3)*dsqrt(value(locv+4))
2019: if (value(locv+13).ne.0.0d0)
2020: 1 value(locv+24)=value(locv+24)*epssil/value(locv+13)
2021: pb=value(locv+14)
2022: c... enter here from ga-as processing also
2023: 475 xm=0.5d0
2024: fc=value(locv+29)
2025: value(locv+29)=fc*pb
2026: xfc=dlog(1.0d0-fc)
2027: value(locv+30)=pb*(1.0d0-dexp((1.0d0-xm)*xfc))/(1.0d0-xm)
2028: value(locv+31)=dexp((1.0d0+xm)*xfc)
2029: value(locv+32)=1.0d0-fc*(1.0d0+xm)
2030: value(locv+33)=-1.0d0
2031: 480 loc=nodplc(loc)
2032: go to 470
2033: c... ga-as processing
2034: 490 value(locv+24)=2.5d+05*dexp(value(locv+2)/1.3d0)
2035: value(locv+25)=5.0d+06*dexp(-value(locv+4)/vt)
2036: value(locv+26)=3.9d-12*dsqrt(value(locv+5)*(value(locv+3)-
2037: 1 value(locv+1)))
2038: value(locv+28)=value(locv+26)*(1.0d0-dsqrt((value(locv+3)-
2039: 1 0.99999d0*value(locv+1))/(value(locv+3)-value(locv+1))))
2040: value(locv+29)=0.5d0
2041: pb=value(locv+3)
2042: go to 475
2043: c
2044: c reserve additional nodes
2045: c convert mosfet geometries to cm
2046: c
2047: c diodes
2048: c
2049: 600 loc=locate(11)
2050: 610 if (loc.eq.0) go to 700
2051: locm=nodplc(loc+5)
2052: locm=nodplc(locm+1)
2053: if (value(locm+2).eq.0.0d0) go to 620
2054: numnod=numnod+1
2055: nodplc(loc+4)=numnod
2056: go to 630
2057: 620 nodplc(loc+4)=nodplc(loc+2)
2058: 630 loc=nodplc(loc)
2059: go to 610
2060: c
2061: c transistors
2062: c
2063: 700 loc=locate(12)
2064: 710 if (loc.eq.0) go to 800
2065: c
2066: c put substrate node into nodplc(loc+30)
2067: c
2068: nodplc(loc+30)=nodplc(loc+5)
2069: locm=nodplc(loc+8)
2070: locm=nodplc(locm+1)
2071: if(value(locm+16).eq.0.0d0) go to 720
2072: numnod=numnod+1
2073: nodplc(loc+6)=numnod
2074: go to 730
2075: 720 nodplc(loc+6)=nodplc(loc+3)
2076: 730 if (value(locm+20).eq.0.0d0) go to 740
2077: numnod=numnod+1
2078: nodplc(loc+5)=numnod
2079: go to 750
2080: 740 nodplc(loc+5)=nodplc(loc+2)
2081: 750 if (value(locm+19).eq.0.0d0) go to 760
2082: numnod=numnod+1
2083: nodplc(loc+7)=numnod
2084: go to 770
2085: 760 nodplc(loc+7)=nodplc(loc+4)
2086: 770 loc=nodplc(loc)
2087: go to 710
2088: c
2089: c jfets
2090: c
2091: 800 loc=locate(13)
2092: 810 if (loc.eq.0) go to 900
2093: locm=nodplc(loc+7)
2094: locm=nodplc(locm+1)
2095: if (value(locm+4).eq.0.0d0) go to 820
2096: numnod=numnod+1
2097: nodplc(loc+5)=numnod
2098: go to 830
2099: 820 nodplc(loc+5)=nodplc(loc+2)
2100: 830 if (value(locm+5).eq.0.0d0) go to 840
2101: numnod=numnod+1
2102: nodplc(loc+6)=numnod
2103: go to 850
2104: 840 nodplc(loc+6)=nodplc(loc+4)
2105: 850 loc=nodplc(loc)
2106: go to 810
2107: c
2108: c mosfets
2109: c
2110: 900 loc=locate(14)
2111: 910 if (loc.eq.0) go to 1000
2112: locm=nodplc(loc+8)
2113: locv=nodplc(loc+1)
2114: if(nodplc(locm+2).eq.0) go to 960
2115: locm=nodplc(locm+1)
2116: value(locv+1)=value(locv+1)*hndrd
2117: value(locv+2)=value(locv+2)*hndrd
2118: value(locv+3)=value(locv+3)*hndrd2
2119: value(locv+4)=value(locv+4)*hndrd2
2120: c... check that effective channel length is greater than zero
2121: if((value(locv+1)-2.0d0*value(locm+20)).gt.0.0d0)
2122: 1 go to 914
2123: write(6,913) value(locv),value(locm)
2124: 913 format('0*error*: effective channel length of ',a8,' less than ',
2125: 1 'zero.',/' check value of ld for model ',a8)
2126: nogo=1
2127: 914 if((value(locv+2)-2.0d0*value(locm+36)).gt.0.0d0) go to 916
2128: write(6,915) value(locv),value(locm)
2129: 915 format('0*error*: effective channel width of ',a8,' less than ',
2130: 1 'zero.',/' check value of wd for model ',a8)
2131: nogo=1
2132: 916 if (value(locv+11).eq.0.0d0) go to 917
2133: value(locv+11)=1.0d0/value(locv+11)
2134: go to 918
2135: 917 if(value(locm+6).eq.0.0d0) go to 920
2136: value(locv+11)=value(locm+6)
2137: 918 numnod=numnod+1
2138: nodplc(loc+6)=numnod
2139: go to 930
2140: 920 nodplc(loc+6)=nodplc(loc+2)
2141: 930 if (value(locv+12).eq.0.0d0) go to 931
2142: value(locv+12)=1.0d0/value(locv+12)
2143: go to 932
2144: 931 if(value(locm+7).eq.0.0d0) go to 940
2145: value(locv+12)=value(locm+7)
2146: 932 numnod=numnod+1
2147: nodplc(loc+7)=numnod
2148: go to 950
2149: 940 nodplc(loc+7)=nodplc(loc+4)
2150: 950 loc=nodplc(loc)
2151: go to 910
2152: c.. special case for ga-as devices
2153: c.. compute rd and rs if not specified on device card
2154: c.. rd and rs are always non-zero.
2155: 960 locm=nodplc(locm+1)
2156: req=1.25d+14/(value(locm+5)*value(locv+2))
2157: if (value(locv+11).eq.0.0d0) value(locv+11)=req
2158: value(locv+11)=1.0d0/value(locv+11)
2159: numnod=numnod+1
2160: nodplc(loc+6)=numnod
2161: if (value(locv+12).eq.0.0d0) value(locv+12)=req
2162: value(locv+12)=1.0d0/value(locv+12)
2163: numnod=numnod+1
2164: nodplc(loc+7)=numnod
2165: loc=nodplc(loc)
2166: go to 910
2167: c
2168: c transmission lines
2169: c
2170: 1000 loc=locate(17)
2171: 1010 if (loc.eq.0) go to 2000
2172: numnod=numnod+1
2173: nodplc(loc+6)=numnod
2174: numnod=numnod+1
2175: nodplc(loc+7)=numnod
2176: loc=nodplc(loc)
2177: go to 1010
2178: c
2179: c finished
2180: c
2181: 2000 return
2182: end
2183: subroutine topchk
2184: implicit double precision (a-h,o-z)
2185: c
2186: c this routine constructs the element node table. it also checks
2187: c for voltage source/inductor loops, current source/capacitor cutsets,
2188: c and that every node has a dc (conductive) path to ground.
2189: c
2190: common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem,
2191: 1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize,
2192: 2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr,
2193: 3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1,
2194: 4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd,
2195: 5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval
2196: common /miscel/ atime,aprog(3),adate,atitle(10),defl,defw,defad,
2197: 1 defas,rstats(50),iwidth,lwidth,nopage
2198: common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop,
2199: 1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs
2200: common /flags/ iprnta,iprntl,iprntm,iprntn,iprnto,limtim,limpts,
2201: 1 lvlcod,lvltim,itl1,itl2,itl3,itl4,itl5,igoof,nogo,keof
2202: common /blank/ value(1000)
2203: integer nodplc(64)
2204: complex*16 cvalue(32)
2205: equivalence (value(1),nodplc(1),cvalue(1))
2206: c
2207: c
2208: dimension atable(12),aide(20),nnods(20)
2209: dimension idlist(4)
2210: dimension toptit(4)
2211: data toptit / 8helement , 8hnode tab, 8hle , 8h /
2212: data idlist / 3, 6, 8, 9 /
2213: data aide / 1hr,0.0d0,1hl,2*0.0d0,1he,0.0d0,1hh,1hv,0.0d0,1hd,
2214: 1 1hq,1hj,1hm,0.0d0,0.0d0,1ht,0.0d0,0.0d0,0.0d0 /
2215: data nnods / 2,2,2,0,2,2,2,2,2,2,2,4,3,4,4,4,4,0,1,0 /
2216: data ablnk /1h /
2217: c
2218: c allocate storage
2219: c
2220: call getm4(iorder,ncnods)
2221: call getm4(iur,ncnods+1)
2222: c
2223: c construct node table
2224: c
2225: kntlim=lwidth/11
2226: 1300 call getm4(itable,0)
2227: call getm4(itabid,0)
2228: istop=ncnods+1
2229: do 1310 i=1,istop
2230: 1310 nodplc(iur+i)=1
2231: do 1370 id=1,19
2232: if (nnods(id).eq.0) go to 1370
2233: loc=locate(id)
2234: 1320 if (loc.eq.0) go to 1370
2235: nloc=loc+1
2236: jstop=nnods(id)
2237: if (id.ne.19) go to 1330
2238: nloc=nodplc(loc+2)
2239: call sizmem(nodplc(loc+2),jstop)
2240: 1330 do 1360 j=1,jstop
2241: node=nodplc(nloc+j)
2242: ispot=nodplc(iur+node+1)
2243: k=nodplc(iur+ncnods+1)
2244: call extmem(itable,1)
2245: call extmem(itabid,1)
2246: if (k.le.ispot) go to 1340
2247: call copy4(nodplc(itable+ispot),nodplc(itable+ispot+1),k-ispot)
2248: call copy4(nodplc(itabid+ispot),nodplc(itabid+ispot+1),k-ispot)
2249: 1340 nodplc(itable+ispot)=loc
2250: nodplc(itabid+ispot)=id
2251: c... treat the substrate node of a mosfet as if it were a transmission
2252: c... line node, i.e. let it dangle if desired
2253: if(id.eq.14.and.j.eq.4) nodplc(itabid+ispot)=17
2254: k=node
2255: kstop=ncnods+1
2256: 1350 k=k+1
2257: if (k.gt.kstop) go to 1360
2258: nodplc(iur+k)=nodplc(iur+k)+1
2259: go to 1350
2260: 1360 continue
2261: loc=nodplc(loc)
2262: go to 1320
2263: 1370 continue
2264: c
2265: c check that every node has a dc path to ground
2266: c
2267: call zero4(nodplc(iorder+1),ncnods)
2268: nodplc(iorder+1)=1
2269: 1420 iflag=0
2270: do 1470 i=2,ncnods
2271: if (nodplc(iorder+i).eq.1) go to 1470
2272: jstart=nodplc(iur+i)
2273: jstop=nodplc(iur+i+1)-1
2274: if (jstart.gt.jstop) go to 1470
2275: do 1450 j=jstart,jstop
2276: loc=nodplc(itable+j)
2277: id=nodplc(itabid+j)
2278: if (aide(id).eq.0.0d0) go to 1450
2279: if (id.eq.17) go to 1445
2280: kstop=loc+nnods(id)-1
2281: do 1440 k=loc,kstop
2282: node=nodplc(k+2)
2283: if (nodplc(iorder+node).eq.1) go to 1460
2284: 1440 continue
2285: go to 1450
2286: 1445 if (nodplc(loc+2).eq.i) node=nodplc(loc+3)
2287: if (nodplc(loc+3).eq.i) node=nodplc(loc+2)
2288: if (nodplc(loc+4).eq.i) node=nodplc(loc+5)
2289: if (nodplc(loc+5).eq.i) node=nodplc(loc+4)
2290: if (nodplc(iorder+node).eq.1) go to 1460
2291: 1450 continue
2292: go to 1470
2293: 1460 nodplc(iorder+i)=1
2294: iflag=1
2295: 1470 continue
2296: if (iflag.eq.1) go to 1420
2297: c
2298: c print node table and topology error messages
2299: c
2300: if (iprntn.eq.0) go to 1510
2301: call title(0,lwidth,1,toptit)
2302: 1510 do 1590 i=1,ncnods
2303: jstart=nodplc(iur+i)
2304: jstop=nodplc(iur+i+1)-1
2305: if (iprntn.eq.0) go to 1550
2306: if (jstart.le.jstop) go to 1520
2307: write (6,1511) nodplc(junode+i)
2308: 1511 format(1h0,i7)
2309: go to 1550
2310: 1520 kntr=0
2311: jflag=1
2312: do 1540 j=jstart,jstop
2313: loc=nodplc(itable+j)
2314: locv=nodplc(loc+1)
2315: kntr=kntr+1
2316: atable(kntr)=value(locv)
2317: if (kntr.lt.kntlim) go to 1540
2318: if (jflag.eq.0) go to 1525
2319: jflag=0
2320: write (6,1521) nodplc(junode+i),(atable(k),k=1,kntr)
2321: 1521 format(1h0,i7,3x,12(1x,a8))
2322: go to 1530
2323: 1525 write (6,1526) (atable(k),k=1,kntr)
2324: 1526 format(11x,12(1x,a8))
2325: 1530 kntr=0
2326: 1540 continue
2327: if (kntr.eq.0) go to 1550
2328: if (jflag.eq.0) go to 1545
2329: write (6,1521) nodplc(junode+i),(atable(k),k=1,kntr)
2330: go to 1550
2331: 1545 write (6,1526) (atable(k),k=1,kntr)
2332: 1550 if (jstart-jstop) 1560,1552,1556
2333: c
2334: c allow node with only one connection iff element is a t-line
2335: c
2336: 1552 if (nodplc(itabid+jstart).eq.17) go to 1560
2337: 1556 nogo=1
2338: write (6,1557) nodplc(junode+i)
2339: 1557 format('0*error*: less than 2 connections at node ',i6/)
2340: go to 1590
2341: 1560 if (nodplc(iorder+i).eq.1) go to 1590
2342: nogo=1
2343: write (6,1561) nodplc(junode+i)
2344: 1561 format('0*error*: no dc path to ground from node ',i6/)
2345: 1590 continue
2346: c
2347: c check for inductor/voltage source loops
2348: c
2349: do 1700 i=1,ncnods
2350: call zero4(nodplc(iorder+1),ncnods)
2351: nodplc(iorder+i)=-1
2352: do 1690 idcntr=1,4
2353: id=idlist(idcntr)
2354: loc=locate(id)
2355: 1610 if (loc.eq.0) go to 1690
2356: node1=nodplc(loc+2)
2357: node2=nodplc(loc+3)
2358: if (nodplc(iorder+node1)) 1620,1640,1630
2359: 1620 nodplc(iorder+node1)=loc
2360: 1630 node=node2
2361: go to 1670
2362: 1640 if (nodplc(iorder+node2)) 1650,1680,1660
2363: 1650 nodplc(iorder+node2)=loc
2364: 1660 node=node1
2365: 1670 if (nodplc(iorder+node).ne.0) go to 1710
2366: nodplc(iorder+node)=loc
2367: 1680 loc=nodplc(loc)
2368: go to 1610
2369: 1690 continue
2370: 1700 continue
2371: go to 1900
2372: c ... loop found
2373: 1710 locv=nodplc(loc+1)
2374: write (6,1711) value(locv)
2375: 1711 format('0*error*: inductor/voltage source loop found, containing
2376: 1',a8/)
2377: nogo=1
2378: c
2379: c
2380: 1900 call clrmem(iorder)
2381: call clrmem(iur)
2382: call clrmem(itable)
2383: call clrmem(itabid)
2384: 2000 return
2385: end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.