implicit double precision (a-h,o-z)
c this routine drives the pre-processing and general error-checking
c of input performed by spice.
common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem,
1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize,
2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr,
3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1,
4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd,
5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval
common /miscel/ atime,aprog(3),adate,atitle(10),defl,defw,defad,
1 defas,rstats(50),iwidth,lwidth,nopage
common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop,
1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs
common /cje/ maxtim,itime,icost
common /status/ omega,time,delta,delold(7),ag(7),vt,xni,egfet,
1 xmu,mode,modedc,icalc,initf,method,iord,maxord,noncon,iterno,
2 itemno,nosolv,ipostp,iscrch
common /flags/ iprnta,iprntl,iprntm,iprntn,iprnto,limtim,limpts,
1 lvlcod,lvltim,itl1,itl2,itl3,itl4,itl5,igoof,nogo,keof
common /knstnt/ twopi,xlog2,xlog10,root2,rad,boltz,charge,ctok,
1 gmin,reltol,abstol,vntol,trtol,chgtol,eps0,epssil,epsox
common /dc/ tcstar(2),tcstop(2),tcincr(2),icvflg,itcelm(2),kssop,
1 kinel,kidin,kovar,kidout
common /ac/ fstart,fstop,fincr,skw2,refprl,spw2,jacflg,idfreq,
1 inoise,nosprt,nosout,nosin,idist,idprt
common /tran/ tstep,tstop,tstart,delmax,tdmax,forfre,jtrflg
common /outinf/ xincr,string(15),xstart,yvar(8),itab(8),itype(8),
1 ilogy(8),npoint,numout,kntr,numdgt
common /blank/ value(1000)
equivalence (value(1),nodplc(1),cvalue(1))
dimension nnods(50),aname(2)
data aname / 4htrap, 4hgear /
data titlop / 8hoption s, 8hummary , 8h , 8h /
data nnods / 2, 2, 2, 0, 2, 2, 2, 2, 2, 2,
1 2, 4, 3, 4, 0, 0, 4, 0, 1, 0,
2 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4 2, 2, 2, 0, 0, 0, 0, 0, 0, 0 /
data aelmt,amodel,aoutpt /7helement,5hmodel,6houtput/
data alsdc,alstr,alsac / 2hdc, 4htran, 2hac /
10 if (loc.eq.0) go to 60
if (nodplc(loc+2).ne.ndefin) go to 50
20 if (id.ge.31) go to 30
40 write (6,41) anam,value(locv)
41 format('0*error*: ',2a8,' has been referenced but not defined'/)
if (nogo.ne.0) go to 2000
c construct ordered list of user specified nodes
if (nnods(id).eq.0) go to 180
110 if (loc.eq.0) go to 180
120 jstop=loc+nnods(id)-1
150 call putnod(nodplc(loc+2))
call putnod(nodplc(loc+3))
call putnod(nodplc(locp+j))
call sizmem(nodplc(loc+2),nssnod)
if (nogo.ne.0) go to 2000
if (nnods(id).eq.0) go to 280
210 if (loc.eq.0) go to 280
220 jstop=loc+nnods(id)-1
240 if (nodplc(loc+5).eq.0) go to 220
250 call getnod(nodplc(loc+2))
call getnod(nodplc(loc+3))
call getnod(nodplc(locp+j))
call sizmem(nodplc(loc+2),nssnod)
c check and set .nodeset nodes to their internal values
call getnod(nodplc(nsnod+i))
c check and set .ic nodes to their internal values
300 call sizmem(icnod,nic)
call getnod(nodplc(icnod+i))
320 if (nogo.ne.0) go to 2000
c expand subcircuit calls
if (nogo.ne.0) go to 2000
if (ncnods.ge.2) go to 400
321 format('0*error*: circuit has no nodes'/)
c link unsatisfied references
if (nogo.ne.0) go to 2000
c generate subcircuit element names
if (jelcnt(19).eq.0) go to 530
510 if (loc.eq.0) go to 520
c translate node initial conditions to device initial conditions
c (capacitance, diode, bjt, and mosfet only
530 call sizmem(icnod,nic)
call getm8(lvnim1,numnod)
call zero8(value(lvnim1+1),numnod)
535 value(lvnim1+node)=value(icval+i)
540 if(loc.eq.0) go to 550
if(value(locv+2).ne.0.0d0) go to 545
value(locv+2)=value(lvnim1+node1)-value(lvnim1+node2)
555 if(loc.eq.0) go to 565
if(value(locv+2).ne.0.0d0) go to 560
value(locv+2)=value(lvnim1+node1)-value(lvnim1+node2)
570 if(loc.eq.0) go to 580
if(value(locv+2).eq.0.0d0) value(locv+2)=value(lvnim1+node2)-
if(value(locv+3).eq.0.0d0) value(locv+3)=value(lvnim1+node1)-
585 if(loc.eq.0) go to 590
if(value(locv+2).eq.0.0d0) value(locv+2)=value(lvnim1+node1)-
if(value(locv+3).eq.0.0d0) value(locv+3)=value(lvnim1+node2)-
595 if(loc.eq.0) go to 598
if(value(locv+5).eq.0.0d0) value(locv+5)=value(lvnim1+node1)-
if(value(locv+6).eq.0.0d0) value(locv+6)=value(lvnim1+node2)-
if(value(locv+7).eq.0.0d0) value(locv+7)=value(lvnim1+node4)-
600 if (jtrflg.eq.0) go to 700
610 if (loc.eq.0) go to 690
go to (680,620,630,640,650,675), jtype
620 value(locp+3)=dmax1(value(locp+3),0.0d0)
if (value(locp+4).le.0.0d0) value(locp+4)=tstep
if (value(locp+5).le.0.0d0) value(locp+5)=tstep
if (value(locp+6).le.0.0d0) value(locp+6)=tstop
if (value(locp+7).le.0.0d0) value(locp+7)=tstop
temp=value(locp+4)+value(locp+5)+value(locp+6)
value(locp+7)=dmax1(value(locp+7),temp)
value(locv+1)=value(locp+1)
630 if (value(locp+3).le.0.0d0) value(locp+3)=1.0d0/tstop
value(locp+4)=dmax1(value(locp+4),0.0d0)
value(locv+1)=value(locp+1)
640 value(locp+3)=dmax1(value(locp+3),0.0d0)
if (value(locp+4).le.0.0d0) value(locp+4)=tstep
if (value(locp+5).le.value(locp+3))
1 value(locp+5)=value(locp+3)+tstep
if (value(locp+6).le.0.0d0) value(locp+6)=tstep
value(locv+1)=value(locp+1)
650 value(locp+1)=dmin1(dmax1(value(locp+1),0.0d0),tstop)
call sizmem(nodplc(loc+5),nump)
660 temp=value(locp+iknt)
if (value(locp+iknt+2).eq.0.0d0) go to 670
if (value(locp+iknt+2).ge.tstop) go to 670
value(locp+iknt+2)=dmax1(value(locp+iknt+2),temp)
if(temp.ne.value(locp+iknt+2)) go to 665
661 format('0*error*: element ',a8,' piecewise linear source table no
if (iknt.lt.nump) go to 660
670 value(locp+iknt+2)=tstop
value(locv+1)=value(locp+2)
call relmem(nodplc(loc+5),nump-iknt-3)
675 if (value(locp+3).le.0.0d0) value(locp+3)=1.0d0/tstop
if (value(locp+5).le.0.0d0) value(locp+5)=1.0d0/tstop
value(locv+1)=value(locp+1)
c use default values for mos device geometries if not specified
710 if(loc.eq.0) go to 720
if(value(locv+1).le.0.0d0) value(locv+1)=defl
if(value(locv+2).le.0.0d0) value(locv+2)=defw
if(value(locv+3).le.0.0d0) value(locv+3)=defad
if(value(locv+4).le.0.0d0) value(locv+4)=defas
c print listing of elements, process device models,
720 if (iprntl.eq.0) go to 730
if (nogo.ne.0) go to 2000
c invert resistance values
810 if (loc.eq.0) go to 900
value(locv+1)=1.0d0/value(locv+2)
c process mutual inductors
910 if (loc.eq.0) go to 940
call sizmem(nodplc(nl1+10),nparam)
if (nparam.ne.1) go to 920
value(ispot1+1)=value(jspot+1)
if (value(ispot1+1).lt.0.0d0) go to 920
call sizmem(nodplc(nl2+10),nparam)
if (nparam.ne.1) go to 920
value(ispot2+1)=value(jspot+1)
if (value(ispot2+1).lt.0.0d0) go to 920
value(locv+1)=value(locv+1)*dsqrt(value(ispot1+1)*value(ispot2+1))
920 write (6,921) value(locv)
921 format('0*error*: inductors coupled by ',a8,' are negative or non
940 if (nogo.ne.0) go to 2000
c limit delmax to minimum delay over 2 if transmission lines in circuit
if (jtrflg.eq.0) go to 1200
1010 if (loc.eq.0) go to 1200
delmax=dmin1(delmax,value(locv+2)/2.0d0)
tdmax=dmax1(tdmax,value(locv+2))
c process source parameters
if (jtrflg.eq.0) go to 1205
call getm8(lsbkpt,numbkp)
1210 if (loc.eq.0) go to 1290
value(locv+3)=value(locv+2)*dsin(temp)
value(locv+2)=value(locv+2)*dcos(temp)
if (jtrflg.eq.0) go to 1280
go to (1280,1220,1230,1235,1240,1260), jtype
1220 value(locp+4)=value(locp+4)+value(locp+3)
value(locp+5)=value(locp+4)+value(locp+6)
value(locp+6)=value(locp+5)+temp
1225 call extmem(lsbkpt,4)
value(lsbkpt+numbkp+1)=value(locp+3)+time
value(lsbkpt+numbkp+2)=value(locp+4)+time
value(lsbkpt+numbkp+3)=value(locp+5)+time
value(lsbkpt+numbkp+4)=value(locp+6)+time
if (time.ge.tstop) go to 1280
1230 value(locp+3)=value(locp+3)*twopi
1231 value(lsbkpt+numbkp+1)=value(locp+4)
1235 call extmem(lsbkpt,2)
value(lsbkpt+numbkp+1)=value(locp+3)
value(lsbkpt+numbkp+2)=value(locp+5)
call sizmem(nodplc(loc+5),nump)
1250 call extmem(lsbkpt,1)
value(lsbkpt+numbkp+1)=value(locp+iknt)
if (iknt.le.nump) go to 1250
1260 value(locp+3)=value(locp+3)*twopi
value(locp+5)=value(locp+5)*twopi
1300 if (jtrflg.eq.0) go to 1600
value(lsbkpt+numbkp+1)=tstop
call shlsrt(value(lsbkpt+1),numbkp)
if ((value(lsbkpt+i)-value(lsbkpt+nbkpt)).lt.tol) go to 1310
value(lsbkpt+nbkpt)=value(lsbkpt+i)
if (value(lsbkpt+nbkpt).ge.tstop) go to 1320
1320 call relmem(lsbkpt,numbkp-nbkpt)
value(lsbkpt+numbkp)=dmax1(value(lsbkpt+numbkp),tstop)
1600 if (iprnto.eq.0) go to 1700
call title(0,lwidth,1,titlop)
write (6,1601) gmin,reltol,abstol,vntol,lvlcod,itl1,itl2
1601 format('0dc analysis -',/,
write (6,1611) aname(method),maxord,chgtol,trtol,lvltim,xmu,
1611 format('0transient analysis -',/,
3 ' chgtol = ',1pd10.3,/,
write (6,1621) limpts,limtim,maxtim,numdgt,value(itemps+1),
1621 format('0miscellaneous -',/,
c miscellaneous error checking
1700 if (icvflg.eq.0) go to 1720
if (icvflg.le.limpts) go to 1710
write (6,1701) limpts,alsdc
1701 format('0warning: more than ',i5,' points for ',a4,' analysis,',/
11x,'analysis omitted. this limit may be overridden using the ',/
21x,'limpts parameter on the .option card'/)
1710 if ((jelcnt(31)+jelcnt(36)).gt.0) go to 1720
if(ipostp.ne.0) go to 1720
1711 format('0warning: no ',a4,' outputs specified .',
1 '.. analysis omitted'/)
1720 if (jtrflg.eq.0) go to 1740
if (method.eq.1) maxord=2
if ((method.eq.2).and.(maxord.ge.3)) lvltim=2
if (jtrflg.le.limpts) go to 1730
write (6,1701) limpts,alstr
1730 if ((jelcnt(32)+jelcnt(37)+nfour).gt.0) go to 1735
if(ipostp.ne.0) go to 1735
1735 if (nfour.eq.0) go to 1740
if ((tstop-forprd).ge.(tstart-1.0d-12)) go to 1740
1736 format('0warning: fourier analysis fundamental frequency is incom
1patible with'/11x'transient analysis print interval ... fourier an
1740 if (jacflg.eq.0) go to 1800
if (jacflg.le.limpts) go to 1750
write (6,1701) limpts,alsac
1750 if ((jelcnt(33)+jelcnt(34)+jelcnt(35)+jelcnt(38)+jelcnt(39)
1 +jelcnt(40)+idist+inoise).gt.0) go to 1800
if(ipostp.ne.0) go to 1800
c sequence through the output lists
1810 if (loc.eq.0) go to 1820
c increase number of .prints if too many outputs for output line-width
ifwdth=max0(numdgt-1,0)+9
noprln=min0(8,(lwidth-12)/ifwdth)
1830 if(loc.eq.0) go to 1860
noprex=nodplc(loc+3)-noprln
if(noprex.le.0) go to 1850
call find(dfloat(jelcnt(id)),id,locnew,1)
nodplc(locnew+2)=nodplc(loc+2)
call copy4(nodplc(loc+2*noprln+4),nodplc(locnew+4),2*noprex)
rstats(1)=rstats(1)+t2-t1
implicit double precision (a-h,o-z)
c this routine sorts the array a using a shell sort algorithm.
c... compute best starting step size
c... ak = record key; ar = record
40 if (ak.ge.a(i)) go to 50
implicit double precision (a-h,o-z)
c this routine adds 'node' to the list of user input nodes in table
common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem,
1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize,
2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr,
3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1,
4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd,
5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval
common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop,
1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs
common /blank/ value(1000)
equivalence (value(1),nodplc(1),cvalue(1))
if (jknt.gt.nunods) go to 20
if (node-nodplc(junode+jknt)) 20,100,10
call copy4(nodplc(junode+jknt),nodplc(junode+jknt+1),k-jknt)
implicit double precision (a-h,o-z)
c this routine converts from the user node number to the internal
common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem,
1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize,
2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr,
3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1,
4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd,
5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval
common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop,
1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs
common /flags/ iprnta,iprntl,iprntm,iprntn,iprnto,limtim,limpts,
1 lvlcod,lvltim,itl1,itl2,itl3,itl4,itl5,igoof,nogo,keof
common /blank/ value(1000)
equivalence (value(1),nodplc(1),cvalue(1))
if (jknt.gt.nunods) go to 20
if (nodplc(junode+jknt).ne.node) go to 10
c unknown node -- must be implied by .print and/or .plot
20 if (node.eq.0) go to 30
21 format('0warning: attempt to reference undefined node ',i5,
1 ' -- node reset to 0'/)
implicit double precision (a-h,o-z)
c this routine drives the expansion of subcircuit calls.
common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem,
1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize,
2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr,
3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1,
4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd,
5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval
common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop,
1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs
common /flags/ iprnta,iprntl,iprntm,iprntn,iprnto,limtim,limpts,
1 lvlcod,lvltim,itl1,itl2,itl3,itl4,itl5,igoof,nogo,keof
common /blank/ value(1000)
equivalence (value(1),nodplc(1),cvalue(1))
c... avoid 'call by value' problems, make inodi, inodx arrays
c... in routines which receive them as parameters !!!
10 if (locx.eq.0) go to 300
call fndnam(asnam,locx-1,locx+3,20)
20 if (isbptr.eq.0) go to 30
if (locs.eq.nodplc(isbptr+3)) go to 260
30 call sizmem(nodplc(locx+2),nxnod)
call sizmem(nodplc(locs+2),nssnod)
if (nxnod.ne.nssnod) go to 250
call copy4(nodplc(itemp+1),nodplc(inodx+1),nssnod)
call copy4(nodplc(itemp+1),nodplc(inodi+1),nxnod)
c add elements of subcircuit to nominal circuit
100 if (loc.eq.0) go to 200
call find(dfloat(jelcnt(id)),id,loce,1)
call addelt(loce,loc,id,inodx,inodi,nxnod)
write (6,251) axnam,asnam
251 format('0*error*: ',a8,' has different number of nodes than ',a8/
261 format('0*error*: subcircuit ',a8,' is defined recursively'/)
subroutine fndnam(anam,jsbptr,ispot,id)
implicit double precision (a-h,o-z)
c this routine searches for an element with id 'id' by tracing back
c up the subcircuit definition list. if the element is not found, the
c nominal element list is searched.
common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem,
1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize,
2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr,
3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1,
4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd,
5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval
common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop,
1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs
common /flags/ iprnta,iprntl,iprntm,iprntn,iprnto,limtim,limpts,
1 lvlcod,lvltim,itl1,itl2,itl3,itl4,itl5,igoof,nogo,keof
common /blank/ value(1000)
equivalence (value(1),nodplc(1),cvalue(1))
10 if (isbptr.eq.0) go to 50
20 if (loc.eq.0) go to 40
if (id.ne.nodplc(loc-1)) go to 30
if (xxor(anam,value(locv)).ne.0) go to 30
40 isbptr=nodplc(isbptr-1)
60 if (loc.eq.0) go to 90
if (nodplc(loc-1).ne.isbptr) go to 70
if (xxor(anam,value(locv)).ne.0) go to 70
91 format('0*error*: unable to find ',a8/)
subroutine newnod(nodold,nodnew,inodx,inodi,nnodi)
implicit double precision (a-h,o-z)
c this routine makes a new node number for an element which is about
c to be added to the circuit as a result of a subcircuit call.
common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem,
1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize,
2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr,
3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1,
4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd,
5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval
common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop,
1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs
common /blank/ value(1000)
equivalence (value(1),nodplc(1),cvalue(1))
c... inodx, inodi are arrays (see subckt)
dimension inodx(1),inodi(1)
if (nodold.ne.nodplc(jnodx+i)) go to 10
nodplc(jnodx+nnodi)=nodold
nodplc(jnodi+nnodi)=ncnods
nodplc(junode+ncnods)=nodplc(junode+ncnods-1)+1
subroutine addelt(loce,loc,id,inodx,inodi,nnodi)
implicit double precision (a-h,o-z)
c this routine adds an element to the nominal circuit definition
common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem,
1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize,
2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr,
3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1,
4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd,
5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval
common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop,
1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs
common /flags/ iprnta,iprntl,iprntm,iprntn,iprnto,limtim,limpts,
1 lvlcod,lvltim,itl1,itl2,itl3,itl4,itl5,igoof,nogo,keof
common /blank/ value(1000)
equivalence (value(1),nodplc(1),cvalue(1))
c... inodx(1), inodi(1) are arrays (see subckt)
dimension inodx(1),inodi(1)
dimension lnod(50),lval(50),nnods(50)
data lnod / 9,13,15, 7,14,15,14,15,12, 7,
1 17,37,26,34, 7, 7,34, 0, 5, 5,
2 4, 4, 4, 4, 0, 0, 0, 0, 0, 0,
3 21,21,21,21,21,21,21,21,21,21,
4 8, 8, 8, 8, 8, 0, 0, 0, 0, 0 /
data lval / 5, 4, 4, 2, 1, 1, 1, 1, 4, 4,
1 3, 4, 4,13, 1, 1, 9, 0, 1, 1,
2 19,55,17,41, 0, 0, 0, 0, 0, 0,
3 1, 1, 1, 1, 1,17,17,17,17,17,
4 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 /
data nnods / 2, 2, 2, 0, 2, 2, 2, 2, 2, 2,
1 2, 4, 3, 4, 4, 4, 4, 0, 1, 0,
2 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4 2, 2, 2, 0, 0, 0, 0, 0, 0, 0 /
call copy4(nodplc(loc+2),nodplc(loce+2),nword)
10 if (id.ge.21) go to 100
if (nnods(id).eq.0) go to 100
call newnod(nodplc(loc+j+1),nodplc(loce+j+1),inodx(1),
40 call newnod(nodplc(loc+2),nodplc(loce+2),inodx(1),inodi(1),nnodi)
call newnod(nodplc(loc+3),nodplc(loce+3),inodx(1),inodi(1),nnodi)
call getm4(nodplc(loce+id+1),nssnod)
call newnod(nodold,nodnew,inodx(1),inodi(1),nnodi)
call sizmem(nodplc(loc+2),nssnod)
call getm4(nodplc(loce+2),nssnod)
100 if (nogo.ne.0) go to 300
call copy8(value(locv),value(locve),lval(id))
c treat non-node tables specially
200 if (id.ge.11) go to 300
go to (300,210,220,300,230,240,230,240,260,260), id
210 call cpytb8(loc+7,loce+7)
220 call cpytb8(loc+10,loce+10)
250 if (id.le.6) go to 255
call cpytb4(loc+itab+1,loce+itab+1)
255 call cpytb4(loc+itab+2,loce+itab+2)
call cpytb8(loc+itab+3,loce+itab+3)
call cpytb8(loc+itab+4,loce+itab+4)
call cpytb4(loc+itab+5,loce+itab+5)
call cpytb8(loc+itab+6,loce+itab+6)
260 call cpytb8(loc+5,loce+5)
subroutine cpytb4(itabo,itabn)
implicit double precision (a-h,o-z)
c this routine copies a table. its use is made necessary by the
c fact that only one pointer is allowed per table.
common /blank/ value(1000)
equivalence (value(1),nodplc(1),cvalue(1))
call sizmem(nodplc(itabo),isize)
call getm4(nodplc(itabn),isize)
call copy4(nodplc(loco+1),nodplc(locn+1),isize)
subroutine cpytb8(itabo,itabn)
implicit double precision (a-h,o-z)
c this routine copies a table. its use is made necessary by the
c fact that only one pointer is allowed per table.
common /blank/ value(1000)
equivalence (value(1),nodplc(1),cvalue(1))
call sizmem(nodplc(itabo),isize)
call getm8(nodplc(itabn),isize)
call copy8(value(loco+1),value(locn+1),isize)
implicit double precision (a-h,o-z)
c this routine resolves all unsatisfied name references.
common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem,
1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize,
2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr,
3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1,
4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd,
5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval
common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop,
1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs
common /flags/ iprnta,iprntl,iprntm,iprntn,iprnto,limtim,limpts,
1 lvlcod,lvltim,itl1,itl2,itl3,itl4,itl5,igoof,nogo,keof
common /blank/ value(1000)
equivalence (value(1),nodplc(1),cvalue(1))
100 if (loc.eq.0) go to 200
call fndnam(value(iunsat+iref),loc-1,loc+2,3)
call fndnam(value(iunsat+iref),loc-1,loc+3,3)
c current-controlled current source
210 if (loc.eq.0) go to 300
call fndnam(value(iunsat+iref),loc-1,locp+i,9)
c current-controlled voltage sources
310 if (loc.eq.0) go to 400
call fndnam(value(iunsat+iref),loc-1,locp+i,9)
410 if (loc.eq.0) go to 500
call fndnam(value(iunsat+iref),loc-1,loc+5,21)
510 if (loc.eq.0) go to 600
call fndnam(value(iunsat+iref),loc-1,loc+8,22)
610 if (loc.eq.0) go to 700
call fndnam(value(iunsat+iref),loc-1,loc+7,23)
710 if (loc.eq.0) go to 1000
call fndnam(value(iunsat+iref),loc-1,loc+8,24)
implicit double precision (a-h,o-z)
c this routine constructs the names of elements added as a result of
c subcircuit expansion. the full element names are of the form
c name.xn. --- xd.xc.xb.xa
c where 'name' is the nominal element name, and the 'x'*s denote the
c sequence of subcircuit calls (from top or circuit level down through
c nested subcircuit calls) which caused the particular element to be
c added. at present, spice restricts all element names to be 8 charac-
c ters or less. therefore, the name used consists of the leftmost 8
c characters of the full element name, with the rightmost character
c replaced by an asterisk ('*') if the full element name is longer than
common /blank/ value(1000)
equivalence (value(1),nodplc(1),cvalue(1))
data ablank, aper, astk / 1h , 1h., 1h* /
c construct subcircuit element name
if (nodplc(loce-1).eq.0) go to 100
call move(achar,1,elname,ichar,1)
if (achar.eq.ablank) go to 30
call move(sname,nchar,achar,1,1)
call move(sname,nchar,aper,1,1)
c name is longer than 8 characters: flag with asterisk
40 call move(sname,8,astk,1,1)
implicit double precision (a-h,o-z)
c this routine prints a circuit element summary.
common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem,
1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize,
2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr,
3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1,
4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd,
5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval
common /miscel/ atime,aprog(3),adate,atitle(10),defl,defw,defad,
1 defas,rstats(50),iwidth,lwidth,nopage
common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop,
1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs
common /flags/ iprnta,iprntl,iprntm,iprntn,iprnto,limtim,limpts,
1 lvlcod,lvltim,itl1,itl2,itl3,itl4,itl5,igoof,nogo,keof
common /tran/ tstep,tstop,tstart,delmax,tdmax,forfre,jtrflg
common /blank/ value(1000)
equivalence (value(1),nodplc(1),cvalue(1))
dimension itab(25),astyp(6)
data eltitl / 8hcircuit , 8helement , 8hsummary , 8h /
data astyp / 1h , 5hpulse, 3hsin, 3hexp, 3hpwl, 4hsffm /
data ablnk,aoff /1h ,3hoff/
c print listing of elements
call title(0,lwidth,1,eltitl)
if (jelcnt(1).eq.0) go to 50
21 format(//'0**** resistors'/'0 name nodes value
30 if (loc.eq.0) go to 50
if (ititle.eq.0) write (6,21)
write (6,31) value(locv),nodplc(junode+node1),
1 nodplc(junode+node2),value(locv+2),value(locv+3),value(locv+4)
31 format(6x,a8,2i5,1p3d11.2)
c print capacitors and inductors
50 if ((jelcnt(2)+jelcnt(3)).eq.0) go to 80
51 format(//'0**** capacitors and inductors'/'0 name nodes
60 if (loc.eq.0) go to 70
if (ititle.eq.0) write (6,51)
call sizmem(nodplc(loc+ltab),nparam)
if (nparam.ge.2) go to 62
write (6,31) value(locv),nodplc(junode+node1),
1 nodplc(junode+node2),value(locv+2),value(ispot)
62 write (6,63) value(locv),nodplc(junode+node1),
1 nodplc(junode+node2),value(locv+2)
63 format(6x,a8,2i5,1pd11.2,' variable')
80 if (jelcnt(4).eq.0) go to 100
81 format(//'0**** mutual inductors'/'0 name coupled induc
90 if (loc.eq.0) go to 110
if (ititle.eq.0) write (6,81)
write (6,91) value(locv),value(nl1),value(nl2),value(locv+1)
91 format(6x,a8,4x,a8,2x,a8,1pd10.2)
c print nonlinear voltage controlled sources
100 if (jelcnt(5).eq.0) go to 120
101 format(//'0**** voltage-controlled current sources'/'0 name
1 + - dimension function')
110 if (loc.eq.0) go to 120
if (ititle.eq.0) write (6,101)
write (6,111) value(locv),nodplc(junode+node1),
1 nodplc(junode+node2),nodplc(loc+4)
111 format(6x,a8,2i5,i8,9x,'poly')
c nonlinear voltage controlled voltage sources
120 if (jelcnt(6).eq.0) go to 140
121 format(//'0**** voltage-controlled voltage sources'/'0 name
1 + - dimension function')
130 if (loc.eq.0) go to 140
if (ititle.eq.0) write (6,121)
write (6,111) value(locv),nodplc(junode+node1),
1 nodplc(junode+node2),nodplc(loc+4)
c nonlinear current controlled current sources
140 if (jelcnt(7).eq.0) go to 160
141 format(//'0**** current-controlled current sources'/'0 name
1 + - dimension function')
150 if (loc.eq.0) go to 160
if (ititle.eq.0) write (6,141)
write (6,111) value(locv),nodplc(junode+node1),
1 nodplc(junode+node2),nodplc(loc+4)
c nonlinear current controlled voltage sources
160 if (jelcnt(8).eq.0) go to 170
161 format(//'0**** current-controlled voltage sources'/'0 name
1 + - dimension function')
165 if (loc.eq.0) go to 170
if (ititle.eq.0) write (6,161)
write (6,111) value(locv),nodplc(junode+node1),
1 nodplc(junode+node2),nodplc(loc+4)
c print independent sources
170 if ((jelcnt(9)+jelcnt(10)).eq.0) go to 250
171 format(//'0**** independent sources'/'0 name nodes dc
1 value ac value ac phase transient'//)
180 if (loc.eq.0) go to 245
if (ititle.eq.0) write (6,171)
write (6,181) value(locv),nodplc(junode+node1),
1 nodplc(junode+node2),value(locv+1),value(locv+2),
181 format(6x,a8,2i5,1p3d11.2,2x,a8)
if (jtrflg.eq.0) go to 240
go to (240,190,200,210,220,230), itype
write (6,191) (value(j),j=jstart,jstop)
191 format(1h0,42x,'initial value',1pd11.2,/,
1 43x,'pulsed value.', d11.2,/,
2 43x,'delay time...', d11.2,/,
3 43x,'risetime.....', d11.2,/,
4 43x,'falltime.....', d11.2,/,
5 43x,'width........', d11.2,/,
6 43x,'period.......', d11.2,/)
write (6,201) (value(j),j=jstart,jstop)
201 format(1h0,42x,'offset.......',1pd11.2,/,
1 43x,'amplitude....', d11.2,/,
2 43x,'frequency....', d11.2,/,
3 43x,'delay........', d11.2,/,
4 43x,'theta........', d11.2,/)
write (6,211) (value(j),j=jstart,jstop)
211 format(1h0,42x,'initial value',1pd11.2,/,
1 43x,'pulsed value.', d11.2,/,
2 43x,'rise delay...', d11.2,/,
3 43x,'rise tau.....', d11.2,/,
4 43x,'fall delay...', d11.2,/,
5 43x,'fall tau.....', d11.2,/)
220 call sizmem(nodplc(loc+5),jstop)
write (6,221) (value(j),j=jstart,jstop)
221 format(1h0,49x,'time value'//,(46x,1p2d11.2))
write (6,231) (value(j),j=jstart,jstop)
231 format(1h0,42x,'offset.......',1pd11.2,/,
1 43x,'amplitude....', d11.2,/,
2 43x,'carrier freq.', d11.2,/,
3 43x,'modn index...', d11.2,/,
4 43x,'signal freq..', d11.2,/)
c print transmission lines
250 if (jelcnt(17).eq.0) go to 260
251 format(//'0**** transmission lines'/'0 name nodes
253 if (loc.eq.0) go to 260
if (ititle.eq.0) write (6,251)
write (6,256) value(locv),nodplc(junode+node1),
1 nodplc(junode+node2),nodplc(junode+node3),
2 nodplc(junode+node4),value(locv+1),value(locv+2)
256 format(6x,a8,4i5,1p2d11.2)
260 if (jelcnt(11).eq.0) go to 290
261 format(//'0**** diodes'/'0 name + - model are
270 if (loc.eq.0) go to 290
if (ititle.eq.0) write (6,261)
if (nodplc(loc+6).eq.1) aic=aoff
write (6,271) value(locv),nodplc(junode+node1),
1 nodplc(junode+node2),value(locm),value(locv+1),aic
271 format(6x,a8,2i5,2x,a8,f8.3,2x,a8)
290 if (jelcnt(12).eq.0) go to 320
291 format(//'0**** bipolar junction transistors'/'0 name c
300 if (loc.eq.0) go to 320
if (ititle.eq.0) write (6,291)
if (nodplc(loc+9).eq.1) aic=aoff
write (6,301) value(locv),nodplc(junode+node1),
1 nodplc(junode+node2),nodplc(junode+node3),nodplc(junode+node4),
2 value(locm),value(locv+1),aic
301 format(6x,a8,4i5,2x,a8,f8.3,2x,a8)
320 if (jelcnt(13).eq.0) go to 350
321 format(//'0**** jfets'/'0 name d g s model
330 if (loc.eq.0) go to 350
if (ititle.eq.0) write (6,321)
if (nodplc(loc+8).eq.1) aic=aoff
write (6,331) value(locv),nodplc(junode+node1),
1 nodplc(junode+node2),nodplc(junode+node3),
2 value(locm),value(locv+1),aic
331 format(6x,a8,3i5,2x,a8,f8.3,2x,a8)
350 if (jelcnt(14).eq.0) go to 400
351 format(//'0**** mosfets',/,'0name d g s b model l
360 if (loc.eq.0) go to 400
if (ititle.eq.0) write (6,351)
if(rd.eq.0.0d0) rd=value(locm+6)
if(rs.eq.0.0d0) rs=value(locm+7)
if (nodplc(loc+9).eq.1) aic=aoff
write (6,361) value(locv),nodplc(junode+node1),
1 nodplc(junode+node2),nodplc(junode+node3),
2 nodplc(junode+node4),value(locm),value(locv+1),value(locv+2),
3 value(locv+3),value(locv+4),rd,rs
361 format(1x,a8,4i4,1x,a8,1pd7.1,5d8.1)
if(aic.ne.ablnk) write(6,362)
362 format(1x,'above device specified to be *off* to aid dc solution',
400 if (jelcnt(19).eq.0) go to 500
401 format(//'0**** subcircuit calls'/'0 name subcircuit ext
410 if (loc.eq.0) go to 500
if (ititle.eq.0) write (6,401)
call sizmem(nodplc(loc+2),nnodx)
412 jstop=min0(nnodx,jstart+ndprln-1)
itab(j-jstart+1)=nodplc(junode+node)
1 write (6,416) value(locv),value(locsv),(itab(j),j=1,jstop)
416 format(6x,a8,2x,a8,4x,20i5)
1 write (6,418) (itab(j-jstart+1),j=jstart,jstop)
if (jstart.le.nnodx) go to 412
if (nnodx.le.ndprln) go to 420
implicit double precision (a-h,o-z)
c this routine performs one-time processing of device model para-
c meters and prints out a device model summary. it also reserves the
c additional nodes required by nonzero device extrinsic resistances.
common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem,
1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize,
2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr,
3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1,
4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd,
5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval
common /miscel/ atime,aprog(3),adate,atitle(10),defl,defw,defad,
1 defas,rstats(50),iwidth,lwidth,nopage
common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop,
1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs
common /status/ omega,time,delta,delold(7),ag(7),vt,xni,egfet,
1 xmu,mode,modedc,icalc,initf,method,iord,maxord,noncon,iterno,
2 itemno,nosolv,ipostp,iscrch
common /flags/ iprnta,iprntl,iprntm,iprntn,iprnto,limtim,limpts,
1 lvlcod,lvltim,itl1,itl2,itl3,itl4,itl5,igoof,nogo,keof
common /knstnt/ twopi,xlog2,xlog10,root2,rad,boltz,charge,ctok,
1 gmin,reltol,abstol,vntol,trtol,chgtol,eps0,epssil,epsox
common /blank/ value(1000)
equivalence (value(1),nodplc(1),cvalue(1))
dimension itab(50),atable(10)
dimension antype(4),aptype(4)
dimension ipar(6),ampar(120),defval(120),ifmt(120)
dimension titled(4),titleb(4),titlej(4),titlem(4)
data titled / 8hdiode mo, 8hdel para, 8hmeters , 8h /
data titleb / 8hbjt mode, 8hl parame, 8hters , 8h /
data titlej / 8hjfet mod, 8hel param, 8heters , 8h /
data titlem / 8hmosfet m, 8hodel par, 8hameters , 8h /
data antype /1h ,3hnpn,3hnjf,4hnmos/
data aptype /1h ,3hpnp,3hpjf,4hpmos/
data ipar / 0, 14, 60, 72, 106, 119 /
data hndrd,hndrd2 /1.0d+02,1.0d+04/
1 6his ,6hrs ,6hn ,6htt ,6hcjo ,6hpb ,6hm ,
2 6heg ,6hpt ,6hkf ,6haf ,6hfc ,6hbv ,6hibv ,
1 6hjs ,6hbf ,6hnf ,6hvbf ,6hjbf ,6hjle ,6hnle ,
2 6hbr ,6hnr ,6hvbr ,6hjbr ,6hjlc ,6hnlc ,6h0 ,
3 6h0 ,6hrb ,6hjrb ,6hrbm ,6hre ,6hrc ,6hcje ,
4 6hvje ,6hmje ,6htf ,6hxtf ,6hvtf ,6hjtf ,6hptf ,
5 6hcjc ,6hvjc ,6hmjc ,6hcdis ,6htr ,6h0 ,6h0 ,
6 6h0 ,6h0 ,6hcjs ,6hvjs ,6hmjs ,6htb ,6heg ,
7 6hpt ,6hkf ,6haf ,6hfc ,
1 6hvto ,6hbeta ,6hlambda,6hrd ,6hrs ,6hcgs ,6hcgd ,
2 6hpb ,6his ,6hkf ,6haf ,6hfc ,
1 6hvto ,6hkp ,6hgamma ,6hphi ,6hlambda,6hrd ,6hrs ,
2 6hcgs ,6hcgd ,6hcgb ,6hcbd ,6hcbs ,6htox ,6hpb ,
3 6hjs ,6hnsub ,6hnss ,6hnfs ,6hxj ,6hld ,6hngate ,
4 6htps ,6huo ,6hucrit ,6huexp ,6hutra ,6hkf ,6haf ,
5 6hfc ,6hwd ,6hecrit ,6hetra ,6hvnorm ,6hdesat ,
1 6hvp ,6hvbr ,6hvbi ,6hvfwd ,6hnd ,6hkdso ,6hkdv ,
2 6hcdso ,6hczg ,6hgnoise,6hnexp ,6hkf ,6haf ,0.0d0 /
1 1.0d-14, 0.0d0, 1.0d0, 2*0.0d0, 1.0d0, 0.5d0, 1.11d0,
2 3.0d0, 0.0d0, 1.0d0, 0.5d0, 0.0d0, 1.0d-3,
1 1.0d-16, 100.0d0, 1.0d0, 3*0.0d0, 1.5d0, 2*1.0d0, 3*0.0d0,
2 2.0d0, 0.0d0, 1.0d0, 0.0d0, 0.0d0, 4*0.0d0, 0.75d0,
3 0.33d0, 2*0.0d0, 2*0.0d0, 2*0.0d0, 0.75d0, 0.33d0, 1.0d0,
4 2*0.0d0, 2*0.0d0, 2*0.0d0, 0.75d0, 0.0d0, 0.0d0, 1.11d0,
5 3.0d0, 0.0d0, 1.0d0, 0.5d0,
1 -2.0d0, 1.0d-4, 5*0.0d0, 1.0d0,1.0d-14, 0.0d0, 1.0d0,
1 3*0.0d0, 0.0d0, 8*0.0d0, 1.0d-7, 0.8d0, 1.0d-4,6*0.0d0,
2 1.0d0,700.0d0, 1.0d+4, 3*0.0d0, 1.0d0, 0.5d0, 0.0d0,
1 -2.1d0, 0.0d0, 0.8d0, 0.6d0, 1.0d17, 5.8d0 ,0.01d0,
2 2.0d-10, 0.0d0, 0.0d0, 1.0d0, 0.0d0, 1.0d0, 0.0d0 /
1 2,1,1,2,2,1,1,1,1,2,1,1,2,2,
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,
a 1,1,2,0,0,0,0,2,1,1,2,1,1,2,2,2,
3 1,2,1,1,1,2,2,1,2,2,1,1,
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,
5 1,1,1,1,2,2,2,2,2,2,1,2,1,0/
tnom=value(itemps+1)+ctok
egfet=1.16d0-(7.02d-04*tnom**2/(tnom+1108.0d0))
arg=-egfet/2.0d0/boltz/tnom+1.1151d0/boltz/2.0d0/(27.0d0+ctok)
xni=1.45d10*(tnom/(27.0d0+ctok))**1.5d0*dexp(charge*arg)
nummod=jelcnt(21)+jelcnt(22)+jelcnt(23)+jelcnt(24)
if (nummod.eq.0) go to 1000
if (jelcnt(id+20).eq.0) go to 390
10 if (loc.eq.0) go to 20
c... special case of gaas
if(id.eq.4.and.nodplc(loc+2).eq.0) id1=5
if (value(locv+i).eq.0.0d0) go to 16
if(i.eq.2.and.id1.eq.5) go to 18
14 if (value(locv+i).gt.0.0d0) go to 18
c.. let pt be negative for bjts (for now anyway!)
if(i.eq.43.and.id.eq.2) go to 18
c... nss, ld, wd, utra and tps for mosfet can be negative
if((i.eq.22.or.i.eq.17.or.i.eq.20.or.i.eq.30.or.i.eq.26)
c... vbr for ga-as fets must be negative
16 value(locv+i)=defval(locm+i)
20 go to (30,40,50,60), id
32 if (loc.eq.0) go to 100
value(locv+7)=dmin1(value(locv+7),0.9d0)
value(locv+8)=dmax1(value(locv+8),0.1d0)
value(locv+11)=dmax1(value(locv+11),0.1d0)
value(locv+12)=dmin1(value(locv+12),0.95d0)
42 if (loc.eq.0) go to 100
value(locv+23)=dmin1(value(locv+23),0.9d0)
if(value(locv+24).eq.0.0d0) value(locv+28)=0.0d0
value(locv+31)=dmin1(value(locv+31),0.9d0)
value(locv+32)=dmin1(value(locv+32),1.0d0)
value(locv+40)=dmin1(value(locv+40),0.9d0)
value(locv+42)=dmax1(value(locv+42),0.1d0)
value(locv+45)=dmax1(value(locv+45),0.1d0)
value(locv+46)=dmin1(value(locv+46),0.9999d0)
if(value(locv+18).eq.0.0d0) value(locv+18)=value(locv+16)
if(value(locv+16).ge.value(locv+18)) go to 42
44 format('0warning: minimum base resistance (rbm) is less than '
1 ,'total (rb) for model ',a8,/10x' rbm set equal to rb',/)
value(locv+18)=value(locv+16)
52 if (loc.eq.0) go to 100
value(locv+11)=dmax1(value(locv+11),0.1d0)
value(locv+12)=dmin1(value(locv+12),0.95d0)
64 if (loc.eq.0) go to 100
if(nodplc(loc+2).eq.0) go to 70
c special preprocessing for mosfet models
cox=epsox/value(locv+13)/hndrd
c... if kp not given, calculate it from cox and uo
if(value(locv+2).eq.0.0d0)
1 value(locv+2)=value(locv+23)*cox
c... nsub nonzero => calculate gamma, vto, phi unless specified
if (value(locv+16).le.0.0d0) go to 68
if (xnsub.le.xni) go to 66
if (value(locv+4).le.0.0d0) value(locv+4)=2.0d0*vt*dlog(xnsub/xni)
if (value(locv+3).le.0.0d0)
1 value(locv+3)=dsqrt(2.0d0*epssil*charge*xnsub)/cox
fermis=type*0.5d0*value(locv+4)
c... polysilicon gate ... calculate appropriate work function
if (value(locv+21).le.0.0d0) go to 65
fermig=type*value(locv+22)*vt*dlog(value(locv+21)/xni)
wkfng=3.25d0+0.5d0*egfet-fermig
65 wkfngs=wkfng-(3.25d0+0.5d0*egfet+fermis)
if(value(locv+1).eq.0.0d0)
1 value(locv+1)= wkfngs-value(locv+17)*charge/cox+
2 type*(value(locv+4)+value(locv+3)*dsqrt(value(locv+4)))
value(locv+35)=dsqrt((epssil+epssil)/(charge*xnsub))
67 format('0*error*: nsub < ni in mosfet model ',a8,/)
c... set phi to default if still zero
68 if(value(locv+4).eq.0.0d0) value(locv+4)=0.6d0
value(locv+4)=dmax1(value(locv+4),0.1d0)
value(locv+28)=dmax1(value(locv+28),0.1d0)
value(locv+29)=dmin1(value(locv+29),0.95d0)
70 value(locv+1)=-dabs(value(locv+1))
if(value(locv+2).ne.0.0d0) value(locv+2)=-dabs(value(locv+2))
value(locv+2)=dmax1(value(locv+2),-200.0d0)
if(value(locv+9).eq.0.0d0)
1 value(locv+9)=2.49d-12*dsqrt(value(locv+5)/value(locv+3))
100 if (iprntm.eq.0) go to 390
go to (120,130,140,150),id
120 call title(0,lwidth,1,titled)
130 call title(0,lwidth,1,titleb)
140 call title(0,lwidth,1,titlej)
150 call title(0,lwidth,1,titlem)
200 if (loc.eq.0) go to 210
if (kntr.lt.kntlim) go to 220
240 write (6,241) (atable(k),k=1,kntr)
241 format(//11x,12(2x,a8))
250 if (loc.eq.0) go to 260
if (kntr.ge.kntlim) go to 260
if (nodplc(loc+2).eq.-1) atable(kntr)=aptype(id)
c... special type for ga-as (do not mix ga-as and mos!)
if(id.eq.4.and.nodplc(loc+2).eq.0) atable(kntr)=agaas
260 write (6,261) (atable(k),k=1,kntr)
261 format('0type',4x,12(4x,a6))
if (itab(i).eq.0) go to 340
310 if (loc.eq.0) go to 320
if (kntr.ge.kntlim) go to 320
atable(kntr)=value(locv+i)
320 if (itab(i).eq.2) go to 330
write (6,321) ampar(locm+i),(atable(k),k=1,kntr)
321 format(1h ,a8,12f10.3)
330 write (6,331) ampar(locm+i),(atable(k),k=1,kntr)
331 format(1h ,a8,1p12d10.2)
c process model parameters
410 if (loc.eq.0) go to 420
if (value(locv+2).ne.0.0d0) value(locv+2)=1.0d0/value(locv+2)
value(locv+15)=pb*(1.0d0-dexp((1.0d0-xm)*xfc))/(1.0d0-xm)
value(locv+16)=dexp((1.0d0+xm)*xfc)
value(locv+17)=1.0d0-fc*(1.0d0+xm)
value(locv+18)=vte*dlog(vte/(root2*csat))
if(bv.eq.0.0d0) go to 418
if(cbv.ge.csat*bv/vt) go to 412
write(6,411) value(locv),cbv
411 format('0warning: in diode model ',a8,' ibv increased to ',
1 1pd10.3,/10x,'to resolve incompatibility with specified is',/)
xbv=bv-vt*dlog(1.0d0+cbv/csat)
413 xbv=bv-vt*dlog(cbv/csat+1.0d0-xbv/vt)
xcbv=csat*(dexp((bv-xbv)/vt)-1.0d0+xbv/vt)
if (dabs(xcbv-cbv).le.tol) go to 416
if (iter.lt.25) go to 413
415 format('0warning: unable to match forward and reverse diode regio
1ns',/,11x,'bv = ',1pd10.3,' and ibv = ',d10.3,/)
c bipolar transistor models
430 if (loc.eq.0) go to 440
if(value(locv+4).ne.0.0d0) value(locv+4)=1.0d0/value(locv+4)
if(value(locv+5).ne.0.0d0) value(locv+5)=1.0d0/value(locv+5)
if(value(locv+10).ne.0.0d0) value(locv+10)=1.0d0/value(locv+10)
if(value(locv+11).ne.0.0d0) value(locv+11)=1.0d0/value(locv+11)
if(value(locv+19).ne.0.0d0) value(locv+19)=1.0d0/value(locv+19)
if(value(locv+20).ne.0.0d0) value(locv+20)=1.0d0/value(locv+20)
if(value(locv+26).ne.0.0d0) value(locv+26)=1.0d0/value(locv+26)
value(locv+28)=value(locv+28)/rad*value(locv+24)
if(value(locv+35).ne.0.0d0) value(locv+35)=1.0d0/value(locv+35)
value(locv+47)=pe*(1.0d0-dexp((1.0d0-xme)*xfc))/(1.0d0-xme)
value(locv+48)=dexp((1.0d0+xme)*xfc)
value(locv+49)=1.0d0-fc*(1.0d0+xme)
value(locv+51)=pc*(1.0d0-dexp((1.0d0-xmc)*xfc))/(1.0d0-xmc)
value(locv+52)=dexp((1.0d0+xmc)*xfc)
value(locv+53)=1.0d0-fc*(1.0d0+xmc)
value(locv+54)=vt*dlog(vt/(root2*csat))
450 if (loc.eq.0) go to 460
if (value(locv+4).ne.0.0d0) value(locv+4)=1.0d0/value(locv+4)
if (value(locv+5).ne.0.0d0) value(locv+5)=1.0d0/value(locv+5)
value(locv+13)=pb*(1.0d0-dexp((1.0d0-xm)*xfc))/(1.0d0-xm)
value(locv+14)=dexp((1.0d0+xm)*xfc)
value(locv+15)=1.0d0-fc*(1.0d0+xm)
value(locv+16)=vt*dlog(vt/(root2*csat))
470 if (loc.eq.0) go to 600
if(nodplc(loc+2).eq.0) go to 490
c... check validiy of lambda
if(value(locv+5).lt.5.0d-6) go to 472
471 format('0warning: value for lambda unrealisticly large for model'
1 ,1x,a8,/'0this parameter has been re-defined. see latest users '
472 value(locv+5)=value(locv+5)*hndrd
value(locv+8)=value(locv+8)/hndrd
value(locv+9)=value(locv+9)/hndrd
value(locv+10)=value(locv+10)/hndrd
value(locv+11)=value(locv+11)/hndrd2
value(locv+12)=value(locv+12)/hndrd2
value(locv+13)=value(locv+13)*hndrd
value(locv+15)=value(locv+15)/hndrd2
value(locv+19)=value(locv+19)*hndrd
value(locv+20)=value(locv+20)*hndrd
c.. move the params wd-gleff out to positions 36-40
value(locv+36)=value(locv+30)*hndrd
value(locv+37)=value(locv+31)
value(locv+38)=value(locv+32)
value(locv+39)=value(locv+33)
value(locv+40)=value(locv+34)
if(value(locv+39).ne.0.0d0) value(locv+39)=1.0d0/value(locv+39)
if (value(locv+6).ne.0.0d0) value(locv+6)=1.0d0/value(locv+6)
if (value(locv+7).ne.0.0d0) value(locv+7)=1.0d0/value(locv+7)
if (value(locv+13).ne.0.0d0) value(locv+13)=epsox/value(locv+13)
value(locv+34)=value(locv+1)-
1 type*value(locv+3)*dsqrt(value(locv+4))
if (value(locv+13).ne.0.0d0)
1 value(locv+24)=value(locv+24)*epssil/value(locv+13)
c... enter here from ga-as processing also
value(locv+30)=pb*(1.0d0-dexp((1.0d0-xm)*xfc))/(1.0d0-xm)
value(locv+31)=dexp((1.0d0+xm)*xfc)
value(locv+32)=1.0d0-fc*(1.0d0+xm)
490 value(locv+24)=2.5d+05*dexp(value(locv+2)/1.3d0)
value(locv+25)=5.0d+06*dexp(-value(locv+4)/vt)
value(locv+26)=3.9d-12*dsqrt(value(locv+5)*(value(locv+3)-
value(locv+28)=value(locv+26)*(1.0d0-dsqrt((value(locv+3)-
1 0.99999d0*value(locv+1))/(value(locv+3)-value(locv+1))))
c reserve additional nodes
c convert mosfet geometries to cm
610 if (loc.eq.0) go to 700
if (value(locm+2).eq.0.0d0) go to 620
620 nodplc(loc+4)=nodplc(loc+2)
710 if (loc.eq.0) go to 800
c put substrate node into nodplc(loc+30)
nodplc(loc+30)=nodplc(loc+5)
if(value(locm+16).eq.0.0d0) go to 720
720 nodplc(loc+6)=nodplc(loc+3)
730 if (value(locm+20).eq.0.0d0) go to 740
740 nodplc(loc+5)=nodplc(loc+2)
750 if (value(locm+19).eq.0.0d0) go to 760
760 nodplc(loc+7)=nodplc(loc+4)
810 if (loc.eq.0) go to 900
if (value(locm+4).eq.0.0d0) go to 820
820 nodplc(loc+5)=nodplc(loc+2)
830 if (value(locm+5).eq.0.0d0) go to 840
840 nodplc(loc+6)=nodplc(loc+4)
910 if (loc.eq.0) go to 1000
if(nodplc(locm+2).eq.0) go to 960
value(locv+1)=value(locv+1)*hndrd
value(locv+2)=value(locv+2)*hndrd
value(locv+3)=value(locv+3)*hndrd2
value(locv+4)=value(locv+4)*hndrd2
c... check that effective channel length is greater than zero
if((value(locv+1)-2.0d0*value(locm+20)).gt.0.0d0)
write(6,913) value(locv),value(locm)
913 format('0*error*: effective channel length of ',a8,' less than ',
1 'zero.',/' check value of ld for model ',a8)
914 if((value(locv+2)-2.0d0*value(locm+36)).gt.0.0d0) go to 916
write(6,915) value(locv),value(locm)
915 format('0*error*: effective channel width of ',a8,' less than ',
1 'zero.',/' check value of wd for model ',a8)
916 if (value(locv+11).eq.0.0d0) go to 917
value(locv+11)=1.0d0/value(locv+11)
917 if(value(locm+6).eq.0.0d0) go to 920
value(locv+11)=value(locm+6)
920 nodplc(loc+6)=nodplc(loc+2)
930 if (value(locv+12).eq.0.0d0) go to 931
value(locv+12)=1.0d0/value(locv+12)
931 if(value(locm+7).eq.0.0d0) go to 940
value(locv+12)=value(locm+7)
940 nodplc(loc+7)=nodplc(loc+4)
c.. special case for ga-as devices
c.. compute rd and rs if not specified on device card
c.. rd and rs are always non-zero.
req=1.25d+14/(value(locm+5)*value(locv+2))
if (value(locv+11).eq.0.0d0) value(locv+11)=req
value(locv+11)=1.0d0/value(locv+11)
if (value(locv+12).eq.0.0d0) value(locv+12)=req
value(locv+12)=1.0d0/value(locv+12)
1010 if (loc.eq.0) go to 2000
implicit double precision (a-h,o-z)
c this routine constructs the element node table. it also checks
c for voltage source/inductor loops, current source/capacitor cutsets,
c and that every node has a dc (conductive) path to ground.
common /tabinf/ ielmnt,isbckt,nsbckt,iunsat,nunsat,itemps,numtem,
1 isens,nsens,ifour,nfour,ifield,icode,idelim,icolum,insize,
2 junode,lsbkpt,numbkp,iorder,jmnode,iur,iuc,ilc,ilr,numoff,isr,
3 nmoffc,iseq,iseq1,neqn,nodevs,ndiag,iswap,iequa,macins,lvnim1,
4 lx0,lvn,lynl,lyu,lyl,lx1,lx2,lx3,lx4,lx5,lx6,lx7,ld0,ld1,ltd,
5 imynl,imvn,lcvn,loutpt,nsnod,nsmat,nsval,icnod,icmat,icval
common /miscel/ atime,aprog(3),adate,atitle(10),defl,defw,defad,
1 defas,rstats(50),iwidth,lwidth,nopage
common /cirdat/ locate(50),jelcnt(50),nunods,ncnods,numnod,nstop,
1 nut,nlt,nxtrm,ndist,ntlin,ibr,numvs
common /flags/ iprnta,iprntl,iprntm,iprntn,iprnto,limtim,limpts,
1 lvlcod,lvltim,itl1,itl2,itl3,itl4,itl5,igoof,nogo,keof
common /blank/ value(1000)
equivalence (value(1),nodplc(1),cvalue(1))
dimension atable(12),aide(20),nnods(20)
data toptit / 8helement , 8hnode tab, 8hle , 8h /
data idlist / 3, 6, 8, 9 /
data aide / 1hr,0.0d0,1hl,2*0.0d0,1he,0.0d0,1hh,1hv,0.0d0,1hd,
1 1hq,1hj,1hm,0.0d0,0.0d0,1ht,0.0d0,0.0d0,0.0d0 /
data nnods / 2,2,2,0,2,2,2,2,2,2,2,4,3,4,4,4,4,0,1,0 /
call getm4(iorder,ncnods)
1300 call getm4(itable,0)
if (nnods(id).eq.0) go to 1370
1320 if (loc.eq.0) go to 1370
call sizmem(nodplc(loc+2),jstop)
if (k.le.ispot) go to 1340
call copy4(nodplc(itable+ispot),nodplc(itable+ispot+1),k-ispot)
call copy4(nodplc(itabid+ispot),nodplc(itabid+ispot+1),k-ispot)
1340 nodplc(itable+ispot)=loc
c... treat the substrate node of a mosfet as if it were a transmission
c... line node, i.e. let it dangle if desired
if(id.eq.14.and.j.eq.4) nodplc(itabid+ispot)=17
if (k.gt.kstop) go to 1360
nodplc(iur+k)=nodplc(iur+k)+1
c check that every node has a dc path to ground
call zero4(nodplc(iorder+1),ncnods)
if (nodplc(iorder+i).eq.1) go to 1470
if (jstart.gt.jstop) go to 1470
if (aide(id).eq.0.0d0) go to 1450
if (nodplc(iorder+node).eq.1) go to 1460
1445 if (nodplc(loc+2).eq.i) node=nodplc(loc+3)
if (nodplc(loc+3).eq.i) node=nodplc(loc+2)
if (nodplc(loc+4).eq.i) node=nodplc(loc+5)
if (nodplc(loc+5).eq.i) node=nodplc(loc+4)
if (nodplc(iorder+node).eq.1) go to 1460
if (iflag.eq.1) go to 1420
c print node table and topology error messages
if (iprntn.eq.0) go to 1510
call title(0,lwidth,1,toptit)
if (iprntn.eq.0) go to 1550
if (jstart.le.jstop) go to 1520
write (6,1511) nodplc(junode+i)
if (kntr.lt.kntlim) go to 1540
if (jflag.eq.0) go to 1525
write (6,1521) nodplc(junode+i),(atable(k),k=1,kntr)
1521 format(1h0,i7,3x,12(1x,a8))
1525 write (6,1526) (atable(k),k=1,kntr)
1526 format(11x,12(1x,a8))
if (kntr.eq.0) go to 1550
if (jflag.eq.0) go to 1545
write (6,1521) nodplc(junode+i),(atable(k),k=1,kntr)
1545 write (6,1526) (atable(k),k=1,kntr)
1550 if (jstart-jstop) 1560,1552,1556
c allow node with only one connection iff element is a t-line
1552 if (nodplc(itabid+jstart).eq.17) go to 1560
write (6,1557) nodplc(junode+i)
1557 format('0*error*: less than 2 connections at node ',i6/)
1560 if (nodplc(iorder+i).eq.1) go to 1590
write (6,1561) nodplc(junode+i)
1561 format('0*error*: no dc path to ground from node ',i6/)
c check for inductor/voltage source loops
call zero4(nodplc(iorder+1),ncnods)
1610 if (loc.eq.0) go to 1690
if (nodplc(iorder+node1)) 1620,1640,1630
1620 nodplc(iorder+node1)=loc
1640 if (nodplc(iorder+node2)) 1650,1680,1660
1650 nodplc(iorder+node2)=loc
1670 if (nodplc(iorder+node).ne.0) go to 1710
write (6,1711) value(locv)
1711 format('0*error*: inductor/voltage source loop found, containing