Minor merge issues
This commit is contained in:
commit
d33b31b3a9
|
|
@ -0,0 +1,95 @@
|
|||
File: buggy-meas-tran.sp
|
||||
* Simple .measurement examples
|
||||
* transient simulation of two sine signals with different frequencies
|
||||
vac1 1 0 DC 0 sin(0 1 1k 0 0)
|
||||
R1 1 0 100k
|
||||
vac2 2 0 DC 0 sin(0 1.2 0.9k 0 0)
|
||||
.tran 10u 5m
|
||||
*
|
||||
.measure tra tdiff TRIG v(1) VAL=0.5 RISE=1 TARG v(1) VAL=0.5 RISE=2
|
||||
.measure tran tdiff RIG v(1) VAL=0.5 RISE=1 TARG v(1) VAL=0.5 RISE=3
|
||||
.measure tran tdiff TRIG v(1 VAL=0.5 RISE=1 TARG v(1) VAL=0.5 FALL=1
|
||||
.measure tran tdiff TRIG v(1) VAL FALL=3 TARG v(2) VAL=0 FALL=3
|
||||
.measure tran tdiff TRIG v(1) VAL=-0.6 CROS=1 TARG v(2) VAL=-0.8 CROSS=1
|
||||
.measure tran tdiff TRIG AT=1m TARG v(2) VAL -0.8 CROSS=3
|
||||
.measure tran teval WHE v(2)=0.7 CROSS=LAST
|
||||
.measure tran teval WHEN v(2)==v(1) FALL=LAST
|
||||
.measure tran teval WHEN v(1)!=v(2) CROSS=LAST
|
||||
.measure tran yeval FIND v(2) WHEN v(1)=0.2 FALL=2
|
||||
.measure tran yeval FIND v(2) AT=2 m
|
||||
.measure tran ymax MAX v(2) fro m=2m to=3m
|
||||
.measure tran tymax MAX_AT v(2) from=2m to=3m
|
||||
.measure tran ypp PP v(1) from=2m to=4m
|
||||
.measure tran yrms RMS v() from=2m to=3.5m
|
||||
.measure tran yavg AVG v(1) from 2m to=4m
|
||||
.measure tran yint INTER v(2) from=2m to=3m
|
||||
.param fval=5
|
||||
.measure tran yadd param='fval + 7'
|
||||
.param vout_diff=50k
|
||||
.meas tran bw_chk param='(vout_diff < 100k) ? 1 : 0'
|
||||
.measure tran vtest find par('v(2)*v(1)') AT=2.3m
|
||||
*
|
||||
.control
|
||||
echo
|
||||
echo **** buggy .measure lines
|
||||
run
|
||||
*plot v(1) v(2)
|
||||
*plot i(vac1)
|
||||
|
||||
echo
|
||||
echo **** good meas lines
|
||||
meas tran tdiff TRIG v(1) VAL=0.5 RISE=1 TARG v(1) VAL=0.5 RISE=2
|
||||
meas tran tdiff TRIG v(1) VAL=0.5 RISE=1 TARG v(1) VAL=0.5 RISE=3
|
||||
meas tran tdiff TRIG v(1) VAL=0.5 RISE=1 TARG v(1) VAL=0.5 FALL=1
|
||||
meas tran tdiff TRIG v(1) VAL=0 FALL=3 TARG v(2) VAL=0 FALL=3
|
||||
meas tran tdiff TRIG v(1) VAL=-0.6 CROSS=1 TARG v(2) VAL=-0.8 CROSS=1
|
||||
meas tran tdiff TRIG AT=1m TARG v(2) VAL=-0.8 CROSS=3
|
||||
meas tran teval WHEN v(2)=0.7 CROSS=LAST
|
||||
meas tran teval WHEN v(2)=v(1) FALL=LAST
|
||||
meas tran teval WHEN v(1)=v(2) CROSS=LAST
|
||||
meas tran yeval FIND v(2) WHEN v(1)=0.2 FALL=2
|
||||
meas tran yeval FIND v(2) AT=2m
|
||||
meas tran ymax MAX v(2) from=2m to=3m
|
||||
meas tran tymax MAX_AT v(2) from=2m to=3m
|
||||
meas tran ypp PP v(1) from=2m to=4m
|
||||
meas tran yrms RMS v(1) from=2m to=3.5m
|
||||
meas tran yavg AVG v(1) from=2m to=4m
|
||||
meas tran yint INTEG v(2) from=2m to=3m
|
||||
meas tran ymax MAX v(2) from=2m to=3m
|
||||
meas tran tmax WHEN v(2)=YMAX from=1m to=2m
|
||||
|
||||
echo
|
||||
echo **** out of intervall examples
|
||||
meas tran tdiff TRIG v(1) VAL=0.5 RISE=1 TARG v(1) VAL=0.5 RISE=25
|
||||
meas tran tdiff TRIG v(1) VAL=0.5 RISE=3 TARG v(1) VAL=0.5 RISE=2
|
||||
meas tran teval WHEN v(2)=70 CROSS=LAST
|
||||
meas tran yeval FIND v(2) AT=2
|
||||
|
||||
echo
|
||||
echo **** buggy input lines
|
||||
meas tran tdiff TRIG v(1) VAL=0.5 RISE=1 TARG v(1) VAL=0.5 RISE=2
|
||||
meas tran tdiff TRIG v(1) VAL=0.5 RISE=1 TARG v(1) VAL=0.5
|
||||
meas tran tdiff TRIG v(1) VAL=0.5 RISE=1 TARG v(1)
|
||||
meas tran tdiff TRIG v(1) VAL=0.5 RISE=1 TARG
|
||||
meas tran tdiff TRIG v(1) VAL=0.5 RISE=1
|
||||
meas tran tdiff TRIG v(1) VAL=0.5
|
||||
meas tran tdiff TRIG v(1)
|
||||
meas tran tdiff TRIG
|
||||
meas tran tdiff
|
||||
meas tran
|
||||
meas
|
||||
echo
|
||||
echo **** more buggy lines
|
||||
meas tran tdiff TRIG v(1) VAL=0.5 RISE=1 TARG v(1) VAL=0.5 RISE=2
|
||||
meas tran TRIG v(1) VAL=0.5 RISE=1 TARG v(1) VAL=0.5 RISE=2
|
||||
meas tran tdiff v(1) VAL=0.5 RISE=1 TARG v(1) VAL=0.5 RISE=2
|
||||
meas tran tdiff TRIG VAL=0.5 RISE=1 TARG v(1) VAL=0.5 RISE=2
|
||||
meas tran tdiff TRIG v(1) RISE=1 TARG v(1) VAL=0.5 RISE=2
|
||||
meas tran tdiff TRIG v(1) VAL=0.5 TARG v(1) VAL=0.5 RISE=2
|
||||
meas tran tdiff TRIG v(1) VAL=0.5 RISE=1 v(1) VAL=0.5 RISE=2
|
||||
meas tran tdiff TRIG v(1) VAL=0.5 RISE=1 TARG VAL=0.5 RISE=2
|
||||
meas tran tdiff TRIG v(1) VAL=0.5 RISE=1 TARG v(1) RISE=2
|
||||
meas tran tdiff TRIG v(1) VAL= RISE=1 TARG v(1) VAL=0.5 RISE=2
|
||||
meas tran tdiff TRIG v(1) VAL=0.5 RISE= TARG v(1) VAL=0.5 RISE=2
|
||||
.endc
|
||||
.end
|
||||
|
|
@ -19,7 +19,6 @@ Rfb ino outo 3k
|
|||
vin in 0 DC 0 PULSE(-0.5 0.5 2uS 200NS 200NS 5uS 10uS)
|
||||
.tran 100n 10u
|
||||
|
||||
.options vntol=10u
|
||||
.control
|
||||
run
|
||||
plot v(in) v(outo)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,115 @@
|
|||
100W VDMOS power amplifier
|
||||
*100W into 8Ω at less than .1% THD
|
||||
*72° phase margin @ 950kHz
|
||||
*Adjust R7 for 15mA quiescent current through Q1/Q2
|
||||
*R24 & R25 are optional output offset trimming
|
||||
*
|
||||
VTamb tamb 0 25
|
||||
MQ1 +V N010 N012 tn tcn IRFP240 tnodeout
|
||||
X1 tcn tamb case-ambient
|
||||
MQ2 -V N020 N017 tp tcp IRFP9240 tnodeout
|
||||
X2 tcp tamb case-ambient
|
||||
R1 OUT N017 .33
|
||||
R2 N012 OUT .33
|
||||
C1 OUT N016 100n
|
||||
R3 N016 0 10
|
||||
R4 N010 N009 470
|
||||
R5 N020 N019 470
|
||||
V1 +V 0 50
|
||||
V2 0 -V 50
|
||||
Q3 N009 N006 N005 0 MJE350
|
||||
Q4 N006 N006 N004 0 MJE350
|
||||
R6 +V N005 100
|
||||
R7 N009 N019 820
|
||||
Q5 N019 N023 N024 0 MJE340
|
||||
R8 +V N004 100
|
||||
R9 N024 -V 100
|
||||
Q6 N022 N021 N024 0 MJE340
|
||||
C2 N023 N019 18p
|
||||
C3 N022 N021 18p
|
||||
R10 N006 N022 10K
|
||||
Q7 N023 N015 N008 0 MJE350
|
||||
Q8 N021 N011 N008 0 MJE350
|
||||
R13 N023 -V 3.9K
|
||||
R14 N021 -V 3.9K
|
||||
Q9 N008 N003 N001 0 MJE350
|
||||
R15 +V N001 470
|
||||
R16 N002 N001 1K
|
||||
Q10 N003 N002 +V 0 MJE350
|
||||
R17 N003 N007 10K
|
||||
R18 N007 0 10K
|
||||
C4 +V N007 47u
|
||||
R19 OUT1 N011 27K
|
||||
R20 N011 N018 1K
|
||||
C5 N018 0 100u
|
||||
C6 N015 0 330p
|
||||
R21 N015 N014 2.2K
|
||||
R22 N014 0 47K
|
||||
C7 N014 N013 2.2u
|
||||
Vin N013 0 ac 0 dc 0 SINE(0 {V} 1K)
|
||||
RLOAD OUT 0 8
|
||||
R24 +V N011 3.7Meg
|
||||
R25 N011 -V 6.1Meg
|
||||
V3 OUT OUT1 dc 0 ac 1
|
||||
C8 OUT1 N011 3p
|
||||
*
|
||||
.param V=1.44 ; 100W RMS
|
||||
.save @r1[i] @r2[i] v(out1) v(out) @rload[i] v(tn) v(tp) v(tcn) v(tcp) inoise_spectrum
|
||||
.control
|
||||
op
|
||||
print v(out) @r1[i] @r2[i]
|
||||
ac dec 100 10 1Meg
|
||||
plot db(V(out)/V(out1))
|
||||
set units=degrees
|
||||
plot ph(V(out)/V(out1))
|
||||
tran 1u 1000m
|
||||
fourier 1K V(out)
|
||||
plot v(out)*@rload[i]
|
||||
settype temperature v(tn) v(tp) v(tcn) v(tcp)
|
||||
plot v(tn) v(tp) v(tcn) v(tcp)
|
||||
linearize v(out)
|
||||
fft v(out)
|
||||
plot db(v(out)) xlimit 0 20k
|
||||
alter v3 ac = 0
|
||||
alter vin ac = 1
|
||||
noise V(out) Vin dec 10 10 100K
|
||||
setplot noise2
|
||||
plot inoise_spectrum
|
||||
.endc
|
||||
*
|
||||
.model IRFP240 VDMOS nchan
|
||||
+ Vto=4 Kp=5.9 Lambda=.001 Theta=0.015 ksubthres=.27
|
||||
+ Rd=61m Rs=18m Rg=3 Rds=1e7
|
||||
+ Cgdmax=2.45n Cgdmin=10p a=0.3 Cgs=1.2n
|
||||
+ Is=60p N=1.1 Rb=14m XTI=3
|
||||
+ Cjo=1.5n Vj=0.8 m=0.5
|
||||
+ tcvth=0.0065 MU=-1.27 texp0=1.5
|
||||
+ Rthjc=0.4 Cthj=5e-3
|
||||
+ mtriode=0.8
|
||||
.model IRFP9240 VDMOS pchan
|
||||
+ Vto=-4 Kp=8.8 Lambda=.003 Theta=0.08 ksubthres=.35
|
||||
+ Rd=180m Rs=50m Rg=3 Rds=1e7
|
||||
+ Cgdmax=1.25n Cgdmin=50p a=0.23 Cgs=1.15n
|
||||
+ Is=150p N=1.3 Rb=16m XTI=2
|
||||
+ Cjo=1.3n Vj=0.8 m=0.5
|
||||
+ tcvth=0.004 MU=-1.27 texp0=1.5
|
||||
+ Rthjc=0.4 Cthj=5e-3
|
||||
+ mtriode=0.6
|
||||
*
|
||||
.model MJE340 NPN(Is=1.03431e-13 BF=172.974 NF=.939811 VAF=27.3487 IKF=0.0260146 ISE=4.48447e-11 Ne=1.61605 Br=16.6725
|
||||
+ Nr=0.796984 VAR=6.11596 IKR=0.10004 Isc=9.99914e-14 Nc=1.99995 RB=1.47761 IRB=0.2 RBM=1.47761 Re=0.0001 RC=1.42228
|
||||
+ XTB=2.70726 XTI=1 Eg=1.206 CJE=1e-11 VJE=0.75 Mje=.33 TF=1e-09 XTF=1 VTF=10 ITF=0.01 CJC=1e-11 VJC=.75 MJC=0.33 XCJC=.9
|
||||
+ Fc=0.5 CJS=0 VJS=0.75 MJS=0.5 TR=1e-07 PTF=0 KF=1e-15 AF=1)
|
||||
.model MJE350 PNP(Is=6.01619e-15 BF=157.387 NF=.910131 VAF=23.273 IKF=0.0564808 Ise=4.48479e-12 Ne=1.58557 BR=0.1
|
||||
+ NR=1.03823 VAR=4.14543 IKR=.0999978 ISC=1.00199e-13 Nc=1.98851 RB=.1 IRB=0.202965 RBM=0.1 Re=.0710678 Rc=.355339
|
||||
+ XTB=1.03638 XTI=3.8424 Eg=1.206 Cje=1e-11 Vje=0.75 Mje=0.33 TF=1e-09 XTF=1 VTF=10 ITF=0.01 Cjc=1e-11 Vjc=0.75
|
||||
+ Mjc=0.33 XCJC=0.9 Fc=0.5 Cjs=0 Vjs=0.75 Mjs=0.5 TR=1e-07 PTF=0 KF=1e-15 AF=1)
|
||||
*
|
||||
.subckt case-ambient case amb
|
||||
rcs case 1 0.1
|
||||
csa 1 0 30m
|
||||
rsa 1 amb 1.3
|
||||
.ends
|
||||
|
||||
.end
|
||||
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
VDMOS wingspread plot example
|
||||
|
||||
M1 +V N004 N005 IRFP240
|
||||
M2 -V N009 N007 IRFP9240
|
||||
R1 OUT N007 .33
|
||||
R2 N005 OUT .33
|
||||
R4 N004 N003 470
|
||||
R5 N009 N008 470
|
||||
V1 +V 0 50
|
||||
V2 0 -V 50
|
||||
Q3 -V N011 N008 0 MJE350
|
||||
R7 N003 N008 870
|
||||
Q5 +V N002 N003 0 MJE340
|
||||
Vin N006 0 0
|
||||
RLoad OUT 0 r = 8
|
||||
V3 N001 N006 4.8
|
||||
V4 N006 N010 4.8
|
||||
I1 +V N001 12m
|
||||
I2 N010 -V 12m
|
||||
R3 N002 N001 10
|
||||
R8 N011 N010 10
|
||||
*
|
||||
.save all @r1[i] @r2[i] v(out) @rload[i]
|
||||
.control
|
||||
|
||||
let gain=vector(2005)
|
||||
reshape gain [5][401]
|
||||
let irload=vector(2005)
|
||||
reshape irload [5][401]
|
||||
|
||||
let offset = 0.05
|
||||
|
||||
foreach Rl 4 6 8
|
||||
|
||||
setplot new
|
||||
set curplottitle = "wingspread $Rl Ohm"
|
||||
set plotname=$curplot
|
||||
|
||||
alter Rload r = $Rl
|
||||
|
||||
let index = 0
|
||||
|
||||
foreach vbias 4.7 4.8 4.9 5.0 5.1
|
||||
alter v3 dc = $vbias + offset
|
||||
alter v4 dc = $vbias - offset
|
||||
op
|
||||
print v(out) @r1[i] @r2[i]
|
||||
dc vin -20 20 0.1
|
||||
set dcplotname = $curplot
|
||||
setplot $plotname
|
||||
let gain[index] = deriv({$dcplotname}.out)
|
||||
let irload[index] = {$dcplotname}.@rload[i]
|
||||
let index = index + 1
|
||||
destroy $dcplotname
|
||||
end
|
||||
|
||||
settype current irload
|
||||
plot gain[0] gain[1] gain[2] gain[3] gain[4] vs irload[2]
|
||||
|
||||
end
|
||||
|
||||
.endc
|
||||
*
|
||||
.model IRFP240 VDMOS nchan
|
||||
+ Vto=4 Kp=5.9 Lambda=.001 Theta=0.015 ksubthres=.27
|
||||
+ Rd=61m Rs=18m Rg=3 Rds=1e7
|
||||
+ Cgdmax=2.45n Cgdmin=10p a=0.3 Cgs=1.2n
|
||||
+ Is=60p N=1.1 Rb=14m XTI=3
|
||||
+ Cjo=1.5n Vj=0.8 m=0.5
|
||||
+ tcvth=0.0065 MU=-1.27 texp0=1.5
|
||||
*+ Rthjc=0.4 Cthj=5e-3
|
||||
+ mtriode=0.8
|
||||
.model IRFP9240 VDMOS pchan
|
||||
+ Vto=-4 Kp=8.8 Lambda=.003 Theta=0.08 ksubthres=.35
|
||||
+ Rd=180m Rs=50m Rg=3 Rds=1e7
|
||||
+ Cgdmax=1.25n Cgdmin=50p a=0.23 Cgs=1.15n
|
||||
+ Is=150p N=1.3 Rb=16m XTI=2
|
||||
+ Cjo=1.3n Vj=0.8 m=0.5
|
||||
+ tcvth=0.004 MU=-1.27 texp0=1.5
|
||||
*+ Rthjc=0.4 Cthj=5e-3
|
||||
+ mtriode=0.6
|
||||
*
|
||||
.model MJE340 NPN(Is=1.03431e-13 BF=172.974 NF=.939811 VAF=27.3487 IKF=0.0260146 ISE=4.48447e-11 Ne=1.61605 Br=16.6725
|
||||
+ Nr=0.796984 VAR=6.11596 IKR=0.10004 Isc=9.99914e-14 Nc=1.99995 RB=1.47761 IRB=0.2 RBM=1.47761 Re=0.0001 RC=1.42228
|
||||
+ XTB=2.70726 XTI=1 Eg=1.206 CJE=1e-11 VJE=0.75 Mje=.33 TF=1e-09 XTF=1 VTF=10 ITF=0.01 CJC=1e-11 VJC=.75 MJC=0.33 XCJC=.9
|
||||
+ Fc=0.5 CJS=0 VJS=0.75 MJS=0.5 TR=1e-07 PTF=0 KF=0 AF=1)
|
||||
.model MJE350 PNP(Is=6.01619e-15 BF=157.387 NF=.910131 VAF=23.273 IKF=0.0564808 Ise=4.48479e-12 Ne=1.58557 BR=0.1
|
||||
+ NR=1.03823 VAR=4.14543 IKR=.0999978 ISC=1.00199e-13 Nc=1.98851 RB=.1 IRB=0.202965 RBM=0.1 Re=.0710678 Rc=.355339
|
||||
+ XTB=1.03638 XTI=3.8424 Eg=1.206 Cje=1e-11 Vje=0.75 Mje=0.33 TF=1e-09 XTF=1 VTF=10 ITF=0.01 Cjc=1e-11 Vjc=0.75
|
||||
+ Mjc=0.33 XCJC=0.9 Fc=0.5 Cjs=0 Vjs=0.75 Mjs=0.5 TR=1e-07 PTF=0 KF=0 AF=1)
|
||||
*
|
||||
.end
|
||||
|
|
@ -36,7 +36,7 @@ plot dc3.vs2#branch vs2#branch
|
|||
+ VTO=4 KP=15
|
||||
+ Lambda=3m $ will be reset by altermod to original 2m
|
||||
+ Mtriode=0.4
|
||||
+ subslope=120m
|
||||
+ Ksubthres=120m
|
||||
+ subshift=160m
|
||||
+ Rs=5m Rd=10m Rds=200e6
|
||||
+ Cgdmax=9000p Cgdmin=300p A=0.25
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
Capacitance and current comparison between models d and bulk diode in vdmos
|
||||
|
||||
D1 ad kd dio
|
||||
.model dio d TT=1371n IS=2.13E-08 N=1.564 RS=0.0038 m=0.548 Vj=0.1 Cjo=3200pF
|
||||
|
||||
Va ad 0 DC 0.5 AC 1 $ DC -20
|
||||
Vk kd 0 0
|
||||
|
||||
m1 d g s IXTP6N100D2
|
||||
.MODEL IXTP6N100D2 VDMOS(KP=2.9 RS=0.1 RD=1.3 RG=1 VTO=-2.7 LAMBDA=0.03 CGDMAX=3000p CGDMIN=2p CGS=2915p a=1 TT=1371n IS=2.13E-08 N=1.564 RB=0.0038 m=0.548 Vj=0.1 Cjo=3200pF ksubthres=0.1 subslope=43m subshift=-25m)
|
||||
|
||||
Vd d 0 DC -0.5 AC 1 $ DC 20
|
||||
Vg g 0 -5 $ transistor is off
|
||||
Vs s 0 0
|
||||
|
||||
.ac dec 10 1 100K
|
||||
|
||||
.control
|
||||
save @d1[id] @m1[id] all
|
||||
run
|
||||
plot mag(i(Vs)) mag (i(Vk))
|
||||
plot ph(i(Vs)) ph(i(Vk))
|
||||
.endc
|
||||
|
||||
.end
|
||||
|
|
@ -3,25 +3,27 @@ Capacitance and current comparison between models d and bulk diode in vdmos
|
|||
D1 ad kd dio
|
||||
.model dio d TT=1371n IS=2.13E-08 N=1.564 RS=0.0038 m=0.548 Vj=0.1 Cjo=3200pF
|
||||
|
||||
Va ad 0 dc 0 pwl(0 -2 2.5 0.5)
|
||||
Va ad 0 ac 1 dc 0.5 pwl(0 -2 2.5 0.5)
|
||||
Vk kd 0 0
|
||||
|
||||
m1 d g s IXTP6N100D2
|
||||
.MODEL IXTP6N100D2 VDMOS(KP=2.9 RS=0.1 RD=1.3 RG=1 VTO=-2.7 LAMBDA=0.03 CGDMAX=3000p CGDMIN=2p CGS=2915p a=1 TT=1371n IS=2.13E-08 N=1.564 RB=0.0038 m=0.548 Vj=0.1 Cjo=3200pF ksubthres=0.1)
|
||||
|
||||
Vd d 0 dc 0 pwl(0 2 2.5 -0.5)
|
||||
Vd d 0 ac 1 dc -0.5 pwl(0 2 2.5 -0.5)
|
||||
Vg g 0 -5 $ transistor is off
|
||||
Vs s 0 0
|
||||
|
||||
.tran 10m 2.5
|
||||
|
||||
.control
|
||||
save @d1[cd] @m1[cds] all
|
||||
run
|
||||
save all @d1[id] @m1[id] @d1[cd] @m1[cds] all
|
||||
tran 10m 2.5
|
||||
plot abs(i(Vk)) abs(i(Vs)) ylog
|
||||
plot @d1[cd] @m1[cds]
|
||||
*plot abs(i(Vk)) - abs(i(Vs))
|
||||
*plot @d1[cd] - @m1[cds]
|
||||
|
||||
ac dec 10 1 100K
|
||||
plot mag(i(Vs)) mag (i(Vk))
|
||||
plot ph(i(Vs)) ph(i(Vk))
|
||||
.endc
|
||||
|
||||
.end
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
crss coss ciss
|
||||
*
|
||||
VP1 P1 0 PULSE(0 1.15m 100n 10n 10n 1 2)
|
||||
VP2 P4 0 PULSE(0 2.8m 100n 10n 10n 1 2)
|
||||
*
|
||||
M1 d1 g1 0 IRFP240
|
||||
V1 g1 0 0.0
|
||||
V2 1 d1 0.0
|
||||
G1 0 1 P1 0 1.04
|
||||
*
|
||||
M2 d2 0 d2 IRFP240
|
||||
V3 2 d2 0.0
|
||||
G2 0 2 P4 0 1.1
|
||||
*
|
||||
M3 d3 g3 0 IRFP9240
|
||||
V4 g3 0 0.0
|
||||
V5 3 d3 0.0
|
||||
G3 3 0 P1 0 0.85
|
||||
e1 d1p 0 d3 0 -1
|
||||
*
|
||||
M4 d4 0 d4 IRFP9240
|
||||
V6 4 d4 0.0
|
||||
G4 4 0 P4 0 1.0
|
||||
e2 d2p 0 d4 0 -1
|
||||
*
|
||||
.control
|
||||
tran 1n 25u
|
||||
*plot v(d1) v(d2) v(d3) v(d4)
|
||||
|
||||
plot 'i(v1)/deriv(v(d1))' 'i(v2)/deriv(v(d1))' vs v(d1) xlog xlimit 1 100 ylimit 0 3n title "IRFP240 crss & coss"
|
||||
plot 'i(v3)/deriv(v(d2))' vs v(d2) xlog xlimit 1 100 ylimit 0 3n title "IRFP240 ciss"
|
||||
|
||||
plot 'i(v4)/deriv(v(d3))' 'i(v5)/deriv(v(d3))' vs v(d1p) xlog xlimit 1 100 ylimit 0 3n title "IRFP9240 crss & coss"
|
||||
plot 'i(v6)/deriv(v(d4))' vs v(d2p) xlog xlimit 1 100 ylimit 0 3n title "IRFP9240 ciss"
|
||||
|
||||
.endc
|
||||
.model IRFP240 VDMOS nchan
|
||||
+ Vto=4 Kp=5.9 Lambda=.001 Theta=0.015 ksubthres=.27
|
||||
+ Rd=61m Rs=18m Rg=3 Rds=1e7
|
||||
+ Cgdmax=2.45n Cgdmin=10p a=0.3 Cgs=1.2n
|
||||
+ Is=60p N=1.1 Rb=14m XTI=3
|
||||
+ Cjo=1.5n Vj=0.8 m=0.5
|
||||
+ tcvth=0.0065 MU=-1.27 texp0=1.5
|
||||
*+ Rthjc=0.4 Cthj=5e-3
|
||||
+ mtriode=0.8
|
||||
.model IRFP9240 VDMOS pchan
|
||||
+ Vto=-4 Kp=8.8 Lambda=.003 Theta=0.08 ksubthres=.35
|
||||
+ Rd=180m Rs=50m Rg=3 Rds=1e7
|
||||
+ Cgdmax=1.25n Cgdmin=50p a=0.23 Cgs=1.15n
|
||||
+ Is=150p N=1.3 Rb=16m XTI=2
|
||||
+ Cjo=1.3n Vj=0.8 m=0.5
|
||||
+ tcvth=0.004 MU=-1.27 texp0=1.5
|
||||
*+ Rthjc=0.4 Cthj=5e-3
|
||||
+ mtriode=0.6
|
||||
.end
|
||||
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
Simple regulated DCDC step-up converter
|
||||
|
||||
V1 clock 0 PULSE(0 6 0 19u 1u 10n 20.01u)
|
||||
V2 ref 0 2.5
|
||||
R1 OUT outdiv 100K
|
||||
R2 0 outdiv 27k
|
||||
R3 outdiv x 10k
|
||||
C2 err x 50n
|
||||
B1 err 0 V = max(0,min(5,V(ref,x)*10k))
|
||||
B2 gate 0 V = max(0,min(5,V(err,clock)*1k))
|
||||
V3 +V 0 5.0
|
||||
L1 +V lx 220u
|
||||
RL lx out1 125m
|
||||
M1 out1 gate 0 IRF510
|
||||
D1 out1 OUT MBRS340
|
||||
C1 OUT cx 33u
|
||||
RC cx 0 50m
|
||||
R4 out2 OUT R = (time<12ms ? {Rload} : time<20ms ? {Rload/2} : {2*Rload})
|
||||
V4 out2 0 0.0
|
||||
|
||||
.param Rload=100
|
||||
|
||||
.model IRF510 VDMOS nchan
|
||||
+ Vto=3.6 Kp=1.3 Lambda=.001 Theta=0.07 ksubthres=.1
|
||||
+ Rg=3 Rd=200m Rs=54m Rds=1e7
|
||||
+ Cgdmax=.2n Cgdmin=.05n a=0.3 Cgs=.12n
|
||||
+ Is=17p N=1.1 Rb=80m XTI=3
|
||||
+ Cjo=.25n Vj=0.8 m=0.5
|
||||
+ tcvth=0.007 MU=-1.27 texp0=1.5
|
||||
|
||||
.model MBRS340 D(Is=22.6u Rs=.042 N=1.094 Cjo=480p M=.61 Eg=.69 Xti=2)
|
||||
|
||||
.control
|
||||
listing e
|
||||
option method=gear
|
||||
tran 10n 30m 0 5n
|
||||
* write dcdc.raw
|
||||
plot v(err) v(clock) v(gate) v(out)
|
||||
plot -i(V3) i(V4) ylimit 0 1
|
||||
rusage all
|
||||
.endc
|
||||
|
||||
.end
|
||||
|
|
@ -1,20 +1,22 @@
|
|||
*****************==== Inverter ====*******************
|
||||
*********** VDMOS ****************************
|
||||
vdd 1 0 5
|
||||
vss 4 0 0
|
||||
|
||||
.subckt inv out in vdd vss
|
||||
mp1 out in vdd p1
|
||||
mn1 out in vss n1
|
||||
.ends
|
||||
|
||||
xinv 3 2 1 0 inv
|
||||
xinv 3 2 1 4 inv
|
||||
|
||||
Vin 2 0 Pulse (0 5 10n 10n 10n 140n 300n)
|
||||
|
||||
.tran 1n 1u
|
||||
Vin 2 0 DC 0 Pulse (0 5 10n 10n 10n 140n 300n)
|
||||
|
||||
.control
|
||||
run
|
||||
dc Vin 0 5 0.05
|
||||
* current and output in a single plot
|
||||
plot v(2) v(3) vss#branch
|
||||
tran 1n 1u
|
||||
* current and output in a single plot
|
||||
plot v(2) v(3)
|
||||
.endc
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
*****************==== Inverter ====*******************
|
||||
*********** VDMOS inverter dc ****************************
|
||||
vdd 1 0 5
|
||||
vss 4 0 0
|
||||
|
||||
.subckt inv out in vdd vss
|
||||
mp1 out in vdd p1
|
||||
mn1 out in vss n1
|
||||
.ends
|
||||
|
||||
xinv 3 2 1 4 inv
|
||||
|
||||
Vin 2 0 0
|
||||
|
||||
.dc Vin 0 5 0.05
|
||||
|
||||
.control
|
||||
run
|
||||
* current and output in a single plot
|
||||
plot v(2) v(3) vss#branch
|
||||
.endc
|
||||
|
||||
.model N1 vdmos cgdmin=0.2p cgdmax=1p a=2 cgs=0.5p rg=5k
|
||||
.model P1 vdmos cgdmin=0.2p cgdmax=1p a=2 cgs=0.5p rg=5k pchan
|
||||
.end
|
||||
|
|
@ -18,8 +18,8 @@ xinv7 9 8 1 0 inv
|
|||
xinv8 10 9 1 0 inv
|
||||
xinv9 2 10 1 0 inv
|
||||
|
||||
.model N1 vdmos cgdmin=0.05p cgdmax=0.2p a=1.2 cgs=0.15p rg=10 kp=2e-5 rb=1e7 cjo=1n subslope=0.2
|
||||
.model P1 vdmos cgdmin=0.05p cgdmax=0.2p a=1.2 cgs=0.15p rg=10 kp=2e-5 rb=1e7 cjo=1n pchan subslope=0.2
|
||||
.model N1 vdmos cgdmin=0.05p cgdmax=0.2p a=1.2 cgs=0.15p rg=10 kp=2e-5 rb=1e7 cjo=1n ksubthres=0.2
|
||||
.model P1 vdmos cgdmin=0.05p cgdmax=0.2p a=1.2 cgs=0.15p rg=10 kp=2e-5 rb=1e7 cjo=1n pchan ksubthres=0.2
|
||||
|
||||
.tran 0.1n 1u
|
||||
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
VDMOS self heating test
|
||||
M1 D G 0 tj tc IRFP240 tnodeout
|
||||
rthk tc 0 0.05
|
||||
VG G 0 5V Pulse 0 10 0 1m 1m 100m 200m
|
||||
*RD D D1 4
|
||||
VD D 0 2V
|
||||
.model IRFP240 VDMOS nchan
|
||||
+ Vto=4 Kp=5.9 Lambda=.001 Theta=0.015 ksubthres=.27
|
||||
+ Rd=61m Rs=18m Rg=3 Rds=1e7
|
||||
+ Cgdmax=2.45n Cgdmin=10p a=0.3 Cgs=1.2n
|
||||
+ Is=60p N=1.1 Rb=14m XTI=3
|
||||
+ Cjo=1.5n Vj=0.8 m=0.5
|
||||
+ tcvth=0.0065 MU=-1.27 texp0=1.5
|
||||
+ Rthjc=0.02 Cthj=1e-3 Rthca=100
|
||||
+ mtriode=0.8
|
||||
.control
|
||||
dc vd 0.1 50 .1 vg 5 13 2
|
||||
plot -i(vd)
|
||||
settype temperature v(tj) v(tc)
|
||||
plot v(tj) v(tc)
|
||||
*tran 1m 0.01
|
||||
*plot v(d) v(g)
|
||||
.endc
|
||||
.end
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
VDMOS SOA check
|
||||
|
||||
.model IRFP240 VDMOS nchan
|
||||
+ Vto=4 Kp=5.9 Lambda=.001 Theta=0.015 ksubthres=.27
|
||||
+ Rd=61m Rs=18m Rg=3 Rds=1e7
|
||||
+ Cgdmax=2.45n Cgdmin=10p a=0.3 Cgs=1.2n
|
||||
+ Is=60p N=1.1 Rb=14m Cjo=1.5n XTI=3
|
||||
+ tcvth=0.0065 MU=-1.27 texp0=1.5
|
||||
+ mtriode=0.8
|
||||
+ Vgs_max=20 Vgd_max=20 Vds_max=200
|
||||
|
||||
vd1 d1 0 dc 0.1
|
||||
vg1 g1 0 dc 0.0
|
||||
vs1 s1 0 dc 0.0
|
||||
m1 d1 g1 s1 IRFP240
|
||||
|
||||
.model IRFP9240 VDMOS pchan
|
||||
+ Vto=-4 Kp=8.8 Lambda=.003 Theta=0.08 ksubthres=.35
|
||||
+ Rd=180m Rs=50m Rg=3 Rds=1e7
|
||||
+ Cgdmax=1.25n Cgdmin=50p a=0.23 Cgs=1.15n
|
||||
+ Is=150p N=1.3 Rb=16m Cjo=1.3n XTI=2
|
||||
+ tcvth=0.004 MU=-1.27 texp0=1.5
|
||||
+ mtriode=0.6
|
||||
+ Vgs_max=20 Vgd_max=20 Vds_max=200
|
||||
|
||||
vd2 0 d2 dc 0.1
|
||||
vg2 0 g2 dc 0.0
|
||||
vs2 0 s2 dc 0.0
|
||||
m2 d2 g2 s2 IRFP9240
|
||||
|
||||
.options warn=1 maxwarns=6
|
||||
|
||||
.control
|
||||
dc vd1 -1 210 1 vg1 5 25 5
|
||||
plot -i(vd1)
|
||||
dc vd2 -1 210 1 vg2 5 25 5
|
||||
plot i(vd2)
|
||||
.endc
|
||||
|
||||
.end
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
VDMOS output
|
||||
|
||||
m1 d g s n1
|
||||
*.model n1 vdmos rb=0.05 is=10n kp=2 bv=12 rd=0.1
|
||||
.model N1 vdmos vto=1 cgdmin=0.05p cgdmax=0.2p a=1.2 cgs=0.15p rg=10 kp=2e-4 rb=1e4 is=1e-9 bv=12 cjo=1p subslope=0.1
|
||||
|
||||
vd d 0 1
|
||||
vg g 0 1
|
||||
vs s 0 0
|
||||
|
||||
.control
|
||||
dc vd -2 15 0.05 vg 0 5 1
|
||||
plot vs#branch
|
||||
dc vg 0 5 0.05 vd 0.5 2.5 0.5
|
||||
plot vs#branch ylog
|
||||
.endc
|
||||
|
||||
.end
|
||||
|
|
@ -2,17 +2,17 @@ VDMOS output
|
|||
|
||||
m1 d g s IRFZ48Z
|
||||
|
||||
.model IRFZ48Z VDMOS (Rg = 1.77 Vto=4 Rd=1.85m Rs=0.0m Rb=3.75m Kp=25 Cgdmax=2.1n Cgdmin=0.05n Cgs=1.8n Cjo=0.55n Is=2.5p tt=20n mfg=International_Rectifier Vds=55 Ron=8.6m Qg=43n)
|
||||
.model IRFZ48Z VDMOS (Rg = 1.77 Vto=4 Rd=1.85m Rs=0.0m Rb=3.75m Kp=25 Cgdmax=2.1n Cgdmin=0.05n Cgs=1.8n Cjo=0.55n Is=2.5p tt=20n ksubthres=0.1 mfg=International_Rectifier Vds=55 Ron=8.6m Qg=43n)
|
||||
|
||||
vd d 0 1
|
||||
vg g 0 1
|
||||
vs s 0 0
|
||||
|
||||
.dc vd -1 15 0.05 vg 3 7 1
|
||||
|
||||
.control
|
||||
run
|
||||
dc vd -1 15 0.05 vg 3 7 1
|
||||
plot vs#branch
|
||||
dc vg 2 7 0.05 vd 0.5 2.5 0.5
|
||||
plot vs#branch ylog
|
||||
.endc
|
||||
|
||||
.end
|
||||
|
|
@ -857,7 +857,7 @@ twoSideSpacing(double width, double hStart, double hEnd, double rWanted,
|
|||
double dSpaceT; /* Exact value of nSpaceT */
|
||||
double dDiff; /* Difference between dSpaceS & dSpaceE */
|
||||
double remaining; /* Length of span between hs and he */
|
||||
double rTempS, rTempE; /* For temporarily calc'ed ratios */
|
||||
double rTempS = 0.0, rTempE = 0.0; /* For temporarily calc'ed ratios */
|
||||
double hsLast, heLast; /* Used to ensure ratio is valid */
|
||||
double rConnect; /* " */
|
||||
double hMax, hMin; /* Max and min between hStart and hEnd */
|
||||
|
|
|
|||
|
|
@ -350,7 +350,7 @@ measure_extract_variables(char *line)
|
|||
* Function: process a WHEN measurement statement which has been
|
||||
* parsed into a measurement structure.
|
||||
* ----------------------------------------------------------------- */
|
||||
static void
|
||||
static int
|
||||
com_measure_when(
|
||||
MEASUREPTR meas /* in : parsed measurement structure */
|
||||
)
|
||||
|
|
@ -385,16 +385,16 @@ com_measure_when(
|
|||
|
||||
if (d == NULL) {
|
||||
fprintf(cp_err, "Error: no such vector as %s.\n", meas->m_vec);
|
||||
return;
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
if (has_d2 && (d2 == NULL)) {
|
||||
fprintf(cp_err, "Error: no such vector as %s.\n", meas->m_vec2);
|
||||
return;
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
if (dScale == NULL) {
|
||||
fprintf(cp_err, "Error: no scale vector.\n");
|
||||
return;
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
prevValue = 0.;
|
||||
|
|
@ -537,13 +537,13 @@ com_measure_when(
|
|||
* exit when we meet condition */
|
||||
// meas->m_measured = prevScaleValue + (value2 - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue);
|
||||
meas->m_measured = prevScaleValue + (prevValue2 - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue - value2 + prevValue2);
|
||||
return;
|
||||
return MEASUREMENT_OK;
|
||||
}
|
||||
if (measurement_pending) {
|
||||
if ((meas->m_cross == MEASURE_DEFAULT) && (meas->m_rise == MEASURE_DEFAULT) && (meas->m_fall == MEASURE_DEFAULT)) {
|
||||
/* user didn't request any option, return the first possible case */
|
||||
meas->m_measured = prevScaleValue + (prevValue2 - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue - value2 + prevValue2);
|
||||
return;
|
||||
return MEASUREMENT_OK;
|
||||
} else if ((meas->m_cross == MEASURE_LAST_TRANSITION) || (meas->m_rise == MEASURE_LAST_TRANSITION) || (meas->m_fall == MEASURE_LAST_TRANSITION)) {
|
||||
meas->m_measured = prevScaleValue + (prevValue2 - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue - value2 + prevValue2);
|
||||
/* no return - look for last */
|
||||
|
|
@ -577,13 +577,13 @@ com_measure_when(
|
|||
/* user requested an exact match of cross, rise, or fall
|
||||
* exit when we meet condition */
|
||||
meas->m_measured = prevScaleValue + (meas->m_val - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue);
|
||||
return;
|
||||
return MEASUREMENT_OK;
|
||||
}
|
||||
if (measurement_pending) {
|
||||
if ((meas->m_cross == MEASURE_DEFAULT) && (meas->m_rise == MEASURE_DEFAULT) && (meas->m_fall == MEASURE_DEFAULT)) {
|
||||
/* user didn't request any option, return the first possible case */
|
||||
meas->m_measured = prevScaleValue + (meas->m_val - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue);
|
||||
return;
|
||||
return MEASUREMENT_OK;
|
||||
} else if ((meas->m_cross == MEASURE_LAST_TRANSITION) || (meas->m_rise == MEASURE_LAST_TRANSITION) || (meas->m_fall == MEASURE_LAST_TRANSITION)) {
|
||||
meas->m_measured = prevScaleValue + (meas->m_val - prevValue) * (scaleValue - prevScaleValue) / (value - prevValue);
|
||||
/* no return - look for last */
|
||||
|
|
@ -603,6 +603,8 @@ com_measure_when(
|
|||
|
||||
if (init_measured_value)
|
||||
meas->m_measured = NAN;
|
||||
|
||||
return MEASUREMENT_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -611,7 +613,7 @@ com_measure_when(
|
|||
* parsed into a measurement structure. We make sure to interpolate
|
||||
* the value when appropriate.
|
||||
* ----------------------------------------------------------------- */
|
||||
static void
|
||||
static int
|
||||
measure_at(
|
||||
MEASUREPTR meas, /* in : parsed "at" data */
|
||||
double at /* in: time to perform measurement */
|
||||
|
|
@ -623,17 +625,23 @@ measure_at(
|
|||
struct dvec *d, *dScale;
|
||||
|
||||
psvalue = pvalue = 0;
|
||||
|
||||
if (meas->m_vec == NULL) {
|
||||
fprintf(stderr, "Error: Syntax error in meas line, missing vector\n");
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
d = vec_get(meas->m_vec);
|
||||
dScale = plot_cur->pl_scale;
|
||||
|
||||
if (d == NULL) {
|
||||
fprintf(cp_err, "Error: no such vector as %s.\n", meas->m_vec);
|
||||
return;
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
if (dScale == NULL) {
|
||||
fprintf(cp_err, "Error: no such vector time, frequency or dc.\n");
|
||||
return;
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
|
|
@ -670,10 +678,10 @@ measure_at(
|
|||
|
||||
if ((i > 0) && (psvalue <= at) && (svalue >= at)) {
|
||||
meas->m_measured = pvalue + (at - psvalue) * (value - pvalue) / (svalue - psvalue);
|
||||
return;
|
||||
return MEASUREMENT_OK;
|
||||
} else if (dc_check && (i > 0) && (psvalue >= at) && (svalue <= at)) {
|
||||
meas->m_measured = pvalue + (at - psvalue) * (value - pvalue) / (svalue - psvalue);
|
||||
return;
|
||||
return MEASUREMENT_OK;
|
||||
}
|
||||
|
||||
psvalue = svalue;
|
||||
|
|
@ -681,6 +689,7 @@ measure_at(
|
|||
}
|
||||
|
||||
meas->m_measured = NAN;
|
||||
return MEASUREMENT_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -690,7 +699,7 @@ measure_at(
|
|||
* the value here when we have m_from and m_to constraints * so this
|
||||
* function is slightly wrong. Need to fix in future rev.
|
||||
* ----------------------------------------------------------------- */
|
||||
static void
|
||||
static int
|
||||
measure_minMaxAvg(
|
||||
MEASUREPTR meas, /* in : parsed measurement data request */
|
||||
ANALYSIS_TYPE_T mFunctionType /* in: one of AT_AVG, AT_MIN, AT_MAX, AT_MIN_AT, AT_MAX_AT */
|
||||
|
|
@ -709,10 +718,15 @@ measure_minMaxAvg(
|
|||
meas->m_measured_at = NAN;
|
||||
first = 0;
|
||||
|
||||
if (meas->m_vec == NULL) {
|
||||
fprintf(cp_err, "Syntax error in meas line\n");
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
d = vec_get(meas->m_vec);
|
||||
if (d == NULL) {
|
||||
fprintf(cp_err, "Error: no such vector as %s.\n", meas->m_vec);
|
||||
return;
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -736,12 +750,12 @@ measure_minMaxAvg(
|
|||
dScale = vec_get("v-sweep");
|
||||
} else { /* error */
|
||||
fprintf(cp_err, "Error: no such analysis type as %s.\n", meas->m_analysis);
|
||||
return;
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
if (dScale == NULL) {
|
||||
fprintf(cp_err, "Error: no such vector as time, frquency or v-sweep.\n");
|
||||
return;
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
for (i = 0; i < d->v_length; i++) {
|
||||
|
|
@ -801,6 +815,7 @@ measure_minMaxAvg(
|
|||
break;
|
||||
default:
|
||||
fprintf(cp_err, "Error: improper min/max/avg call.\n");
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
} else {
|
||||
switch (mFunctionType) {
|
||||
|
|
@ -829,6 +844,7 @@ measure_minMaxAvg(
|
|||
}
|
||||
default :
|
||||
fprintf(cp_err, "Error: improper min/max/avg call.\n");
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -851,7 +867,9 @@ measure_minMaxAvg(
|
|||
}
|
||||
default :
|
||||
fprintf(cp_err, "Error: improper min/max/avg call.\n");
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
return MEASUREMENT_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -860,7 +878,7 @@ measure_minMaxAvg(
|
|||
* parsed into a measurement structure. Here we do interpolate
|
||||
* the starting and stopping time window so the answer is correct.
|
||||
* ----------------------------------------------------------------- */
|
||||
static void
|
||||
static int
|
||||
measure_rms_integral(
|
||||
MEASUREPTR meas, /* in : parsed measurement data request */
|
||||
ANALYSIS_TYPE_T mFunctionType /* in: one of AT_RMS, or AT_INTEG */
|
||||
|
|
@ -897,7 +915,7 @@ measure_rms_integral(
|
|||
d = vec_get(meas->m_vec);
|
||||
if (d == NULL) {
|
||||
fprintf(cp_err, "Error: no such vector as %s.\n", meas->m_vec);
|
||||
return;
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
if (ac_check || sp_check) {
|
||||
|
|
@ -908,12 +926,12 @@ measure_rms_integral(
|
|||
xScale = vec_get("v-sweep");
|
||||
} else { /* error */
|
||||
fprintf(cp_err, "Error: no such analysis type as %s.\n", meas->m_analysis);
|
||||
return;
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
if (xScale == NULL) {
|
||||
fprintf(cp_err, "Error: no such vector as time.\n");
|
||||
return;
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
/* Allocate buffers for calculation. */
|
||||
|
|
@ -1033,6 +1051,7 @@ measure_rms_integral(
|
|||
txfree(x);
|
||||
txfree(y);
|
||||
txfree(width);
|
||||
return MEASUREMENT_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1170,7 +1189,7 @@ measure_parse_stdParams(
|
|||
continue;
|
||||
} else {
|
||||
sprintf(errbuf, "bad syntax. equal sign missing ?\n");
|
||||
return 0;
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1181,7 +1200,7 @@ measure_parse_stdParams(
|
|||
if (ft_numparse(&pValue, FALSE, &engVal1) < 0) {
|
||||
sprintf(errbuf, "bad syntax, cannot evaluate right hand side "
|
||||
"of %s=%s\n", pName, pValue);
|
||||
return 0;
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1209,7 +1228,7 @@ measure_parse_stdParams(
|
|||
meas->m_at = engVal1;
|
||||
} else {
|
||||
sprintf(errbuf, "no such parameter as '%s'\n", pName);
|
||||
return 0;
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
pCnt ++;
|
||||
|
|
@ -1221,20 +1240,20 @@ measure_parse_stdParams(
|
|||
sprintf(errbuf, "bad syntax of %s\n", pName);
|
||||
else
|
||||
sprintf(errbuf, "bad syntax of\n");
|
||||
return 0;
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
// valid vector
|
||||
if (measure_valid_vector(meas->m_vec) == 0) {
|
||||
sprintf(errbuf, "no such vector as '%s'\n", meas->m_vec);
|
||||
return 0;
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
// valid vector2
|
||||
if (meas->m_vec2 != NULL)
|
||||
if (measure_valid_vector(meas->m_vec2) == 0) {
|
||||
sprintf(errbuf, "no such vector as '%s'\n", meas->m_vec2);
|
||||
return 0;
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
/* dc: make m_from always less than m_to */
|
||||
|
|
@ -1243,7 +1262,7 @@ measure_parse_stdParams(
|
|||
SWAP(double, meas->m_from, meas->m_to);
|
||||
}
|
||||
|
||||
return 1;
|
||||
return MEASUREMENT_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1295,29 +1314,30 @@ measure_parse_find(
|
|||
|
||||
if (pVal == NULL) {
|
||||
sprintf(errbuf, "bad syntax of WHEN\n");
|
||||
return 0;
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
if (strcasecmp(pName, "AT") == 0) {
|
||||
if (ft_numparse((char **) &pVal, FALSE, &meas->m_at) < 0) {
|
||||
sprintf(errbuf, "bad syntax of WHEN\n");
|
||||
return 0;
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
sprintf(errbuf, "bad syntax of WHEN\n");
|
||||
return 0;
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
} else {
|
||||
if (measure_parse_stdParams(meas, wl, NULL, errbuf) == 0)
|
||||
return 0;
|
||||
if (measure_parse_stdParams(meas, wl, NULL, errbuf) ==
|
||||
MEASUREMENT_FAILURE)
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
wl = wl->wl_next;
|
||||
pCnt ++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return MEASUREMENT_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1364,7 +1384,7 @@ measure_parse_when(
|
|||
|
||||
if (pVar2 == NULL) {
|
||||
sprintf(errBuf, "bad syntax\n");
|
||||
return 0;
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
meas->m_vec = copy(pVar1);
|
||||
|
|
@ -1380,15 +1400,15 @@ measure_parse_when(
|
|||
meas->m_val = INPevaluate(&pVar2, &err, 1);
|
||||
}
|
||||
} else {
|
||||
if (measure_parse_stdParams(meas, wl, NULL, errBuf) == 0)
|
||||
return 0;
|
||||
if (measure_parse_stdParams(meas, wl, NULL, errBuf) == MEASUREMENT_FAILURE)
|
||||
return MEASUREMENT_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
wl = wl->wl_next;
|
||||
pCnt ++;
|
||||
}
|
||||
return 1;
|
||||
return MEASUREMENT_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1437,11 +1457,13 @@ measure_parse_trigtarg(
|
|||
if (cieq("ac", meas->m_analysis) || cieq("sp", meas->m_analysis))
|
||||
correct_vec(meas);
|
||||
} else if (ciprefix("at", p)) {
|
||||
if (measure_parse_stdParams(meas, words, wlTarg, errbuf) == 0)
|
||||
return 0;
|
||||
if (measure_parse_stdParams(meas, words, wlTarg, errbuf) ==
|
||||
MEASUREMENT_FAILURE)
|
||||
return MEASUREMENT_FAILURE;
|
||||
} else {
|
||||
if (measure_parse_stdParams(meas, words, wlTarg, errbuf) == 0)
|
||||
return 0;
|
||||
if (measure_parse_stdParams(meas, words, wlTarg, errbuf) ==
|
||||
MEASUREMENT_FAILURE)
|
||||
return MEASUREMENT_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1451,16 +1473,16 @@ measure_parse_trigtarg(
|
|||
|
||||
if (pcnt == 0) {
|
||||
sprintf(errbuf, "bad syntax of '%s'\n", trigTarg);
|
||||
return 0;
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
// valid vector
|
||||
if (measure_valid_vector(meas->m_vec) == 0) {
|
||||
sprintf(errbuf, "no such vector as '%s'\n", meas->m_vec);
|
||||
return 0;
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return MEASUREMENT_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1543,6 +1565,8 @@ get_measure2(
|
|||
printf("Error: measure %s :\n", mName);
|
||||
printf("\tno such function as '%s'\n", words->wl_word);
|
||||
}
|
||||
tfree(mName);
|
||||
tfree(mAnalysis);
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
break;
|
||||
|
|
@ -1568,6 +1592,8 @@ get_measure2(
|
|||
printf("\tmeasure '%s' failed\n", mName);
|
||||
printf("Error: measure %s :\n", mName);
|
||||
printf("\tinvalid num params\n");
|
||||
tfree(mName);
|
||||
tfree(mAnalysis);
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
|
|
@ -1596,7 +1622,8 @@ get_measure2(
|
|||
|
||||
measTrig->m_analysis = measTarg->m_analysis = mAnalysis;
|
||||
|
||||
if (measure_parse_trigtarg(measTrig, words , wlTarg, "trig", errbuf) == 0) {
|
||||
if (measure_parse_trigtarg(measTrig, words, wlTarg, "trig", errbuf) ==
|
||||
MEASUREMENT_FAILURE) {
|
||||
measure_errMessage(mName, mFunction, "TRIG", errbuf, autocheck);
|
||||
goto err_ret1;
|
||||
}
|
||||
|
|
@ -1614,7 +1641,8 @@ get_measure2(
|
|||
if (words)
|
||||
words = words->wl_next; // skip targ
|
||||
|
||||
if (measure_parse_trigtarg(measTarg, words , NULL, "targ", errbuf) == 0) {
|
||||
if (measure_parse_trigtarg(measTarg, words, NULL, "targ", errbuf) ==
|
||||
MEASUREMENT_FAILURE) {
|
||||
measure_errMessage(mName, mFunction, "TARG", errbuf, autocheck);
|
||||
goto err_ret1;
|
||||
}
|
||||
|
|
@ -1675,7 +1703,7 @@ err_ret1:
|
|||
|
||||
meas->m_analysis = measFind->m_analysis = mAnalysis;
|
||||
|
||||
if (measure_parse_find(meas, words, wlWhen, errbuf) == 0) {
|
||||
if (measure_parse_find(meas, words, wlWhen, errbuf) == MEASUREMENT_FAILURE) {
|
||||
measure_errMessage(mName, mFunction, "FIND", errbuf, autocheck);
|
||||
goto err_ret2;
|
||||
}
|
||||
|
|
@ -1688,7 +1716,7 @@ err_ret1:
|
|||
if (words)
|
||||
words = words->wl_next; // skip targ
|
||||
|
||||
if (measure_parse_when(measFind, words, errbuf) == 0) {
|
||||
if (measure_parse_when(measFind, words, errbuf) == MEASUREMENT_FAILURE) {
|
||||
measure_errMessage(mName, mFunction, "WHEN", errbuf, autocheck);
|
||||
goto err_ret2;
|
||||
}
|
||||
|
|
@ -1701,11 +1729,16 @@ err_ret1:
|
|||
goto err_ret2;
|
||||
}
|
||||
|
||||
measure_at(meas, measFind->m_measured);
|
||||
if(measure_at(meas, measFind->m_measured) == MEASUREMENT_FAILURE){
|
||||
goto err_ret2;
|
||||
}
|
||||
|
||||
meas->m_at = measFind->m_measured;
|
||||
|
||||
} else {
|
||||
measure_at(meas, meas->m_at);
|
||||
if (measure_at(meas, meas->m_at) == MEASUREMENT_FAILURE) {
|
||||
goto err_ret2;
|
||||
}
|
||||
}
|
||||
|
||||
if (isnan(meas->m_measured)) {
|
||||
|
|
@ -1739,7 +1772,7 @@ err_ret2:
|
|||
MEASUREPTR meas;
|
||||
meas = TMALLOC(struct measure, 1);
|
||||
meas->m_analysis = mAnalysis;
|
||||
if (measure_parse_when(meas, words, errbuf) == 0) {
|
||||
if (measure_parse_when(meas, words, errbuf) == MEASUREMENT_FAILURE) {
|
||||
measure_errMessage(mName, mFunction, "WHEN", errbuf, autocheck);
|
||||
goto err_ret3;
|
||||
}
|
||||
|
|
@ -1778,7 +1811,8 @@ err_ret3:
|
|||
MEASUREPTR meas;
|
||||
meas = TMALLOC(struct measure, 1);
|
||||
meas->m_analysis = mAnalysis;
|
||||
if (measure_parse_trigtarg(meas, words , NULL, "trig", errbuf) == 0) {
|
||||
if (measure_parse_trigtarg(meas, words, NULL, "trig", errbuf) ==
|
||||
MEASUREMENT_FAILURE) {
|
||||
measure_errMessage(mName, mFunction, "TRIG", errbuf, autocheck);
|
||||
goto err_ret4;
|
||||
}
|
||||
|
|
@ -1822,7 +1856,8 @@ err_ret4:
|
|||
|
||||
meas->m_analysis = mAnalysis;
|
||||
|
||||
if (measure_parse_trigtarg(meas, words , NULL, "trig", errbuf) == 0) {
|
||||
if (measure_parse_trigtarg(meas, words, NULL, "trig", errbuf) ==
|
||||
MEASUREMENT_FAILURE) {
|
||||
measure_errMessage(mName, mFunction, "TRIG", errbuf, autocheck);
|
||||
goto err_ret5;
|
||||
}
|
||||
|
|
@ -1865,7 +1900,8 @@ err_ret5:
|
|||
MEASUREPTR measTrig;
|
||||
measTrig = TMALLOC(struct measure, 1);
|
||||
measTrig->m_analysis = mAnalysis;
|
||||
if (measure_parse_trigtarg(measTrig, words , NULL, "trig", errbuf) == 0) {
|
||||
if (measure_parse_trigtarg(measTrig, words, NULL, "trig", errbuf) ==
|
||||
MEASUREMENT_FAILURE) {
|
||||
measure_errMessage(mName, mFunction, "TRIG", errbuf, autocheck);
|
||||
goto err_ret6;
|
||||
}
|
||||
|
|
@ -1916,7 +1952,8 @@ err_ret6:
|
|||
MEASUREPTR measTrig;
|
||||
measTrig = TMALLOC(struct measure, 1);
|
||||
measTrig->m_analysis = mAnalysis;
|
||||
if (measure_parse_trigtarg(measTrig, words , NULL, "trig", errbuf) == 0) {
|
||||
if (measure_parse_trigtarg(measTrig, words, NULL, "trig", errbuf) ==
|
||||
MEASUREMENT_FAILURE) {
|
||||
measure_errMessage(mName, mFunction, "TRIG", errbuf, autocheck);
|
||||
goto err_ret7;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -386,7 +386,17 @@ static void set_static_system_info(void)
|
|||
return;
|
||||
} /* end of function set_static_system_info */
|
||||
|
||||
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
/* Get memory information */
|
||||
static int get_sysmem(struct sys_memory *memall)
|
||||
{
|
||||
fprintf(stderr, "System memory info is not available\n");
|
||||
return -1;
|
||||
}
|
||||
/* Get system information */
|
||||
static void set_static_system_info(void)
|
||||
{
|
||||
}
|
||||
|
||||
#elif defined(_WIN32)
|
||||
|
||||
|
|
|
|||
|
|
@ -434,7 +434,7 @@ eval_seed_opt(struct card *deck)
|
|||
* filter out the following cards: .save, .width, .four, .print, and
|
||||
* .plot, to perform after the run is over.
|
||||
* Then, we run dodeck, which parses up the deck. */
|
||||
void
|
||||
int
|
||||
inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile)
|
||||
/* arguments:
|
||||
* *fp = pointer to the input file
|
||||
|
|
@ -528,12 +528,12 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile)
|
|||
}
|
||||
tfree(dir_name);
|
||||
|
||||
/* if nothing came back from inp_readall, just close fp and return to
|
||||
* caller */
|
||||
/* if nothing came back from inp_readall, e.g. after calling ngspice
|
||||
* without parameters, just close fp and return to caller */
|
||||
if (!deck) {
|
||||
if (!intfile && fp)
|
||||
fclose(fp);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* files starting with *ng_script are user supplied command files */
|
||||
|
|
@ -730,19 +730,22 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile)
|
|||
#ifdef HAS_PROGREP
|
||||
SetAnalyse("Prepare Deck", 0);
|
||||
#endif
|
||||
/*FIXME This is for the globel param setting only */
|
||||
/* replace agauss(x,y,z) in each b-line by suitable value */
|
||||
static char *statfcn[] = { "agauss", "gauss", "aunif", "unif", "limit" };
|
||||
int ii;
|
||||
for (ii = 0; ii < 5; ii++)
|
||||
eval_agauss(deck, statfcn[ii]);
|
||||
/*This is for the globel param setting only */
|
||||
/* replace agauss(x,y,z) in each b-line by suitable value, one for all */
|
||||
bool statlocal = cp_getvar("statlocal", CP_BOOL, NULL, 0);
|
||||
if (!statlocal) {
|
||||
static char *statfcn[] = {"agauss", "gauss", "aunif", "unif", "limit"};
|
||||
int ii;
|
||||
for (ii = 0; ii < 5; ii++)
|
||||
eval_agauss(deck, statfcn[ii]);
|
||||
}
|
||||
/* Now expand subcircuit macros and substitute numparams.*/
|
||||
if (!cp_getvar("nosubckt", CP_BOOL, NULL, 0))
|
||||
if ((deck->nextcard = inp_subcktexpand(deck->nextcard)) == NULL) {
|
||||
line_free(realdeck, TRUE);
|
||||
line_free(deck->actualLine, TRUE);
|
||||
tfree(tt);
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Now handle translation of spice2c6 POLYs. */
|
||||
|
|
@ -818,17 +821,20 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile)
|
|||
|
||||
/* replace agauss(x,y,z) in each b-line by suitable value */
|
||||
/* FIXME: This is for the local param setting (not yet implemented in
|
||||
inp_fix_agauss_in_param() for model parameters according to HSPICE manual)
|
||||
static char *statfcn[] = { "agauss", "gauss", "aunif", "unif", "limit" };
|
||||
int ii;
|
||||
for (ii = 0; ii < 5; ii++)
|
||||
eval_agauss(deck, statfcn[ii]); */
|
||||
inp_fix_agauss_in_param() for model parameters according to HSPICE manual)*/
|
||||
if (statlocal) {
|
||||
static char *statfcn[] = {"agauss", "gauss", "aunif", "unif", "limit"};
|
||||
int ii;
|
||||
for (ii = 0; ii < 5; ii++)
|
||||
eval_agauss(deck, statfcn[ii]);
|
||||
}
|
||||
/* If user wants all currents saved (.options savecurrents), add .save
|
||||
to wl_first with all terminal currents available on selected devices */
|
||||
wl_first = inp_savecurrents(deck, options, wl_first, controls);
|
||||
|
||||
/* now load deck into ft_curckt -- the current circuit. */
|
||||
inp_dodeck(deck, tt, wl_first, FALSE, options, filename);
|
||||
if(inp_dodeck(deck, tt, wl_first, FALSE, options, filename) != 0)
|
||||
return 1;
|
||||
|
||||
if (ft_curckt) {
|
||||
ft_curckt->devtlist = devtlist;
|
||||
|
|
@ -981,6 +987,8 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile)
|
|||
cp_curerr = lasterr;
|
||||
|
||||
tfree(tt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -992,7 +1000,7 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile)
|
|||
* It appears that inp_dodeck adds the circuit described by *deck
|
||||
* to the current circuit (ft_curckt).
|
||||
*-----------------------------------------------------------------*/
|
||||
void
|
||||
int
|
||||
inp_dodeck(
|
||||
struct card *deck, /*in: the spice deck */
|
||||
char *tt, /*in: the title of the deck */
|
||||
|
|
@ -1158,6 +1166,7 @@ inp_dodeck(
|
|||
out_printf("Error on line %d :\n %s\n%s\n",
|
||||
dd->linenum_orig, dd->line, dd->error);
|
||||
have_err = TRUE;
|
||||
return 1;
|
||||
}
|
||||
if (ft_stricterror)
|
||||
controlled_exit(EXIT_BAD);
|
||||
|
|
@ -1279,6 +1288,7 @@ inp_dodeck(
|
|||
#if 0
|
||||
cp_addkword(CT_CKTNAMES, tt);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1599,7 +1609,9 @@ com_source(wordlist *wl)
|
|||
if (Infile_Path)
|
||||
tfree(Infile_Path);
|
||||
Infile_Path = ngdirname(firstfile);
|
||||
inp_spsource(fp, FALSE, tempfile ? NULL : wl->wl_word, FALSE);
|
||||
if (inp_spsource(fp, FALSE, tempfile ? NULL : wl->wl_word, FALSE) != 0) {
|
||||
fprintf(stderr, " Simulation interrupted due to error!\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
cp_interactive = inter;
|
||||
|
|
|
|||
|
|
@ -4009,7 +4009,7 @@ static int get_number_terminals(char *c)
|
|||
char *inst = gettok_instance(&c);
|
||||
strncpy(nam_buf, inst, sizeof(nam_buf) - 1);
|
||||
txfree(inst);
|
||||
if (strstr(nam_buf, "off") || strchr(nam_buf, '='))
|
||||
if (strstr(nam_buf, "off") || strchr(nam_buf, '=') || strstr(nam_buf, "tnodeout"))
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
|
|
@ -7389,7 +7389,7 @@ static bool del_models(struct vsmodels *vsmodel)
|
|||
* add predefined params TEMP, VT, GMIN to beginning of deck
|
||||
* add predefined params TEMP, VT, GMIN to beginning of each .subckt call
|
||||
* add .functions limit, pwr, pwrs, stp, if, int
|
||||
* replace
|
||||
* replace vswitch part S
|
||||
S1 D S DG GND SWN
|
||||
.MODEL SWN VSWITCH(VON = { 0.55 } VOFF = { 0.49 }
|
||||
RON = { 1 / (2 * M*(W / LE)*(KPN / 2) * 10) } ROFF = { 1G })
|
||||
|
|
@ -7397,6 +7397,15 @@ static bool del_models(struct vsmodels *vsmodel)
|
|||
as1 %vd(DG GND) % gd(D S) aswn
|
||||
.model aswn aswitch(cntl_off={0.49} cntl_on={0.55} r_off={1G}
|
||||
+ r_on={ 1 / (2 * M*(W / LE)*(KPN / 2) * 10) } log = TRUE)
|
||||
* replace vsitch part S_ST
|
||||
S1 D S DG GND S_ST
|
||||
.MODEL S_ST VSWITCH(VT = { 1.5 } VH = { 0.s }
|
||||
RON = { 1 / (2 * M*(W / LE)*(KPN / 2) * 10) } ROFF = { 1G })
|
||||
* by the classical voltage controlled ngspice switch
|
||||
S1 D S DG GND SWN
|
||||
.MODEL S_ST SW(VT = { 1.5 } VH = { 0.s }
|
||||
RON = { 1 / (2 * M*(W / LE)*(KPN / 2) * 10) } ROFF = { 1G })
|
||||
switch parameter td is not yet supported
|
||||
* replace & by &&
|
||||
* replace | by ||
|
||||
* in R instance, replace TC = xx1, xx2 by TC1=xx1 TC2=xx2
|
||||
|
|
@ -7708,19 +7717,31 @@ static struct card *pspice_compat(struct card *oldcard)
|
|||
}
|
||||
}
|
||||
|
||||
/* replace
|
||||
* S1 D S DG GND SWN
|
||||
* .MODEL SWN VSWITCH ( VON = {0.55} VOFF = {0.49}
|
||||
* RON={1/(2*M*(W/LE)*(KPN/2)*10)} ROFF={1G} )
|
||||
* by
|
||||
* a1 %v(DG) %gd(D S) swa
|
||||
* .MODEL SWA aswitch(cntl_off=0.49 cntl_on=0.55 r_off=1G
|
||||
* r_on={1/(2*M*(W/LE)*(KPN/2)*10)} log=TRUE)
|
||||
*
|
||||
* simple hierachy, as nested subcircuits are not allowed in PSPICE */
|
||||
/* if vswitch part s, replace
|
||||
* S1 D S DG GND SWN
|
||||
* .MODEL SWN VSWITCH ( VON = {0.55} VOFF = {0.49}
|
||||
* RON={1/(2*M*(W/LE)*(KPN/2)*10)} ROFF={1G} )
|
||||
* by
|
||||
* a1 %v(DG) %gd(D S) swa
|
||||
* .MODEL SWA aswitch(cntl_off=0.49 cntl_on=0.55 r_off=1G
|
||||
* r_on={1/(2*M*(W/LE)*(KPN/2)*10)} log=TRUE)
|
||||
*
|
||||
* if vswitch part s_st, don't replace instance, only model
|
||||
* replace
|
||||
* S1 D S DG GND S_ST
|
||||
* .MODEL S_ST VSWITCH(VT = { 1.5 } VH = { 0.s }
|
||||
RON = { 1 / (2 * M*(W / LE)*(KPN / 2) * 10) } ROFF = { 1G })
|
||||
* by the classical voltage controlled ngspice switch
|
||||
* S1 D S DG GND S_ST
|
||||
* .MODEL S_ST SW(VT = { 1.5 } VH = { 0.s }
|
||||
RON = { 1 / (2 * M*(W / LE)*(KPN / 2) * 10) } ROFF = { 1G })
|
||||
* vswitch delay parameter td is not yet supported
|
||||
|
||||
* simple hierachy, as nested subcircuits are not allowed in PSPICE */
|
||||
|
||||
/* first scan: find the vswitch models, transform them and put them into a
|
||||
* list */
|
||||
bool have_vt = FALSE, have_vh = FALSE;
|
||||
for (card = newcard; card; card = card->nextcard) {
|
||||
char *str;
|
||||
static struct card *subcktline = NULL;
|
||||
|
|
@ -7781,12 +7802,28 @@ static struct card *pspice_compat(struct card *oldcard)
|
|||
else
|
||||
/* vswitch defined without parens */
|
||||
modpar[3] = copy(equalptr[3]);
|
||||
tfree(card->line);
|
||||
/* replace VON by cntl_on, VOFF by cntl_off, RON by r_on, and ROFF
|
||||
* by r_off */
|
||||
rep_spar(modpar);
|
||||
card->line = tprintf(".model a%s aswitch(%s %s %s %s log=TRUE)",
|
||||
modname, modpar[0], modpar[1], modpar[2], modpar[3]);
|
||||
|
||||
/* check if we have parameters VT and VH */
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (ciprefix("vh", modpar[i]))
|
||||
have_vh = TRUE;
|
||||
if (ciprefix("vt", modpar[i]))
|
||||
have_vt = TRUE;
|
||||
}
|
||||
if (have_vh && have_vt) {
|
||||
/* replace vswitch by sw */
|
||||
char *vs = strstr(card->line, "vswitch");
|
||||
memmove(vs, " sw", 7);
|
||||
}
|
||||
else {
|
||||
/* replace VON by cntl_on, VOFF by cntl_off, RON by r_on, and
|
||||
* ROFF by r_off */
|
||||
tfree(card->line);
|
||||
rep_spar(modpar);
|
||||
card->line = tprintf(
|
||||
".model a%s aswitch(%s %s %s %s log=TRUE)", modname,
|
||||
modpar[0], modpar[1], modpar[2], modpar[3]);
|
||||
}
|
||||
for (i = 0; i < 4; i++)
|
||||
tfree(modpar[i]);
|
||||
if (nesting > 0)
|
||||
|
|
@ -7802,6 +7839,10 @@ static struct card *pspice_compat(struct card *oldcard)
|
|||
if (!modelsfound)
|
||||
return newcard;
|
||||
|
||||
/* no need to change the switch instances if switch sw is used */
|
||||
if (have_vh && have_vt)
|
||||
return newcard;
|
||||
|
||||
/* second scan: find the switch instances s calling a vswitch model and
|
||||
* transform them */
|
||||
for (card = newcard; card; card = card->nextcard) {
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ GRAPH *FindGraph(int id)
|
|||
GRAPH *CopyGraph(GRAPH *graph)
|
||||
{
|
||||
GRAPH *ret;
|
||||
struct dveclist *link, *newlink;
|
||||
struct dveclist *link = NULL, *newlink = NULL;
|
||||
|
||||
if (!graph) {
|
||||
return NULL;
|
||||
|
|
|
|||
|
|
@ -253,7 +253,6 @@ static struct dvec *find_permanent_vector_by_name(
|
|||
NGHASHPTR pl_lookup_table, char *name)
|
||||
{
|
||||
struct dvec *d;
|
||||
|
||||
/* Find the first vector with the given name and then find others
|
||||
* until one having the VF_PERMANENT flag set is found. */
|
||||
for (d = nghash_find(pl_lookup_table, name);
|
||||
|
|
@ -264,7 +263,18 @@ static struct dvec *find_permanent_vector_by_name(
|
|||
return d;
|
||||
}
|
||||
} /* end of loop over vectors in the plot having this name */
|
||||
|
||||
/* try again, this time without quotes around the name */
|
||||
char *nname = cp_unquote(name);
|
||||
for (d = nghash_find(pl_lookup_table, nname);
|
||||
d;
|
||||
d = nghash_find_again(pl_lookup_table, nname)) {
|
||||
if (d->v_flags & VF_PERMANENT) {
|
||||
/* A "permanent" vector was found with the name, so done */
|
||||
tfree(nname);
|
||||
return d;
|
||||
}
|
||||
} /* end of loop over vectors in the plot having this name */
|
||||
tfree(nname);
|
||||
return (struct dvec *) NULL; /* not found */
|
||||
} /* end of function find_permanent_vector_by_name */
|
||||
|
||||
|
|
@ -447,7 +457,7 @@ struct dvec *vec_fromplot(char *word, struct plot *plot) {
|
|||
if (word[1] == '(') { /* x(, x != '(' */
|
||||
const char * const p_last_close_paren = strrchr(word + 2, ')');
|
||||
if (p_last_close_paren != (char *) NULL &&
|
||||
p_last_close_paren - word > (ptrdiff_t) 3 &&
|
||||
p_last_close_paren - word > (ptrdiff_t) 2 &&
|
||||
p_last_close_paren[1] == '\0') {
|
||||
/* Of form x(node). Create node string. */
|
||||
DS_CREATE(ds, 100);
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ void DEVcmeyer(double,double,double,double,double,double,double,double,double,
|
|||
void DEVqmeyer(double,double,double,double,double,double*,double*,double*,
|
||||
double,double);
|
||||
void DevCapVDMOS(double, double, double, double, double,
|
||||
double*, double*, double*);
|
||||
double*, double*);
|
||||
double DEVpred(CKTcircuit*,int);
|
||||
|
||||
/* Cider integration */
|
||||
|
|
|
|||
|
|
@ -208,10 +208,10 @@ extern bool gr_circular;
|
|||
|
||||
/* inp.c */
|
||||
|
||||
void inp_dodeck(struct card *deck, char *tt, wordlist *end, bool reuse,
|
||||
int inp_dodeck(struct card *deck, char *tt, wordlist *end, bool reuse,
|
||||
struct card *options, char *filename);
|
||||
extern void inp_source(const char *file);
|
||||
void inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile);
|
||||
int inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile);
|
||||
extern void inp_casefix(char *string);
|
||||
extern void inp_list(FILE *file, struct card *deck, struct card *extras, int type);
|
||||
extern struct card *inp_readall(FILE *fp, char *dir_name, bool comfile, bool intfile, bool *expr_w_temper);
|
||||
|
|
|
|||
|
|
@ -1307,7 +1307,9 @@ int main(int argc, char **argv)
|
|||
|
||||
if (tempfile && (!err || !ft_batchmode)) {
|
||||
/* Copy the input file name for becoming another file search path */
|
||||
inp_spsource(tempfile, FALSE, dname, FALSE);
|
||||
if (inp_spsource(tempfile, FALSE, dname, FALSE) != 0) {
|
||||
fprintf(stderr, " Simulation interrupted due to error!\n\n");
|
||||
}
|
||||
tfree(dname);
|
||||
gotone = TRUE;
|
||||
}
|
||||
|
|
@ -1319,7 +1321,9 @@ int main(int argc, char **argv)
|
|||
} /* --- if (!ft_servermode) --- */
|
||||
|
||||
if (!gotone && ft_batchmode) {
|
||||
inp_spsource(circuit_file, FALSE, NULL, FALSE);
|
||||
if (inp_spsource(circuit_file, FALSE, NULL, FALSE) != 0) {
|
||||
fprintf(stderr, " Simulation interrupted due to error!\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ CKTdestroy(CKTcircuit *ckt)
|
|||
CKTnode *node;
|
||||
CKTnode *nnode;
|
||||
|
||||
if (!ckt)
|
||||
return (E_NOTFOUND);
|
||||
|
||||
|
||||
#ifdef WANT_SENSE2
|
||||
if(ckt->CKTsenInfo){
|
||||
|
|
|
|||
|
|
@ -122,7 +122,69 @@ B1dSetup(GENmodel *inModel, CKTcircuit *ckt)
|
|||
Dderivs d_VgsVth, d_G, d_A, d_Arg, d_DrCur;
|
||||
Dderivs d_Ugs, d_Uds, d_Eta, d_Vpb, d_SqrtVpb, d_Von;
|
||||
Dderivs d_p, d_q, d_r, d_zero;
|
||||
/* remove compiler warnings */
|
||||
d_qg.value = 0.0;
|
||||
d_qg.d1_p = 0.0;
|
||||
d_qg.d1_q = 0.0;
|
||||
d_qg.d1_r = 0.0;
|
||||
d_qg.d2_p2 = 0.0;
|
||||
d_qg.d2_q2 = 0.0;
|
||||
d_qg.d2_r2 = 0.0;
|
||||
d_qg.d2_pq = 0.0;
|
||||
d_qg.d2_qr = 0.0;
|
||||
d_qg.d2_pr = 0.0;
|
||||
d_qg.d3_p3 = 0.0;
|
||||
d_qg.d3_q3 = 0.0;
|
||||
d_qg.d3_r3 = 0.0;
|
||||
d_qg.d3_p2q = 0.0;
|
||||
d_qg.d3_p2r = 0.0;
|
||||
d_qg.d3_pq2 = 0.0;
|
||||
d_qg.d3_q2r = 0.0;
|
||||
d_qg.d3_pr2 = 0.0;
|
||||
d_qg.d3_qr2 = 0.0;
|
||||
d_qg.d3_pqr = 0.0;
|
||||
|
||||
d_qb.value = 0.0;
|
||||
d_qb.d1_p = 0.0;
|
||||
d_qb.d1_q = 0.0;
|
||||
d_qb.d1_r = 0.0;
|
||||
d_qb.d2_p2 = 0.0;
|
||||
d_qb.d2_q2 = 0.0;
|
||||
d_qb.d2_r2 = 0.0;
|
||||
d_qb.d2_pq = 0.0;
|
||||
d_qb.d2_qr = 0.0;
|
||||
d_qb.d2_pr = 0.0;
|
||||
d_qb.d3_p3 = 0.0;
|
||||
d_qb.d3_q3 = 0.0;
|
||||
d_qb.d3_r3 = 0.0;
|
||||
d_qb.d3_p2q = 0.0;
|
||||
d_qb.d3_p2r = 0.0;
|
||||
d_qb.d3_pq2 = 0.0;
|
||||
d_qb.d3_q2r = 0.0;
|
||||
d_qb.d3_pr2 = 0.0;
|
||||
d_qb.d3_qr2 = 0.0;
|
||||
d_qb.d3_pqr = 0.0;
|
||||
|
||||
d_qd.value = 0.0;
|
||||
d_qd.d1_p = 0.0;
|
||||
d_qd.d1_q = 0.0;
|
||||
d_qd.d1_r = 0.0;
|
||||
d_qd.d2_p2 = 0.0;
|
||||
d_qd.d2_q2 = 0.0;
|
||||
d_qd.d2_r2 = 0.0;
|
||||
d_qd.d2_pq = 0.0;
|
||||
d_qd.d2_qr = 0.0;
|
||||
d_qd.d2_pr = 0.0;
|
||||
d_qd.d3_p3 = 0.0;
|
||||
d_qd.d3_q3 = 0.0;
|
||||
d_qd.d3_r3 = 0.0;
|
||||
d_qd.d3_p2q = 0.0;
|
||||
d_qd.d3_p2r = 0.0;
|
||||
d_qd.d3_pq2 = 0.0;
|
||||
d_qd.d3_q2r = 0.0;
|
||||
d_qd.d3_pr2 = 0.0;
|
||||
d_qd.d3_qr2 = 0.0;
|
||||
d_qd.d3_pqr = 0.0;
|
||||
|
||||
/* loop through all the B1 device models */
|
||||
for( ; model != NULL; model = B1nextModel(model)) {
|
||||
|
|
|
|||
|
|
@ -97,15 +97,15 @@ B2load(GENmodel *inModel, CKTcircuit *ckt)
|
|||
double cgdb;
|
||||
double cgsb;
|
||||
double cbdb;
|
||||
double cdgb;
|
||||
double cddb;
|
||||
double cdsb;
|
||||
double cdgb = 0.0;
|
||||
double cddb = 0.0;
|
||||
double cdsb = 0.0;
|
||||
double cggb;
|
||||
double cbgb;
|
||||
double cbsb;
|
||||
double csgb;
|
||||
double cssb;
|
||||
double csdb;
|
||||
double csgb = 0.0;
|
||||
double cssb = 0.0;
|
||||
double csdb = 0.0;
|
||||
double PhiB;
|
||||
double PhiBSW;
|
||||
double MJ;
|
||||
|
|
|
|||
|
|
@ -620,7 +620,7 @@ http://ltwiki.org/index.php5?title=Undocumented_LTspice#VDMOS:_Breakdown_and_Sub
|
|||
void
|
||||
DevCapVDMOS(double vgd, double cgdmin,
|
||||
double cgdmax, double a, double cgs,
|
||||
double *capgs, double *capgd, double *capgb)
|
||||
double *capgs, double *capgd)
|
||||
{
|
||||
double s = (cgdmax - cgdmin) / (1 + M_PI / 2);
|
||||
double y = cgdmax - s;
|
||||
|
|
@ -629,7 +629,6 @@ DevCapVDMOS(double vgd, double cgdmin,
|
|||
else
|
||||
*capgd = 0.5 * (s * atan(a * vgd) + y);
|
||||
*capgs = 0.5 * cgs;
|
||||
*capgb = 0;
|
||||
}
|
||||
|
||||
/* Compute the MOS overlap capacitances as functions of the device
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
double vt; /* K t / Q */
|
||||
double vte, vtesw, vtetun;
|
||||
double vtebrk;
|
||||
int Check;
|
||||
int Check = 0;
|
||||
int error;
|
||||
int SenCond=0; /* sensitivity condition */
|
||||
double diffcharge, diffchargeSW, deplcharge, deplchargeSW, diffcap, diffcapSW, deplcap, deplcapSW;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ LTRAload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
LTRAinstance *here;
|
||||
double t1=0.0, t2=0.0, t3=0.0;
|
||||
double qf1=0.0, qf2=0.0, qf3=0.0;
|
||||
double lf2, lf3;
|
||||
double lf2=0.0, lf3=0.0;
|
||||
double v1d = 0.0, v2d = 0.0, i1d = 0.0, i2d = 0.0;
|
||||
double dummy1=0.0, dummy2=0.0;
|
||||
int isaved = 0;
|
||||
|
|
|
|||
|
|
@ -60,14 +60,35 @@ MOS2dSetup(GENmodel *inModel, CKTcircuit *ckt)
|
|||
double lgbs, lgbs2, lgbs3;
|
||||
double lgbd, lgbd2, lgbd3;
|
||||
double vgst;
|
||||
double lcapbs, lcapbs2, lcapbs3;
|
||||
double lcapbd, lcapbd2, lcapbd3;
|
||||
double gm2, gb2, gds2;
|
||||
double gmb, gmds, gbds;
|
||||
double gm3, gb3, gds3;
|
||||
double gm2b, gm2ds, gmb2, gmds2, gbds2, gb2ds;
|
||||
double gmbds;
|
||||
Dderivs d_cdrain;
|
||||
double lcapbs, lcapbs2, lcapbs3;
|
||||
double lcapbd, lcapbd2, lcapbd3;
|
||||
double gm2, gb2, gds2;
|
||||
double gmb, gmds, gbds;
|
||||
double gm3, gb3, gds3;
|
||||
double gm2b, gm2ds, gmb2, gmds2, gbds2, gb2ds;
|
||||
double gmbds;
|
||||
Dderivs d_cdrain;
|
||||
/*remove compiler warnings */
|
||||
d_cdrain.value = 0.0;
|
||||
d_cdrain.d1_p = 0.0;
|
||||
d_cdrain.d1_q = 0.0;
|
||||
d_cdrain.d1_r = 0.0;
|
||||
d_cdrain.d2_p2 = 0.0;
|
||||
d_cdrain.d2_q2 = 0.0;
|
||||
d_cdrain.d2_r2 = 0.0;
|
||||
d_cdrain.d2_pq = 0.0;
|
||||
d_cdrain.d2_qr = 0.0;
|
||||
d_cdrain.d2_pr = 0.0;
|
||||
d_cdrain.d3_p3 = 0.0;
|
||||
d_cdrain.d3_q3 = 0.0;
|
||||
d_cdrain.d3_r3 = 0.0;
|
||||
d_cdrain.d3_p2q = 0.0;
|
||||
d_cdrain.d3_p2r = 0.0;
|
||||
d_cdrain.d3_pq2 = 0.0;
|
||||
d_cdrain.d3_q2r = 0.0;
|
||||
d_cdrain.d3_pr2 = 0.0;
|
||||
d_cdrain.d3_qr2 = 0.0;
|
||||
d_cdrain.d3_pqr = 0.0;
|
||||
|
||||
/* loop through all the MOS2 device models */
|
||||
for( ; model != NULL; model = MOS2nextModel(model)) {
|
||||
|
|
@ -231,8 +252,8 @@ double gmbds;
|
|||
double y3;
|
||||
double delta4;
|
||||
double xvalid = 0.0;
|
||||
double bsarg;
|
||||
double bodys;
|
||||
double bsarg = 0.0;
|
||||
double bodys = 0.0;
|
||||
double sargv;
|
||||
double xlfact;
|
||||
double xdv;
|
||||
|
|
|
|||
|
|
@ -518,7 +518,7 @@ next1: if(vbs <= -3*vt) {
|
|||
double delta4;
|
||||
double xvalid = 0.0;
|
||||
double bsarg = 0.0;
|
||||
double dbsrdb;
|
||||
double dbsrdb = 0.0;
|
||||
double bodys = 0.0;
|
||||
double gdbdvs = 0.0;
|
||||
double sargv;
|
||||
|
|
|
|||
|
|
@ -35,13 +35,13 @@ NBJTload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
register ONEdevice *pDevice;
|
||||
double startTime, startTime2, totalTime, totalTime2;
|
||||
double tol;
|
||||
double ic, ie;
|
||||
double ic=0, ie=0;
|
||||
double iceq, ieeq;
|
||||
double ichat = 0.0, iehat = 0.0;
|
||||
double delVce, delVbe;
|
||||
double vce, vbe /*, vbc*/;
|
||||
double dIeDVce, dIeDVbe;
|
||||
double dIcDVce, dIcDVbe;
|
||||
double dIeDVce=0, dIeDVbe=0;
|
||||
double dIcDVce=0, dIcDVbe=0;
|
||||
double xfact;
|
||||
int icheck;
|
||||
int icheck1;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ NBJTtemp(GENmodel *inModel, CKTcircuit *ckt)
|
|||
ONEmaterial *pM, *pMaterial, *pNextMaterial;
|
||||
ONEdevice *pDevice;
|
||||
double startTime;
|
||||
int baseIndex, indexBE, indexBC;
|
||||
int baseIndex, indexBE=0, indexBC=0;
|
||||
|
||||
|
||||
/* loop through all the bjt models */
|
||||
|
|
|
|||
|
|
@ -35,13 +35,13 @@ NBJT2load(GENmodel *inModel, CKTcircuit *ckt)
|
|||
register TWOdevice *pDevice;
|
||||
double startTime, startTime2, totalTime, totalTime2;
|
||||
double tol;
|
||||
double ic, ie;
|
||||
double ic = 0.0, ie = 0.0;
|
||||
double iceq, ieeq;
|
||||
double ichat = 0.0, iehat = 0.0;
|
||||
double delVce, delVbe;
|
||||
double vce, vbe;
|
||||
double dIeDVce, dIeDVbe;
|
||||
double dIcDVce, dIcDVbe;
|
||||
double dIeDVce = 0.0, dIeDVbe = 0.0;
|
||||
double dIcDVce = 0.0, dIcDVbe = 0.0;
|
||||
double xfact;
|
||||
int icheck;
|
||||
int icheck1;
|
||||
|
|
|
|||
|
|
@ -34,12 +34,12 @@ NUMDload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
register ONEdevice *pDevice;
|
||||
double startTime, startTime2, totalTime, totalTime2;
|
||||
double tol; /* temporary for tolerance calculations */
|
||||
double id;
|
||||
double id = 0.0;
|
||||
double ideq;
|
||||
double idhat = 0.0;
|
||||
double delVd;
|
||||
double vd; /* current diode voltage */
|
||||
double gd;
|
||||
double gd = 0.0;
|
||||
double xfact;
|
||||
int check;
|
||||
int i;
|
||||
|
|
|
|||
|
|
@ -31,10 +31,10 @@ NUMD2load(GENmodel *inModel, CKTcircuit *ckt)
|
|||
register NUMD2instance *inst;
|
||||
register TWOdevice *pDevice;
|
||||
double startTime, startTime2, totalTime, totalTime2;
|
||||
double id;
|
||||
double id=0.;
|
||||
double idhat = 0.0;
|
||||
double ideq;
|
||||
double gd;
|
||||
double gd=0.;
|
||||
double xfact;
|
||||
double tol; /* temporary for tolerance calculations */
|
||||
double vd; /* current diode voltage */
|
||||
|
|
|
|||
|
|
@ -34,12 +34,11 @@ NUMOSload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
double startTime, startTime2, totalTime, totalTime2;
|
||||
double tol;
|
||||
double xfact;
|
||||
double id, is, ig;
|
||||
double id = 0.0, is = 0.0, ig = 0.0;
|
||||
double ideq, iseq, igeq;
|
||||
double idhat = 0.0, ishat = 0.0, ighat = 0.0;
|
||||
double delVdb, delVsb, delVgb;
|
||||
double vdb, vsb, vgb;
|
||||
struct mosConductances g;
|
||||
int icheck;
|
||||
int icheck1;
|
||||
int i;
|
||||
|
|
@ -51,6 +50,17 @@ NUMOSload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
int doVoltPred;
|
||||
char *initStateName;
|
||||
|
||||
struct mosConductances g;
|
||||
/* remove compiler warning */
|
||||
g.dIdDVdb = 0.0;
|
||||
g.dIdDVsb = 0.0;
|
||||
g.dIdDVgb = 0.0;
|
||||
g.dIsDVdb = 0.0;
|
||||
g.dIsDVsb = 0.0;
|
||||
g.dIsDVgb = 0.0;
|
||||
g.dIgDVdb = 0.0;
|
||||
g.dIgDVsb = 0.0;
|
||||
g.dIgDVgb = 0.0;
|
||||
/* loop through all the models */
|
||||
for (; model != NULL; model = NUMOSnextModel(model)) {
|
||||
FieldDepMobility = model->NUMOSmodels->MODLfieldDepMobility;
|
||||
|
|
|
|||
|
|
@ -136,6 +136,13 @@ SOI3load(GENmodel *inModel, CKTcircuit *ckt)
|
|||
double gcbgf,gcbd,gcbs,gcbdeltaT,gcbgb;
|
||||
double gcgbgf,gcgbd,gcgbs,gcgbdeltaT,gcgbgb;
|
||||
|
||||
/* remove compiler warnings */
|
||||
cgfgf=cgfd=cgfs=cgfdeltaT=cgfgb = 0;
|
||||
cdgf=cdd=cds=cddeltaT=cdgb = 0;
|
||||
csgf=csd=css=csdeltaT=csgb = 0;
|
||||
cbgf=cbd=cbs=cbdeltaT=cbgb = 0;
|
||||
cgbgf=cgbd=cgbs=cgbdeltaT=cgbgb = 0;
|
||||
|
||||
double alphaBJT;
|
||||
double tauFBJTeff,tauRBJTeff;
|
||||
double ISts,IS1ts,IStd,IS1td;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ libvdmos_la_SOURCES = \
|
|||
vdmospar.c \
|
||||
vdmospzld.c \
|
||||
vdmosset.c \
|
||||
vdmossoachk.c \
|
||||
vdmostemp.c \
|
||||
vdmostrun.c
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1987 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
VDMOS Model: 2018 Holger Vogt
|
||||
VDMOS: 2018 Holger Vogt, 2020 Dietmar Warning
|
||||
**********/
|
||||
|
||||
#include "ngspice/ngspice.h"
|
||||
|
|
@ -12,35 +12,36 @@ VDMOS Model: 2018 Holger Vogt
|
|||
#include "ngspice/suffix.h"
|
||||
|
||||
IFparm VDMOSpTable[] = { /* parameters */
|
||||
IOPU("mu", VDMOS_M, IF_REAL, "Multiplier"),
|
||||
IOPU("l", VDMOS_L, IF_REAL, "Length"),
|
||||
IOPU("w", VDMOS_W, IF_REAL, "Width"),
|
||||
IP("off", VDMOS_OFF, IF_FLAG, "Device initially off"),
|
||||
IOPU("icvds", VDMOS_IC_VDS, IF_REAL, "Initial D-S voltage"),
|
||||
IOPU("icvgs", VDMOS_IC_VGS, IF_REAL, "Initial G-S voltage"),
|
||||
IOPU("temp", VDMOS_TEMP, IF_REAL, "Instance temperature"),
|
||||
IOPU("dtemp", VDMOS_DTEMP, IF_REAL, "Instance temperature difference"),
|
||||
IP( "ic", VDMOS_IC, IF_REALVEC, "Vector of D-S, G-S voltages"),
|
||||
IOPU("m", VDMOS_M, IF_REAL, "Multiplier"),
|
||||
IOPU("l", VDMOS_L, IF_REAL, "Length"),
|
||||
IOPU("w", VDMOS_W, IF_REAL, "Width"),
|
||||
IP("off", VDMOS_OFF, IF_FLAG, "Device initially off"),
|
||||
IOPU("icvds", VDMOS_IC_VDS, IF_REAL, "Initial D-S voltage"),
|
||||
IOPU("icvgs", VDMOS_IC_VGS, IF_REAL, "Initial G-S voltage"),
|
||||
IOPU("temp", VDMOS_TEMP, IF_REAL, "Instance temperature"),
|
||||
IOPU("dtemp", VDMOS_DTEMP, IF_REAL, "Instance temperature difference"),
|
||||
IP( "ic", VDMOS_IC, IF_REALVEC, "Vector of D-S, G-S voltages"),
|
||||
|
||||
OP( "id", VDMOS_CD, IF_REAL, "Drain current"),
|
||||
OP( "is", VDMOS_CS, IF_REAL, "Source current"),
|
||||
OP( "ig", VDMOS_CG, IF_REAL, "Gate current "),
|
||||
OP( "vgs", VDMOS_VGS, IF_REAL, "Gate-Source voltage"),
|
||||
OP( "vds", VDMOS_VDS, IF_REAL, "Drain-Source voltage"),
|
||||
OP( "cgs", VDMOS_CAPGS, IF_REAL, "Gate-Source capacitance"),
|
||||
OP( "cgd", VDMOS_CAPGD, IF_REAL, "Gate-Drain capacitance"),
|
||||
OP( "cds", VDMOS_CAPDS, IF_REAL, "Drain-Source capacitance"),
|
||||
IOP("tnodeout", VDMOS_TNODEOUT, IF_FLAG, "Thermal model switch on/off"),
|
||||
|
||||
OP( "id", VDMOS_CD, IF_REAL, "Drain current"),
|
||||
OP( "is", VDMOS_CS, IF_REAL, "Source current"),
|
||||
OP( "ig", VDMOS_CG, IF_REAL, "Gate current"),
|
||||
OP( "vgs", VDMOS_VGS, IF_REAL, "Gate-Source voltage"),
|
||||
OP( "vds", VDMOS_VDS, IF_REAL, "Drain-Source voltage"),
|
||||
OP( "cgs", VDMOS_CAPGS, IF_REAL, "Gate-Source capacitance"),
|
||||
OP( "cgd", VDMOS_CAPGD, IF_REAL, "Gate-Drain capacitance"),
|
||||
OP( "cds", VDMOS_CAPDS, IF_REAL, "Drain-Source capacitance"),
|
||||
|
||||
OPU( "dnode", VDMOS_DNODE, IF_INTEGER, "Number of the drain node "),
|
||||
OPU( "gnode", VDMOS_GNODE, IF_INTEGER, "Number of the gate node "),
|
||||
OPU( "snode", VDMOS_SNODE, IF_INTEGER, "Number of the source node "),
|
||||
OPU( "tempnode", VDMOS_TNODE, IF_INTEGER, "Number of temperature node"),
|
||||
OPU( "tcasenode", VDMOS_TCASE, IF_INTEGER, "Number of 2nd temperature node"),
|
||||
OPU( "dnodeprime", VDMOS_DNODEPRIME, IF_INTEGER, "Number of int. drain node"),
|
||||
OPU( "snodeprime", VDMOS_SNODEPRIME, IF_INTEGER, "Number of int. source node "),
|
||||
|
||||
OP( "von", VDMOS_VON, IF_REAL, " "),
|
||||
OP( "vdsat", VDMOS_VDSAT, IF_REAL, "Saturation drain voltage"),
|
||||
OPU( "sourcevcrit", VDMOS_SOURCEVCRIT, IF_REAL, "Critical source voltage"),
|
||||
OPU( "drainvcrit", VDMOS_DRAINVCRIT, IF_REAL, "Critical drain voltage"),
|
||||
OP( "von", VDMOS_VON, IF_REAL, "Device on state voltage"),
|
||||
OP( "rs", VDMOS_SOURCERESIST, IF_REAL, "Source resistance"),
|
||||
OPU("sourceconductance", VDMOS_SOURCECONDUCT, IF_REAL, "Conductance of source"),
|
||||
OP( "rd", VDMOS_DRAINRESIST, IF_REAL, "Drain conductance"),
|
||||
|
|
@ -54,13 +55,14 @@ IFparm VDMOSpTable[] = { /* parameters */
|
|||
|
||||
OPU( "qgs", VDMOS_QGS, IF_REAL, "Gate-Source charge storage"),
|
||||
OPU( "qgd", VDMOS_QGD, IF_REAL, "Gate-Drain charge storage"),
|
||||
OPU( "p", VDMOS_POWER, IF_REAL, "Instaneous power"),
|
||||
OPU( "p", VDMOS_POWER, IF_REAL, "Instantaneous power"),
|
||||
};
|
||||
|
||||
IFparm VDMOSmPTable[] = { /* model parameters */
|
||||
/* basic device */
|
||||
OP("type", VDMOS_MOD_TYPE, IF_STRING, "N-channel or P-channel MOS"),
|
||||
IOP("vto", VDMOS_MOD_VTO, IF_REAL, "Threshold voltage"),
|
||||
IOP("vto", VDMOS_MOD_VTH, IF_REAL, "Threshold voltage"),
|
||||
IOPR("vth0", VDMOS_MOD_VTH, IF_REAL, "Threshold voltage"),
|
||||
IOP("kp", VDMOS_MOD_KP, IF_REAL, "Transconductance parameter"),
|
||||
IOP("phi", VDMOS_MOD_PHI, IF_REAL, "Surface potential"),
|
||||
IOP("lambda",VDMOS_MOD_LAMBDA,IF_REAL, "Channel length modulation"),
|
||||
|
|
@ -80,10 +82,17 @@ IFparm VDMOSmPTable[] = { /* model parameters */
|
|||
IOP("vq", VDMOS_MOD_VQ, IF_REAL, "Quasi saturation voltage fitting parameter"),
|
||||
IOP("mtriode", VDMOS_MOD_MTRIODE, IF_REAL, "Conductance multiplier in triode region"),
|
||||
|
||||
/* temperature dependency */
|
||||
IOP( "tcvth", VDMOS_MOD_TCVTH, IF_REAL, "Linear Vth0 temperature coefficient"),
|
||||
IOPR("vtotc", VDMOS_MOD_TCVTH, IF_REAL, "Linear Vth0 temperature coefficient"),
|
||||
IOP( "mu", VDMOS_MOD_MU, IF_REAL, "Exponent of gain temperature dependency"),
|
||||
IOPR("bex", VDMOS_MOD_MU, IF_REAL, "Exponent of gain temperature dependency"),
|
||||
IOP( "texp0", VDMOS_MOD_TEXP0, IF_REAL, "Drain resistance rd0 temperature exponent"),
|
||||
IOP( "texp1", VDMOS_MOD_TEXP1, IF_REAL, "Drain resistance rd1 temperature exponent"),
|
||||
|
||||
/* weak inversion */
|
||||
IOP("subslope", VDMOS_MOD_SUBSLOPE, IF_REAL, "Slope of weak inversion log current versus vgs - vth"),
|
||||
IOP("subshift", VDMOS_MOD_SUBSHIFT, IF_REAL, "Shift of weak inversion plot on the vgs axis"),
|
||||
IOP("ksubthres", VDMOS_MOD_KSUBTHRES, IF_REAL, "Shift of weak inversion plot on the vgs axis"),
|
||||
IOP("ksubthres", VDMOS_MOD_KSUBTHRES, IF_REAL, "Slope of weak inversion log current versus vgs"),
|
||||
|
||||
/* body diode */
|
||||
IOP("bv", VDMOS_MOD_BV, IF_REAL, "Vds breakdown voltage"),
|
||||
|
|
@ -94,7 +103,7 @@ IFparm VDMOSmPTable[] = { /* model parameters */
|
|||
IOP("n", VDMOS_MOD_N, IF_REAL, "Body diode emission coefficient"),
|
||||
IOP("tt", VDMOS_MOD_TT, IF_REAL, "Body diode transit time"),
|
||||
IOP("eg", VDMOS_MOD_EG, IF_REAL, "Body diode activation energy for temperature effect on Is"),
|
||||
IOP("Xti", VDMOS_MOD_XTI, IF_REAL, "Body diode saturation current temperature exponent"),
|
||||
IOP("xti", VDMOS_MOD_XTI, IF_REAL, "Body diode saturation current temperature exponent"),
|
||||
IOP("is", VDMOS_MOD_IS, IF_REAL, "Body diode saturation current"),
|
||||
IOP("vj", VDMOS_MOD_VJ, IF_REAL, "Body diode junction potential"),
|
||||
|
||||
|
|
@ -108,16 +117,30 @@ IFparm VDMOSmPTable[] = { /* model parameters */
|
|||
IOPA("cgdmax", VDMOS_MOD_CGDMAX, IF_REAL, "Maximum non-linear G-D capacitance"),
|
||||
IOPA("a", VDMOS_MOD_A, IF_REAL, "Non-linear Cgd capacitance parameter"),
|
||||
IOPA("cgs", VDMOS_MOD_CGS, IF_REAL, "Gate-source capacitance"),
|
||||
|
||||
/* self heating */
|
||||
IOP("rthjc", VDMOS_MOD_RTHJC, IF_REAL, "Self-heating thermal resistance"),
|
||||
IOP("rthca", VDMOS_MOD_RTHCA, IF_REAL, "Self-heating thermal resistance"),
|
||||
IOP("cthj", VDMOS_MOD_CTHJ, IF_REAL, "Self-heating thermal capacitance"),
|
||||
|
||||
/* soa check */
|
||||
IOP("vgs_max", VDMOS_MOD_VGS_MAX, IF_REAL, "maximum voltage G-S branch"),
|
||||
IOP("vgd_max", VDMOS_MOD_VGD_MAX, IF_REAL, "maximum voltage G-D branch"),
|
||||
IOP("vds_max", VDMOS_MOD_VDS_MAX, IF_REAL, "maximum voltage D-S branch"),
|
||||
IOP("vgsr_max", VDMOS_MOD_VGSR_MAX, IF_REAL, "maximum voltage G-S branch"),
|
||||
IOP("vgdr_max", VDMOS_MOD_VGDR_MAX, IF_REAL, "maximum voltage G-D branch"),
|
||||
};
|
||||
|
||||
char *VDMOSnames[] = {
|
||||
"Drain",
|
||||
"Gate",
|
||||
"Source"
|
||||
"Source",
|
||||
"Temp",
|
||||
"Tcase"
|
||||
};
|
||||
|
||||
int VDMOSnSize = NUMELEMS(VDMOSnames);
|
||||
int VDMOSpTSize = NUMELEMS(VDMOSpTable);
|
||||
int VDMOSmPTSize = NUMELEMS(VDMOSmPTable);
|
||||
int VDMOSiSize = sizeof(VDMOSinstance);
|
||||
int VDMOSmSize = sizeof(VDMOSmodel);
|
||||
int VDMOSnSize = NUMELEMS(VDMOSnames);
|
||||
int VDMOSpTSize = NUMELEMS(VDMOSpTable);
|
||||
int VDMOSmPTSize = NUMELEMS(VDMOSmPTable);
|
||||
int VDMOSiSize = sizeof(VDMOSinstance);
|
||||
int VDMOSmSize = sizeof(VDMOSmodel);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
VDMOS: 2018 Holger Vogt, 2020 Dietmar Warning
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
|
@ -20,15 +21,21 @@ VDMOSacLoad(GENmodel *inModel, CKTcircuit *ckt)
|
|||
VDMOSinstance *here;
|
||||
int xnrm;
|
||||
int xrev;
|
||||
double xgs;
|
||||
double xgd;
|
||||
double capgs;
|
||||
double capgd;
|
||||
double xgs, xcgT;
|
||||
double xgd, xcdT;
|
||||
double capgs, cgT;
|
||||
double capgd, cdT;
|
||||
double cTt, gTtt, gTtg, gTtdp, gTtsp;
|
||||
double GmT;
|
||||
double xcsT, xcTt;
|
||||
|
||||
register int selfheat;
|
||||
|
||||
for( ; model != NULL; model = VDMOSnextModel(model)) {
|
||||
for(here = VDMOSinstances(model); here!= NULL;
|
||||
here = VDMOSnextInstance(here)) {
|
||||
|
||||
|
||||
selfheat = (here->VDMOStnodeoutGiven) && (model->VDMOSrthjcGiven);
|
||||
if (here->VDMOSmode < 0) {
|
||||
xnrm=0;
|
||||
xrev=1;
|
||||
|
|
@ -36,6 +43,27 @@ VDMOSacLoad(GENmodel *inModel, CKTcircuit *ckt)
|
|||
xnrm=1;
|
||||
xrev=0;
|
||||
}
|
||||
|
||||
if (here->VDMOSmode >= 0) {
|
||||
GmT = model->VDMOStype * here->VDMOSgmT;
|
||||
cgT = model->VDMOStype * here->VDMOScgT;
|
||||
cdT = model->VDMOStype * here->VDMOScdT;
|
||||
cTt = model->VDMOScthj;
|
||||
gTtg = here->VDMOSgtempg;
|
||||
gTtdp = here->VDMOSgtempd;
|
||||
gTtt = here->VDMOSgtempT;
|
||||
gTtsp = - (gTtg + gTtdp);
|
||||
} else {
|
||||
GmT = -model->VDMOStype * here->VDMOSgmT;
|
||||
cgT = -model->VDMOStype * here->VDMOScgT;
|
||||
cdT = -model->VDMOStype * here->VDMOScdT;
|
||||
cTt = -model->VDMOScthj;
|
||||
gTtg = -here->VDMOSgtempg;
|
||||
gTtdp = -here->VDMOSgtempd;
|
||||
gTtt = -here->VDMOSgtempT;
|
||||
gTtsp = gTtg + gTtdp;
|
||||
}
|
||||
|
||||
/*
|
||||
* VDMOS cap model parameters
|
||||
*/
|
||||
|
|
@ -46,7 +74,12 @@ VDMOSacLoad(GENmodel *inModel, CKTcircuit *ckt)
|
|||
xgs = capgs * ckt->CKTomega;
|
||||
xgd = capgd * ckt->CKTomega;
|
||||
|
||||
/* bulk diode */
|
||||
xcgT = cgT * ckt->CKTomega;
|
||||
xcdT = cdT * ckt->CKTomega;
|
||||
xcsT = -(cgT + cdT) * ckt->CKTomega;
|
||||
xcTt = cTt * ckt->CKTomega;
|
||||
|
||||
/* body diode */
|
||||
double gspr, geq, xceq;
|
||||
gspr = here->VDIOtConductance;
|
||||
geq = *(ckt->CKTstate0 + here->VDIOconduct);
|
||||
|
|
@ -62,6 +95,7 @@ VDMOSacLoad(GENmodel *inModel, CKTcircuit *ckt)
|
|||
*(here->VDMOSGPspPtr +1) -= xgs;
|
||||
*(here->VDMOSDPgpPtr +1) -= xgd;
|
||||
*(here->VDMOSSPgpPtr +1) -= xgs;
|
||||
|
||||
*(here->VDMOSDdPtr) += here->VDMOSdrainConductance;
|
||||
*(here->VDMOSSsPtr) += here->VDMOSsourceConductance;
|
||||
*(here->VDMOSDPdpPtr) += here->VDMOSdrainConductance+
|
||||
|
|
@ -78,10 +112,10 @@ VDMOSacLoad(GENmodel *inModel, CKTcircuit *ckt)
|
|||
*(here->VDMOSSPdpPtr) -= here->VDMOSgds+xrev*(here->VDMOSgm);
|
||||
/* gate resistor */
|
||||
*(here->VDMOSGgPtr) += (here->VDMOSgateConductance);
|
||||
*(here->VDMOSGPgpPtr) += (here->VDMOSgateConductance)/* + ?? FIXME */;
|
||||
*(here->VDMOSGPgpPtr) += (here->VDMOSgateConductance);
|
||||
*(here->VDMOSGgpPtr) -= here->VDMOSgateConductance;
|
||||
*(here->VDMOSGPgPtr) -= here->VDMOSgateConductance;
|
||||
/* bulk diode */
|
||||
/* body diode */
|
||||
*(here->VDMOSSsPtr) += gspr;
|
||||
*(here->VDMOSDdPtr) += geq;
|
||||
*(here->VDMOSDdPtr +1) += xceq;
|
||||
|
|
@ -93,6 +127,29 @@ VDMOSacLoad(GENmodel *inModel, CKTcircuit *ckt)
|
|||
*(here->VDIORPsPtr) -= gspr;
|
||||
*(here->VDIORPdPtr) -= geq;
|
||||
*(here->VDIORPdPtr +1) -= xceq;
|
||||
if (selfheat)
|
||||
{
|
||||
*(here->VDMOSDPtempPtr) += GmT;
|
||||
*(here->VDMOSSPtempPtr) += -GmT;
|
||||
|
||||
*(here->VDMOSTemptempPtr) += gTtt + 1/model->VDMOSrthjc;
|
||||
*(here->VDMOSTempgpPtr) += gTtg;
|
||||
*(here->VDMOSTempdpPtr) += gTtdp;
|
||||
*(here->VDMOSTempspPtr) += gTtsp;
|
||||
*(here->VDMOSTemptcasePtr) += -1/model->VDMOSrthjc;
|
||||
*(here->VDMOSTcasetempPtr) += -1/model->VDMOSrthjc;
|
||||
*(here->VDMOSTcasetcasePtr) += 1/model->VDMOSrthjc + 1/model->VDMOSrthca;
|
||||
*(here->VDMOSTptpPtr) += 1/model->VDMOSrthca;
|
||||
*(here->VDMOSTptcasePtr) += -1/model->VDMOSrthca;
|
||||
*(here->VDMOSTcasetpPtr) += -1/model->VDMOSrthca;
|
||||
*(here->VDMOSCktTtpPtr) += 1.0;
|
||||
*(here->VDMOSTpcktTPtr) += 1.0;
|
||||
|
||||
*(here->VDMOSTemptempPtr + 1) += xcTt;
|
||||
*(here->VDMOSDPtempPtr + 1) += xcdT;
|
||||
*(here->VDMOSSPtempPtr + 1) += xcsT;
|
||||
*(here->VDMOSGPtempPtr + 1) += xcgT;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
|
|
|
|||
|
|
@ -43,19 +43,22 @@ VDMOSask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value,
|
|||
return(OK);
|
||||
case VDMOS_L:
|
||||
value->rValue = here->VDMOSl;
|
||||
return(OK);
|
||||
return(OK);
|
||||
case VDMOS_W:
|
||||
value->rValue = here->VDMOSw;
|
||||
return(OK);
|
||||
return(OK);
|
||||
case VDMOS_OFF:
|
||||
value->rValue = here->VDMOSoff;
|
||||
return(OK);
|
||||
value->iValue = here->VDMOSoff;
|
||||
return(OK);
|
||||
case VDMOS_TNODEOUT:
|
||||
value->iValue = here->VDMOStnodeout;
|
||||
return(OK);
|
||||
case VDMOS_IC_VDS:
|
||||
value->rValue = here->VDMOSicVDS;
|
||||
return(OK);
|
||||
return(OK);
|
||||
case VDMOS_IC_VGS:
|
||||
value->rValue = here->VDMOSicVGS;
|
||||
return(OK);
|
||||
return(OK);
|
||||
case VDMOS_DNODE:
|
||||
value->iValue = here->VDMOSdNode;
|
||||
return(OK);
|
||||
|
|
@ -65,6 +68,9 @@ VDMOSask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value,
|
|||
case VDMOS_SNODE:
|
||||
value->iValue = here->VDMOSsNode;
|
||||
return(OK);
|
||||
case VDMOS_TNODE:
|
||||
value->iValue = here->VDMOStempNode;
|
||||
return(OK);
|
||||
case VDMOS_SNODEPRIME:
|
||||
value->iValue = here->VDMOSsNodePrime;
|
||||
return(OK);
|
||||
|
|
@ -89,15 +95,6 @@ VDMOSask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value,
|
|||
case VDMOS_VON:
|
||||
value->rValue = here->VDMOSvon;
|
||||
return(OK);
|
||||
case VDMOS_VDSAT:
|
||||
value->rValue = here->VDMOSvdsat;
|
||||
return(OK);
|
||||
case VDMOS_SOURCEVCRIT:
|
||||
value->rValue = here->VDMOSsourceVcrit;
|
||||
return(OK);
|
||||
case VDMOS_DRAINVCRIT:
|
||||
value->rValue = here->VDMOSdrainVcrit;
|
||||
return(OK);
|
||||
case VDMOS_CD:
|
||||
value->rValue = here->VDMOScd;
|
||||
return(OK);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
VDMOS: 2018 Holger Vogt, 2020 Dietmar Warning
|
||||
**********/
|
||||
|
||||
#ifndef VDMOS
|
||||
|
|
@ -41,10 +42,15 @@ typedef struct sVDMOSinstance {
|
|||
const int VDMOSdNode; /* number of the gate node of the mosfet */
|
||||
const int VDMOSgNode; /* number of the gate node of the mosfet */
|
||||
const int VDMOSsNode; /* number of the source node of the mosfet */
|
||||
int VDMOStempNode; /* number of the temperature node of the mosfet */
|
||||
int VDMOStcaseNode; /* number of the 2nd temperature node of the mosfet */
|
||||
int VDMOSdNodePrime; /* number of the internal drain node of the mosfet */
|
||||
int VDMOSsNodePrime; /* number of the internal source node of the mosfet */
|
||||
int VDMOSgNodePrime; /* number of the internal gate node of the mosfet */
|
||||
int VDIOposPrimeNode; /* number of the internal node of the bulk diode */
|
||||
int VDMOStNodePrime; /* number of the internal temp node between voltage source and Rthca */
|
||||
int VDIOposPrimeNode; /* number of the internal node of the body diode */
|
||||
|
||||
int VDMOSvcktTbranch; /* equation number of branch equation added for cktTemp source */
|
||||
|
||||
double VDMOSm; /* parallel device multiplier */
|
||||
|
||||
|
|
@ -52,42 +58,37 @@ typedef struct sVDMOSinstance {
|
|||
double VDMOSw; /* the width of the channel region */
|
||||
double VDMOSsourceConductance; /*conductance of source(or 0):set in setup*/
|
||||
double VDMOSdrainConductance; /*conductance of drain(or 0):set in setup*/
|
||||
double VDMOSdrainResistance; /*resistance of drain(or 0): set in temp*/
|
||||
double VDMOSqsResistance; /*resistance of drain: set in temp*/
|
||||
double VDMOSgateConductance; /*conductance of gate(or 0):set in setup*/
|
||||
double VDMOSdsConductance; /*conductance of drain to source:set in setup*/
|
||||
double VDMOStemp; /* operating temperature of this instance */
|
||||
double VDMOSdtemp; /* operating temperature of the instance relative to circuit temperature*/
|
||||
int VDMOStnodeout; /* flag indicate self heating on */
|
||||
|
||||
double VDMOStTransconductance; /* temperature corrected transconductance*/
|
||||
double VDMOStPhi; /* temperature corrected Phi */
|
||||
double VDMOStVto; /* temperature corrected Vto */
|
||||
double VDMOStSatCur; /* temperature corrected saturation Cur. */
|
||||
double VDMOStVth; /* temperature corrected Vth */
|
||||
|
||||
double VDMOSicVDS; /* initial condition D-S voltage */
|
||||
double VDMOSicVGS; /* initial condition G-S voltage */
|
||||
double VDMOSvon;
|
||||
double VDMOSvdsat;
|
||||
double VDMOSsourceVcrit; /* Vcrit for pos. vds */
|
||||
double VDMOSdrainVcrit; /* Vcrit for pos. vds */
|
||||
double VDMOScd;
|
||||
double VDMOSgm;
|
||||
double VDMOSgds;
|
||||
double VDMOSf2d;
|
||||
double VDMOSf3d;
|
||||
double VDMOSf4d;
|
||||
double VDMOSf2s;
|
||||
double VDMOSf3s;
|
||||
double VDMOSf4s;
|
||||
|
||||
double VDIOcap;
|
||||
double VDIOtSatCur; /* temperature corrected saturation Cur. density*/
|
||||
double VDIOtSatCur; /* temperature corrected saturation Cur. density*/
|
||||
double VDIOinitCond;
|
||||
double VDIOtVcrit;
|
||||
double VDIOconductance;
|
||||
double VDIOtConductance;
|
||||
double VDIOtBrkdwnV;
|
||||
double VDIOtJctCap;
|
||||
double VDIOtDepCap; /* temperature adjusted transition point in */
|
||||
/* the cureve matching Fc * Vj */
|
||||
double VDIOtJctPot; /* temperature corrected Bulk potential */
|
||||
/* the curve matching Fc * Vj */
|
||||
double VDIOtJctPot; /* temperature corrected junction potential */
|
||||
double VDIOtGradingCoeff;
|
||||
|
||||
double VDIOtTransitTime;
|
||||
|
|
@ -95,6 +96,16 @@ typedef struct sVDMOSinstance {
|
|||
double VDIOtF2;
|
||||
double VDIOtF3;
|
||||
|
||||
double VDMOSTempSH; /* for portability of SH temp to noise analysis */
|
||||
|
||||
double VDMOSgmT;
|
||||
double VDMOSgtempg;
|
||||
double VDMOSgtempd;
|
||||
double VDMOSgtempT;
|
||||
double VDMOScgT;
|
||||
double VDMOScdT;
|
||||
double VDMOScth; /* current alias power */
|
||||
|
||||
/*
|
||||
* naming convention:
|
||||
* x = vgs
|
||||
|
|
@ -135,21 +146,20 @@ typedef struct sVDMOSinstance {
|
|||
|
||||
int VDMOSmode; /* device mode : 1 = normal, -1 = inverse */
|
||||
|
||||
|
||||
unsigned VDMOSoff:1; /* non-zero to indicate device is off for dc analysis*/
|
||||
unsigned VDMOStempGiven :1; /* instance temperature specified */
|
||||
unsigned VDMOSdtempGiven :1; /* instance delta temperature specified */
|
||||
unsigned VDMOSmGiven :1;
|
||||
unsigned VDMOSlGiven :1;
|
||||
unsigned VDMOSwGiven :1;
|
||||
unsigned VDMOSdNodePrimeSet :1;
|
||||
unsigned VDMOSsNodePrimeSet :1;
|
||||
unsigned VDMOSdNodePrimeSet :1;
|
||||
unsigned VDMOSsNodePrimeSet :1;
|
||||
unsigned VDMOSicVDSGiven :1;
|
||||
unsigned VDMOSicVGSGiven :1;
|
||||
unsigned VDMOSvonGiven :1;
|
||||
unsigned VDMOStnodeoutGiven : 1; /* flag indicate self heating on */
|
||||
unsigned VDMOSvonGiven : 1;
|
||||
unsigned VDMOSvdsatGiven :1;
|
||||
unsigned VDMOSmodeGiven :1;
|
||||
|
||||
unsigned VDMOSmodeGiven :1;
|
||||
|
||||
double *VDMOSDdPtr; /* pointer to sparse matrix element at
|
||||
* (Drain node,drain node) */
|
||||
|
|
@ -201,7 +211,7 @@ typedef struct sVDMOSinstance {
|
|||
* (source node, drain node) */
|
||||
double *VDMOSSdPtr; /* pointer to sparse matrix element at
|
||||
* (drain node, source node) */
|
||||
/* bulk diode */
|
||||
/* body diode */
|
||||
double *VDIORPdPtr; /* pointer to sparse matrix element at
|
||||
* (diode prime node, drain node) */
|
||||
double *VDIODrpPtr; /* pointer to sparse matrix element at
|
||||
|
|
@ -212,32 +222,57 @@ typedef struct sVDMOSinstance {
|
|||
* (source node, diode prime node) */
|
||||
double *VDIORPsPtr; /* pointer to sparse matrix element at
|
||||
* (diode prime node, source node) */
|
||||
/* self heating */
|
||||
double *VDMOSTemptempPtr;
|
||||
double *VDMOSTempdpPtr;
|
||||
double *VDMOSTempspPtr;
|
||||
double *VDMOSTempgpPtr;
|
||||
double *VDMOSGPtempPtr;
|
||||
double *VDMOSDPtempPtr;
|
||||
double *VDMOSSPtempPtr;
|
||||
|
||||
double *VDMOSTcasetcasePtr; /* for Rthjc */
|
||||
double *VDMOSTcasetempPtr;
|
||||
double *VDMOSTemptcasePtr;
|
||||
|
||||
double *VDMOSTptpPtr; /* for Rthca */
|
||||
double *VDMOSTptcasePtr;
|
||||
double *VDMOSTcasetpPtr;
|
||||
|
||||
double *VDMOSCktTcktTPtr; /* for VcktTemp */
|
||||
double *VDMOSCktTtpPtr;
|
||||
double *VDMOSTpcktTPtr;
|
||||
|
||||
} VDMOSinstance ;
|
||||
|
||||
#define VDMOSvgs VDMOSstates+ 0 /* gate-source voltage */
|
||||
#define VDMOSvds VDMOSstates+ 1 /* drain-source voltage */
|
||||
#define VDMOSdeltemp VDMOSstates+ 2
|
||||
|
||||
#define VDMOScapgs VDMOSstates+2 /* gate-source capacitor value */
|
||||
#define VDMOSqgs VDMOSstates+ 3 /* gate-source capacitor charge */
|
||||
#define VDMOScqgs VDMOSstates+ 4 /* gate-source capacitor current */
|
||||
#define VDMOScapgs VDMOSstates+3 /* gate-source capacitor value */
|
||||
#define VDMOSqgs VDMOSstates+ 4 /* gate-source capacitor charge */
|
||||
#define VDMOScqgs VDMOSstates+ 5 /* gate-source capacitor current */
|
||||
|
||||
#define VDMOScapgd VDMOSstates+ 5 /* gate-drain capacitor value */
|
||||
#define VDMOSqgd VDMOSstates+ 6 /* gate-drain capacitor charge */
|
||||
#define VDMOScqgd VDMOSstates+ 7 /* gate-drain capacitor current */
|
||||
#define VDMOScapgd VDMOSstates+ 6 /* gate-drain capacitor value */
|
||||
#define VDMOSqgd VDMOSstates+ 7 /* gate-drain capacitor charge */
|
||||
#define VDMOScqgd VDMOSstates+ 8 /* gate-drain capacitor current */
|
||||
|
||||
#define VDIOvoltage VDMOSstates+ 8
|
||||
#define VDIOcurrent VDMOSstates+ 9
|
||||
#define VDIOconduct VDMOSstates+ 10
|
||||
#define VDIOcapCharge VDMOSstates+ 11
|
||||
#define VDIOcapCurrent VDMOSstates+ 12
|
||||
#define VDIOvoltage VDMOSstates+ 9
|
||||
#define VDIOcurrent VDMOSstates+ 10
|
||||
#define VDIOconduct VDMOSstates+ 11
|
||||
#define VDIOcapCharge VDMOSstates+ 12
|
||||
#define VDIOcapCurrent VDMOSstates+ 13
|
||||
|
||||
#define VDMOSnumStates 13
|
||||
#define VDMOScapth VDMOSstates+ 14 /* thermal capacitor value */
|
||||
#define VDMOSqth VDMOSstates+ 15 /* thermal capacitor charge */
|
||||
#define VDMOScqth VDMOSstates+ 16 /* thermal capacitor current */
|
||||
|
||||
#define VDMOSnumStates 17
|
||||
|
||||
|
||||
/* per model data */
|
||||
|
||||
/* NOTE: parameters marked 'input - use xxxx' are paramters for
|
||||
/* NOTE: parameters marked 'input - use xxxx' are parameters for
|
||||
* which a temperature correction is applied in VDMOStemp, thus
|
||||
* the VDMOSxxxx value in the per-instance structure should be used
|
||||
* instead in all calculations
|
||||
|
|
@ -262,7 +297,7 @@ typedef struct sVDMOSmodel { /* model structure for a resistor */
|
|||
double VDMOSqsVoltage;
|
||||
double VDMOStransconductance; /* input - use tTransconductance */
|
||||
double VDMOSoxideCapFactor;
|
||||
double VDMOSvt0; /* input - use tVto */
|
||||
double VDMOSvth0; /* input - use tVth */
|
||||
double VDMOSphi; /* input - use tPhi */
|
||||
double VDMOSlambda;
|
||||
double VDMOStheta;
|
||||
|
|
@ -273,34 +308,44 @@ typedef struct sVDMOSmodel { /* model structure for a resistor */
|
|||
double VDMOScgdmax;
|
||||
double VDMOSa;
|
||||
double VDMOScgs;
|
||||
double VDMOSsubsl;
|
||||
double VDMOSsubshift;
|
||||
double VDMOSksubthres;
|
||||
double VDMOSmtr;
|
||||
|
||||
/* bulk diode */
|
||||
/* body diode */
|
||||
double VDIOjunctionCap; /* input - use tCj */
|
||||
double VDIOjunctionPot; /* input - use tBulkPot */
|
||||
double VDIOjunctionPot; /* input - use tJctPot */
|
||||
double VDIOdepletionCapCoeff;
|
||||
double VDIOjctSatCur; /* input - use tSatCur */
|
||||
double VDMOSDbv;
|
||||
double VDMOSDibv;
|
||||
double VDMOSbv;
|
||||
double VDMOSibv;
|
||||
double VDIObrkdEmissionCoeff;
|
||||
double VDIOresistance;
|
||||
double VDIOresistTemp1;
|
||||
double VDIOresistTemp2;
|
||||
double VDIOconductance;
|
||||
double VDMOSrds;
|
||||
double VDMOSDn;
|
||||
double VDMOSn;
|
||||
double VDIOtransitTime;
|
||||
double VDIOtranTimeTemp1;
|
||||
double VDIOtranTimeTemp2;
|
||||
double VDMOSDeg;
|
||||
double VDMOSDxti;
|
||||
double VDMOSeg;
|
||||
double VDMOSxti;
|
||||
double VDIOgradCoeff;
|
||||
double VDIOgradCoeffTemp1;
|
||||
double VDIOgradCoeffTemp2;
|
||||
|
||||
double VDMOSrthjc;
|
||||
double VDMOSrthca;
|
||||
double VDMOScthj;
|
||||
double VDMOSmu;
|
||||
double VDMOStexp0;
|
||||
double VDMOStexp1;
|
||||
double VDMOStcvth;
|
||||
|
||||
double VDMOSvgsMax;
|
||||
double VDMOSvgdMax;
|
||||
double VDMOSvdsMax;
|
||||
double VDMOSvgsrMax;
|
||||
double VDMOSvgdrMax;
|
||||
|
||||
unsigned VDMOStypeGiven :1;
|
||||
unsigned VDIOjctSatCurGiven :1;
|
||||
unsigned VDMOSdrainResistanceGiven :1;
|
||||
|
|
@ -310,7 +355,7 @@ typedef struct sVDMOSmodel { /* model structure for a resistor */
|
|||
unsigned VDMOSqsVoltageGiven :1;
|
||||
unsigned VDMOSqsGiven :1;
|
||||
unsigned VDMOStransconductanceGiven :1;
|
||||
unsigned VDMOSvt0Given :1;
|
||||
unsigned VDMOSvth0Given :1;
|
||||
unsigned VDIOgradCoeffGiven :1;
|
||||
unsigned VDIOdepletionCapCoeffGiven :1;
|
||||
unsigned VDMOSphiGiven :1;
|
||||
|
|
@ -324,23 +369,35 @@ typedef struct sVDMOSmodel { /* model structure for a resistor */
|
|||
unsigned VDMOScgdmaxGiven :1;
|
||||
unsigned VDMOScgsGiven :1;
|
||||
unsigned VDMOSaGiven :1;
|
||||
unsigned VDMOSsubslGiven :1;
|
||||
unsigned VDMOSsubshiftGiven :1;
|
||||
unsigned VDMOSksubthresGiven :1;
|
||||
unsigned VDMOSmtrGiven :1;
|
||||
|
||||
unsigned VDMOSDbvGiven :1;
|
||||
unsigned VDMOSDibvGiven :1;
|
||||
unsigned VDMOSbvGiven :1;
|
||||
unsigned VDMOSibvGiven :1;
|
||||
unsigned VDIOjunctionCapGiven :1;
|
||||
unsigned VDIOjunctionPotGiven :1;
|
||||
unsigned VDIObrkdEmissionCoeffGiven :1;
|
||||
unsigned VDIOresistanceGiven :1;
|
||||
unsigned VDMOSrdsGiven :1;
|
||||
unsigned VDMOSDnGiven :1;
|
||||
unsigned VDMOSnGiven :1;
|
||||
unsigned VDIOtransitTimeGiven :1;
|
||||
unsigned VDMOSDegGiven :1;
|
||||
unsigned VDMOSDxtiGiven :1;
|
||||
unsigned VDMOSegGiven :1;
|
||||
unsigned VDMOSxtiGiven :1;
|
||||
|
||||
unsigned VDMOSrthjcGiven :1;
|
||||
unsigned VDMOSrthcaGiven :1;
|
||||
unsigned VDMOScthjGiven :1;
|
||||
unsigned VDMOSmuGiven :1;
|
||||
unsigned VDMOStexp0Given :1;
|
||||
unsigned VDMOStexp1Given :1;
|
||||
unsigned VDMOStcvthGiven :1;
|
||||
|
||||
unsigned VDMOSvgsMaxGiven :1;
|
||||
unsigned VDMOSvgdMaxGiven :1;
|
||||
unsigned VDMOSvdsMaxGiven :1;
|
||||
unsigned VDMOSvgsrMaxGiven :1;
|
||||
unsigned VDMOSvgdrMaxGiven :1;
|
||||
} VDMOSmodel;
|
||||
|
||||
#ifndef NMOS
|
||||
|
|
@ -362,11 +419,12 @@ enum {
|
|||
VDMOS_TEMP,
|
||||
VDMOS_M,
|
||||
VDMOS_DTEMP,
|
||||
VDMOS_TNODEOUT,
|
||||
};
|
||||
|
||||
/* model paramerers */
|
||||
/* model parameters */
|
||||
enum {
|
||||
VDMOS_MOD_VTO = 101,
|
||||
VDMOS_MOD_VTH = 101,
|
||||
VDMOS_MOD_KP,
|
||||
VDMOS_MOD_PHI,
|
||||
VDMOS_MOD_LAMBDA,
|
||||
|
|
@ -394,7 +452,6 @@ enum {
|
|||
VDMOS_MOD_CGS,
|
||||
VDMOS_MOD_RB,
|
||||
VDMOS_MOD_MTRIODE,
|
||||
VDMOS_MOD_SUBSLOPE,
|
||||
VDMOS_MOD_SUBSHIFT,
|
||||
VDMOS_MOD_KSUBTHRES,
|
||||
VDMOS_MOD_BV,
|
||||
|
|
@ -405,6 +462,18 @@ enum {
|
|||
VDMOS_MOD_TT,
|
||||
VDMOS_MOD_EG,
|
||||
VDMOS_MOD_XTI,
|
||||
VDMOS_MOD_RTHJC,
|
||||
VDMOS_MOD_RTHCA,
|
||||
VDMOS_MOD_CTHJ,
|
||||
VDMOS_MOD_MU,
|
||||
VDMOS_MOD_TEXP0,
|
||||
VDMOS_MOD_TEXP1,
|
||||
VDMOS_MOD_TCVTH,
|
||||
VDMOS_MOD_VGS_MAX,
|
||||
VDMOS_MOD_VGD_MAX,
|
||||
VDMOS_MOD_VDS_MAX,
|
||||
VDMOS_MOD_VGSR_MAX,
|
||||
VDMOS_MOD_VGDR_MAX,
|
||||
};
|
||||
|
||||
/* device questions */
|
||||
|
|
@ -415,14 +484,13 @@ enum {
|
|||
VDMOS_DNODE,
|
||||
VDMOS_GNODE,
|
||||
VDMOS_SNODE,
|
||||
VDMOS_TNODE,
|
||||
VDMOS_TCASE,
|
||||
VDMOS_DNODEPRIME,
|
||||
VDMOS_SNODEPRIME,
|
||||
VDMOS_SOURCECONDUCT,
|
||||
VDMOS_DRAINCONDUCT,
|
||||
VDMOS_VON,
|
||||
VDMOS_VDSAT,
|
||||
VDMOS_SOURCEVCRIT,
|
||||
VDMOS_DRAINVCRIT,
|
||||
VDMOS_CD,
|
||||
VDMOS_GM,
|
||||
VDMOS_GDS,
|
||||
|
|
|
|||
|
|
@ -21,8 +21,7 @@ VDMOSdSetup(GENmodel *inModel, CKTcircuit *ckt)
|
|||
VDMOSmodel *model = (VDMOSmodel *) inModel;
|
||||
VDMOSinstance *here;
|
||||
double Beta;
|
||||
double DrainSatCur;
|
||||
double SourceSatCur;
|
||||
double OxideCap;
|
||||
double gm;
|
||||
double gds;
|
||||
double vgst;
|
||||
|
|
@ -52,11 +51,10 @@ VDMOSdSetup(GENmodel *inModel, CKTcircuit *ckt)
|
|||
|
||||
vt = CONSTKoverQ * here->VDMOStemp;
|
||||
|
||||
DrainSatCur = here->VDMOSm * here->VDMOStSatCur;
|
||||
SourceSatCur = here->VDMOSm * here->VDMOStSatCur;
|
||||
Beta = here->VDMOStTransconductance;
|
||||
|
||||
Beta = here->VDMOStTransconductance * here->VDMOSm *
|
||||
here->VDMOSw/here->VDMOSl;
|
||||
OxideCap = model->VDMOSoxideCapFactor * here->VDMOSl *
|
||||
here->VDMOSm * here->VDMOSw;
|
||||
|
||||
vgs = model->VDMOStype * (
|
||||
*(ckt->CKTrhsOld+here->VDMOSgNode) -
|
||||
|
|
@ -84,7 +82,7 @@ VDMOSdSetup(GENmodel *inModel, CKTcircuit *ckt)
|
|||
/*
|
||||
* this block of code evaluates the drain current and its
|
||||
* derivatives using the shichman-hodges model and the
|
||||
* charges associated with the gate, channel and bulk for
|
||||
* charges associated with the gate and channel for
|
||||
* mosfets
|
||||
*
|
||||
*/
|
||||
|
|
@ -93,59 +91,50 @@ VDMOSdSetup(GENmodel *inModel, CKTcircuit *ckt)
|
|||
* it is obvious that they can be made global
|
||||
*/
|
||||
{
|
||||
double betap;
|
||||
double von = here->VDMOStVth * model->VDMOStype;
|
||||
vgst = (here->VDMOSmode == 1 ? vgs : vgd) - von;
|
||||
vdsat = MAX(vgst, 0);
|
||||
double slope = model->VDMOSksubthres;
|
||||
double lambda = model->VDMOSlambda;
|
||||
double theta = model->VDMOStheta;
|
||||
double shift = model->VDMOSsubshift;
|
||||
double mtr = model->VDMOSmtr;
|
||||
|
||||
vgst=(here->VDMOSmode==1?vgs:vgd);
|
||||
vdsat=MAX(vgst,0);
|
||||
/* scale vds with mtr (except with lambda) */
|
||||
double vdss = vds*mtr*here->VDMOSmode;
|
||||
double t0 = 1 + lambda*vds;
|
||||
double t1 = 1 + theta*vgs;
|
||||
double betap = Beta*t0/t1;
|
||||
double dbetapdvgs = -Beta*theta*t0/(t1*t1);
|
||||
double dbetapdvds = Beta*lambda/t1;
|
||||
|
||||
if (vgst <= 0) {
|
||||
/*
|
||||
* cutoff region
|
||||
*/
|
||||
/* cdrain = 0 */
|
||||
gm=0;
|
||||
gds=0;
|
||||
gm2=gds2=0;
|
||||
gmds=0;
|
||||
gm3=gds3=0;
|
||||
gm2ds=gmds2=0;
|
||||
} else {
|
||||
/*
|
||||
* saturation region
|
||||
*/
|
||||
double t2 = exp((vgst-shift)/slope);
|
||||
vgst = slope * log(1 + t2);
|
||||
double dvgstdvgs = t2/(t2+1);
|
||||
|
||||
betap=Beta*(1+model->VDMOSlambda*(vds*here->VDMOSmode));
|
||||
/* cdrain = betap * vgst * vgst * 0.5; */
|
||||
if (vgst <= (vds*here->VDMOSmode)){
|
||||
gm=betap*vgst;
|
||||
gds=model->VDMOSlambda*Beta*vgst*vgst*.5;
|
||||
if (vgst <= vdss) {
|
||||
/* saturation region */
|
||||
gm = betap*vgst*dvgstdvgs + 0.5*dbetapdvgs*vgst*vgst;
|
||||
gds = .5*dbetapdvds*vgst*vgst;
|
||||
gm2 = betap;
|
||||
gds2 = 0;
|
||||
gmds = vgst*model->VDMOSlambda*Beta;
|
||||
gmds = Beta*lambda*vgst;
|
||||
gm3 = 0;
|
||||
gds3 = 0;
|
||||
gm2ds = Beta * model->VDMOSlambda;
|
||||
gm2ds = Beta*lambda;
|
||||
gmds2 = 0;
|
||||
|
||||
} else {
|
||||
/*
|
||||
* linear region
|
||||
*/
|
||||
/* cdrain = betap * vds * (vgst - vds/2); */
|
||||
gm=betap*(vds*here->VDMOSmode);
|
||||
gds= Beta * model->VDMOSlambda*(vgst*
|
||||
vds*here->VDMOSmode - vds*vds*0.5) +
|
||||
betap*(vgst - vds*here->VDMOSmode);
|
||||
}
|
||||
else {
|
||||
/* linear region */
|
||||
gm = betap*vdss*dvgstdvgs + vdss*dbetapdvgs*(vgst-.5*vdss);
|
||||
gds = vdss*dbetapdvds*(vgst-.5*vdss) + betap*mtr*(vgst-.5*vdss) - .5*vdss*betap*mtr;
|
||||
gm2 = 0;
|
||||
gds2 = 2*Beta * model->VDMOSlambda*(vgst -
|
||||
vds*here->VDMOSmode) - betap;
|
||||
gmds = Beta * model->VDMOSlambda* vds *
|
||||
here->VDMOSmode + betap;
|
||||
gds2 = 2*Beta * lambda*(vgst - vds*here->VDMOSmode) - betap;
|
||||
gmds = Beta * lambda * vds * here->VDMOSmode + betap;
|
||||
gm3=0;
|
||||
gds3 = -Beta*model->VDMOSlambda*3.;
|
||||
gds3 = -Beta*lambda*3.;
|
||||
gm2ds=0;
|
||||
gmds2 = 2*model->VDMOSlambda*Beta;
|
||||
}
|
||||
gmds2 = 2*lambda*Beta;
|
||||
}
|
||||
/*
|
||||
* finished
|
||||
|
|
@ -156,15 +145,6 @@ VDMOSdSetup(GENmodel *inModel, CKTcircuit *ckt)
|
|||
/*
|
||||
* COMPUTE EQUIVALENT DRAIN CURRENT SOURCE
|
||||
*/
|
||||
/*
|
||||
* now we do the hard part of the bulk-drain and bulk-source
|
||||
* diode - we evaluate the non-linear capacitance and
|
||||
* charge
|
||||
*
|
||||
* the basic equations are not hard, but the implementation
|
||||
* is somewhat long in an attempt to avoid log/exponential
|
||||
* evaluations
|
||||
*/
|
||||
/*
|
||||
* meyer's capacitor model
|
||||
*/
|
||||
|
|
@ -180,7 +160,6 @@ VDMOSdSetup(GENmodel *inModel, CKTcircuit *ckt)
|
|||
* expressions for the charge are available
|
||||
*/
|
||||
|
||||
|
||||
{
|
||||
|
||||
double phi;
|
||||
|
|
@ -191,7 +170,7 @@ VDMOSdSetup(GENmodel *inModel, CKTcircuit *ckt)
|
|||
/* von, vgst and vdsat have already been adjusted for
|
||||
possible source-drain interchange */
|
||||
phi = here->VDMOStPhi;
|
||||
cox = 0;/*FIXME: can we do disto without knowing the oxide thickness?*/
|
||||
cox = OxideCap; /*FIXME: using a guess for the oxide thickness of 1e-07 in vdmostemp.c */
|
||||
lcapgs2=lcapgs3=lcapgd2=lcapgd3=0;
|
||||
if (vgst <= 0) {
|
||||
lcapgs2 = cox/(3*phi);
|
||||
|
|
|
|||
|
|
@ -20,3 +20,4 @@ extern int VDMOSconvTest(GENmodel*,CKTcircuit*);
|
|||
extern int VDMOSdisto(int,GENmodel*,CKTcircuit*);
|
||||
extern int VDMOSnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
|
||||
extern int VDMOSdSetup(GENmodel*,CKTcircuit*);
|
||||
extern int VDMOSsoaCheck(CKTcircuit *, GENmodel *);
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ SPICEdev VDMOSinfo = {
|
|||
.DEVsenTrunc = NULL,
|
||||
.DEVdisto = VDMOSdisto,
|
||||
.DEVnoise = VDMOSnoise,
|
||||
.DEVsoaCheck = NULL,
|
||||
.DEVsoaCheck = VDMOSsoaCheck,
|
||||
.DEVinstSize = &VDMOSiSize,
|
||||
.DEVmodSize = &VDMOSmSize,
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
VDMOS: 2018 Holger Vogt
|
||||
VDMOS: 2018 Holger Vogt, 2020 Dietmar Warning
|
||||
**********/
|
||||
|
||||
#include "ngspice/ngspice.h"
|
||||
|
|
@ -14,9 +14,35 @@ VDMOS: 2018 Holger Vogt
|
|||
#include "ngspice/sperror.h"
|
||||
#include "ngspice/suffix.h"
|
||||
|
||||
/* VDMOSlimitlog(deltemp, deltemp_old, LIM_TOL, check)
|
||||
* Logarithmic damping the per-iteration change of deltemp beyond LIM_TOL.
|
||||
*/
|
||||
static double
|
||||
cweakinv2(double sl, double shift, double vgst, double vds, double lambda, double beta, double vt, double mtr, double theta);
|
||||
|
||||
VDMOSlimitlog(
|
||||
double deltemp,
|
||||
double deltemp_old,
|
||||
double LIM_TOL,
|
||||
int *check)
|
||||
{
|
||||
*check = 0;
|
||||
if (isnan (deltemp) || isnan (deltemp_old))
|
||||
{
|
||||
fprintf(stderr, "Alberto says: YOU TURKEY! The limiting function received NaN.\n");
|
||||
fprintf(stderr, "New prediction returns to 0.0!\n");
|
||||
deltemp = 0.0;
|
||||
*check = 1;
|
||||
}
|
||||
/* Logarithmic damping of deltemp beyond LIM_TOL */
|
||||
if (deltemp > deltemp_old + LIM_TOL) {
|
||||
deltemp = deltemp_old + LIM_TOL + log10((deltemp-deltemp_old)/LIM_TOL);
|
||||
*check = 1;
|
||||
}
|
||||
else if (deltemp < deltemp_old - LIM_TOL) {
|
||||
deltemp = deltemp_old - LIM_TOL - log10((deltemp_old-deltemp)/LIM_TOL);
|
||||
*check = 1;
|
||||
}
|
||||
return deltemp;
|
||||
}
|
||||
|
||||
int
|
||||
VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
|
||||
|
|
@ -27,8 +53,6 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
VDMOSmodel *model = (VDMOSmodel *)inModel;
|
||||
VDMOSinstance *here;
|
||||
double Beta;
|
||||
double DrainSatCur;
|
||||
double SourceSatCur;
|
||||
double arg;
|
||||
double cdhat;
|
||||
double cdrain;
|
||||
|
|
@ -55,14 +79,18 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
#ifndef PREDICTOR
|
||||
double xfact = 0.0;
|
||||
#endif
|
||||
int xnrm;
|
||||
int xrev;
|
||||
int xnrm, xrev;
|
||||
double capgs = 0.0; /* total gate-source capacitance */
|
||||
double capgd = 0.0; /* total gate-drain capacitance */
|
||||
int Check;
|
||||
double capth = 0.0; /* total thermal capacitance */
|
||||
int Check_mos, Check_diode;
|
||||
int error;
|
||||
|
||||
double CGBdummy;
|
||||
register int selfheat;
|
||||
double rd0T, rd1T, dBeta_dT, drd0T_dT, drd1T_dT, dIds_dT;
|
||||
double deldelTemp, delTemp, delTemp1, Temp, Vds, Vgs;
|
||||
double ceqqth=0.0;
|
||||
double GmT, gTtg, gTtdp, gTtt, gTtsp, gcTt=0.0;
|
||||
|
||||
/* loop through all the VDMOS device models */
|
||||
for (; model != NULL; model = VDMOSnextModel(model)) {
|
||||
|
|
@ -76,34 +104,60 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
for (here = VDMOSinstances(model); here != NULL;
|
||||
here = VDMOSnextInstance(here)) {
|
||||
|
||||
selfheat = (here->VDMOStnodeoutGiven) && (model->VDMOSrthjcGiven);
|
||||
if (selfheat)
|
||||
Check_mos = 1;
|
||||
else
|
||||
Check_mos = 0;
|
||||
|
||||
vt = CONSTKoverQ * here->VDMOStemp;
|
||||
Check = 1;
|
||||
|
||||
/* first, we compute a few useful values - these could be
|
||||
* pre-computed, but for historical reasons are still done
|
||||
* here. They may be moved at the expense of instance size
|
||||
*/
|
||||
|
||||
DrainSatCur = here->VDMOSm * here->VDMOStSatCur;
|
||||
SourceSatCur = here->VDMOSm * here->VDMOStSatCur;
|
||||
Beta = here->VDMOStTransconductance * here->VDMOSm *
|
||||
here->VDMOSw / here->VDMOSl;
|
||||
delTemp = 0.0;
|
||||
if ((ckt->CKTmode & MODEINITSMSIG)) {
|
||||
vgs = *(ckt->CKTstate0 + here->VDMOSvgs);
|
||||
vds = *(ckt->CKTstate0 + here->VDMOSvds);
|
||||
delTemp = *(ckt->CKTstate0 + here->VDMOSdeltemp);
|
||||
} else if ((ckt->CKTmode & MODEINITTRAN)) {
|
||||
vgs = *(ckt->CKTstate1 + here->VDMOSvgs);
|
||||
vds = *(ckt->CKTstate1 + here->VDMOSvds);
|
||||
delTemp = *(ckt->CKTstate1 + here->VDMOSdeltemp);
|
||||
} else if ((ckt->CKTmode & MODEINITJCT) && !here->VDMOSoff) {
|
||||
/* ok - not one of the simple cases, so we have to
|
||||
* look at all of the possibilities for why we were
|
||||
* called. We still just initialize the two voltages
|
||||
*/
|
||||
vds = model->VDMOStype * here->VDMOSicVDS;
|
||||
vgs = model->VDMOStype * here->VDMOSicVGS;
|
||||
delTemp = 0.0;
|
||||
if ((vds == 0.0) && (vgs == 0.0) &&
|
||||
((ckt->CKTmode & (MODETRAN | MODEAC|MODEDCOP |
|
||||
MODEDCTRANCURVE)) || (!(ckt->CKTmode & MODEUIC))))
|
||||
{
|
||||
vgs = model->VDMOStype * model->VDMOSvth0 + 0.1;
|
||||
vds = 0.0;
|
||||
}
|
||||
} else if ((ckt->CKTmode & (MODEINITJCT | MODEINITFIX)) && (here->VDMOSoff)) {
|
||||
delTemp = vgs = vds = 0.0;
|
||||
|
||||
/*
|
||||
* ok - now to do the start-up operations
|
||||
*
|
||||
* we must get values for vbs, vds, and vgs from somewhere
|
||||
* we must get values for vds and vgs from somewhere
|
||||
* so we either predict them or recover them from last iteration
|
||||
* These are the two most common cases - either a prediction
|
||||
* step or the general iteration step and they
|
||||
* share some code, so we put them first - others later on
|
||||
*/
|
||||
|
||||
if ((ckt->CKTmode & (MODEINITFLOAT | MODEINITPRED | MODEINITSMSIG
|
||||
| MODEINITTRAN)) ||
|
||||
((ckt->CKTmode & MODEINITFIX) && (!here->VDMOSoff))) {
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef PREDICTOR
|
||||
if (ckt->CKTmode & (MODEINITPRED | MODEINITTRAN)) {
|
||||
if (ckt->CKTmode & MODEINITPRED) {
|
||||
|
||||
/* predictor step */
|
||||
|
||||
|
|
@ -116,7 +170,13 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
*(ckt->CKTstate1 + here->VDMOSvds);
|
||||
vds = (1 + xfact)* (*(ckt->CKTstate1 + here->VDMOSvds))
|
||||
- (xfact * (*(ckt->CKTstate2 + here->VDMOSvds)));
|
||||
} else {
|
||||
*(ckt->CKTstate0 + here->VDMOSdeltemp) =
|
||||
*(ckt->CKTstate1 + here->VDMOSdeltemp);
|
||||
delTemp = (1 + xfact)* (*(ckt->CKTstate1 + here->VDMOSdeltemp))
|
||||
- (xfact * (*(ckt->CKTstate2 + here->VDMOSdeltemp)));
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif /* PREDICTOR */
|
||||
|
||||
/* general iteration */
|
||||
|
|
@ -127,6 +187,10 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
vds = model->VDMOStype * (
|
||||
*(ckt->CKTrhsOld + here->VDMOSdNodePrime) -
|
||||
*(ckt->CKTrhsOld + here->VDMOSsNodePrime));
|
||||
if (selfheat)
|
||||
delTemp = *(ckt->CKTrhsOld + here->VDMOStempNode);
|
||||
else
|
||||
delTemp = 0.0;
|
||||
#ifndef PREDICTOR
|
||||
}
|
||||
#endif /* PREDICTOR */
|
||||
|
|
@ -140,61 +204,73 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
delvds = vds - *(ckt->CKTstate0 + here->VDMOSvds);
|
||||
delvgd = vgd - vgdo;
|
||||
|
||||
deldelTemp = delTemp - *(ckt->CKTstate0 + here->VDMOSdeltemp);
|
||||
|
||||
/* these are needed for convergence testing */
|
||||
|
||||
if (here->VDMOSmode >= 0) {
|
||||
cdhat =
|
||||
here->VDMOScd
|
||||
+ here->VDMOSgm * delvgs
|
||||
+ here->VDMOSgds * delvds;
|
||||
here->VDMOScd
|
||||
+ here->VDMOSgm * delvgs
|
||||
+ here->VDMOSgds * delvds
|
||||
+ here->VDMOSgmT * deldelTemp;
|
||||
} else {
|
||||
cdhat =
|
||||
here->VDMOScd
|
||||
- here->VDMOSgm * delvgd
|
||||
+ here->VDMOSgds * delvds;
|
||||
here->VDMOScd
|
||||
- here->VDMOSgm * delvgd
|
||||
+ here->VDMOSgds * delvds
|
||||
+ here->VDMOSgmT * deldelTemp;
|
||||
}
|
||||
|
||||
#ifndef NOBYPASS
|
||||
/* now lets see if we can bypass (ugh) */
|
||||
if ((!(ckt->CKTmode &
|
||||
(MODEINITPRED | MODEINITTRAN | MODEINITSMSIG))) &&
|
||||
if ((!(ckt->CKTmode & MODEINITPRED)) &&
|
||||
(ckt->CKTbypass) &&
|
||||
(fabs(delvgs) < (ckt->CKTreltol *
|
||||
MAX(fabs(vgs),
|
||||
fabs(*(ckt->CKTstate0 +
|
||||
here->VDMOSvgs))) +
|
||||
ckt->CKTvoltTol)) &&
|
||||
(fabs(delvds) < (ckt->CKTreltol *
|
||||
MAX(fabs(vds),
|
||||
fabs(*(ckt->CKTstate0 +
|
||||
here->VDMOSvds))) +
|
||||
ckt->CKTvoltTol)) &&
|
||||
(fabs(cdhat - here->VDMOScd) < (ckt->CKTreltol *
|
||||
MAX(fabs(cdhat),
|
||||
fabs(here->VDMOScd)) +
|
||||
ckt->CKTabstol))) {
|
||||
/* bypass code */
|
||||
/* nothing interesting has changed since last
|
||||
* iteration on this device, so we just
|
||||
* copy all the values computed last iteration out
|
||||
* and keep going
|
||||
*/
|
||||
vgs = *(ckt->CKTstate0 + here->VDMOSvgs);
|
||||
vds = *(ckt->CKTstate0 + here->VDMOSvds);
|
||||
vgd = vgs - vds;
|
||||
cdrain = here->VDMOSmode * (here->VDMOScd);
|
||||
if (ckt->CKTmode & (MODETRAN | MODETRANOP)) {
|
||||
capgs = (*(ckt->CKTstate0 + here->VDMOScapgs) +
|
||||
*(ckt->CKTstate1 + here->VDMOScapgs));
|
||||
capgd = (*(ckt->CKTstate0 + here->VDMOScapgd) +
|
||||
*(ckt->CKTstate1 + here->VDMOScapgd));
|
||||
|
||||
}
|
||||
goto bypass;
|
||||
}
|
||||
(fabs(delvds) < (ckt->CKTreltol *
|
||||
MAX(fabs(vds),
|
||||
fabs(*(ckt->CKTstate0 +
|
||||
here->VDMOSvds))) +
|
||||
ckt->CKTvoltTol)) &&
|
||||
(fabs(cdhat - here->VDMOScd) < (ckt->CKTreltol *
|
||||
MAX(fabs(cdhat),
|
||||
fabs(here->VDMOScd)) +
|
||||
ckt->CKTabstol)) &&
|
||||
((here->VDMOStempNode == 0) ||
|
||||
(fabs(deldelTemp) < (ckt->CKTreltol * MAX(fabs(delTemp),
|
||||
fabs(*(ckt->CKTstate0+here->VDMOSdeltemp)))
|
||||
+ ckt->CKTvoltTol*1e4))))
|
||||
{
|
||||
/* bypass code */
|
||||
/* nothing interesting has changed since last
|
||||
* iteration on this device, so we just
|
||||
* copy all the values computed last iteration out
|
||||
* and keep going
|
||||
*/
|
||||
vgs = *(ckt->CKTstate0 + here->VDMOSvgs);
|
||||
vds = *(ckt->CKTstate0 + here->VDMOSvds);
|
||||
vgd = vgs - vds;
|
||||
delTemp = *(ckt->CKTstate0 + here->VDMOSdeltemp);
|
||||
/* calculate Vds for temperature conductance calculation
|
||||
in bypass (used later when filling Temp node matrix) */
|
||||
Vds = here->VDMOSmode > 0 ? vds : -vds;
|
||||
cdrain = here->VDMOSmode * (here->VDMOScd);
|
||||
if (ckt->CKTmode & (MODETRAN | MODETRANOP)) {
|
||||
capgs = (*(ckt->CKTstate0 + here->VDMOScapgs) +
|
||||
*(ckt->CKTstate1 + here->VDMOScapgs));
|
||||
capgd = (*(ckt->CKTstate0 + here->VDMOScapgd) +
|
||||
*(ckt->CKTstate1 + here->VDMOScapgd));
|
||||
capth = (*(ckt->CKTstate0 + here->VDMOScapth) +
|
||||
*(ckt->CKTstate1 + here->VDMOScapth));
|
||||
}
|
||||
goto bypass;
|
||||
}
|
||||
#endif /*NOBYPASS*/
|
||||
|
||||
|
||||
/* ok - bypass is out, do it the hard way */
|
||||
|
||||
von = model->VDMOStype * here->VDMOSvon;
|
||||
|
|
@ -202,7 +278,7 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
#ifndef NODELIMITING
|
||||
/*
|
||||
* limiting
|
||||
* we want to keep device voltages from changing
|
||||
* we want to keep device voltages from changing
|
||||
* so fast that the exponentials churn out overflows
|
||||
* and similar rudeness
|
||||
*/
|
||||
|
|
@ -222,31 +298,41 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
}
|
||||
vgs = vgd + vds;
|
||||
}
|
||||
if (selfheat)
|
||||
delTemp = VDMOSlimitlog(delTemp,
|
||||
*(ckt->CKTstate0 + here->VDMOSdeltemp),100,&Check_mos);
|
||||
else
|
||||
delTemp = 0.0;
|
||||
#endif /*NODELIMITING*/
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
/* ok - not one of the simple cases, so we have to
|
||||
* look at all of the possibilities for why we were
|
||||
* called. We still just initialize the three voltages
|
||||
*/
|
||||
|
||||
if ((ckt->CKTmode & MODEINITJCT) && !here->VDMOSoff) {
|
||||
vds = model->VDMOStype * here->VDMOSicVDS;
|
||||
vgs = model->VDMOStype * here->VDMOSicVGS;
|
||||
if ((vds == 0) && (vgs == 0) &&
|
||||
((ckt->CKTmode &
|
||||
(MODETRAN | MODEDCOP | MODEDCTRANCURVE)) ||
|
||||
(!(ckt->CKTmode & MODEUIC)))) {
|
||||
vgs = model->VDMOStype * here->VDMOStVto;
|
||||
vds = 0;
|
||||
}
|
||||
} else {
|
||||
vgs = vds = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Temp = delTemp + here->VDMOStemp;
|
||||
here->VDMOSTempSH = Temp; /* added for portability of SH Temp for noise analysis */
|
||||
|
||||
/* Calculate temperature dependent values for self-heating effect */
|
||||
if (selfheat) {
|
||||
double TempRatio = Temp / here->VDMOStemp;
|
||||
Beta = here->VDMOStTransconductance * pow(TempRatio,model->VDMOSmu);
|
||||
dBeta_dT = here->VDMOStTransconductance * model->VDMOSmu / (here->VDMOStemp * pow(TempRatio,1-model->VDMOSmu));
|
||||
rd0T = here->VDMOSdrainResistance * pow(TempRatio, model->VDMOStexp0);
|
||||
drd0T_dT = rd0T * model->VDMOStexp0 / Temp;
|
||||
rd1T = 0.0;
|
||||
drd1T_dT = 0.0;
|
||||
if (model->VDMOSqsGiven) {
|
||||
rd1T = here->VDMOSqsResistance * pow(TempRatio, model->VDMOStexp1);
|
||||
drd1T_dT = rd1T * model->VDMOStexp1 / Temp;
|
||||
}
|
||||
} else {
|
||||
Beta = here->VDMOStTransconductance;
|
||||
dBeta_dT = 0.0;
|
||||
rd0T = here->VDMOSdrainResistance;
|
||||
drd0T_dT = 0.0;
|
||||
rd1T = 0.0;
|
||||
if (model->VDMOSqsGiven)
|
||||
rd1T = here->VDMOSqsResistance;
|
||||
drd1T_dT = 0.0;
|
||||
}
|
||||
|
||||
/*
|
||||
* now all the preliminaries are over - we can start doing the
|
||||
|
|
@ -261,125 +347,63 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
if (vds >= 0) {
|
||||
/* normal mode */
|
||||
here->VDMOSmode = 1;
|
||||
Vds = vds;
|
||||
Vgs = vgs;
|
||||
} else {
|
||||
/* inverse mode */
|
||||
here->VDMOSmode = -1;
|
||||
Vds = -vds;
|
||||
Vgs = vgd;
|
||||
}
|
||||
|
||||
{
|
||||
/*
|
||||
* this block of code evaluates the drain current and its
|
||||
* derivatives using the shichman-hodges model and the
|
||||
* charges associated with the gate, channel and bulk for
|
||||
* charges associated with the gate and channel for
|
||||
* mosfets
|
||||
*
|
||||
*/
|
||||
|
||||
/* the following 2 variables are local to this code block until
|
||||
* it is obvious that they can be made global
|
||||
*/
|
||||
double betap;
|
||||
double vgst;
|
||||
|
||||
von = (model->VDMOSvt0*model->VDMOStype);
|
||||
vgst = (here->VDMOSmode == 1 ? vgs : vgd) - von;
|
||||
von = here->VDMOStVth * model->VDMOStype;
|
||||
double vgst = (here->VDMOSmode == 1 ? vgs : vgd) - von;
|
||||
vdsat = MAX(vgst, 0);
|
||||
if (model->VDMOSksubthresGiven) {
|
||||
/* Alternative simple weak inversion model, according to https://www.anasoft.co.uk/MOS1Model.htm
|
||||
/* Simple weak inversion model, according to https://www.anasoft.co.uk/MOS1Model.htm
|
||||
* Scale the voltage overdrive vgst logarithmically in weak inversion.
|
||||
* Best fits LTSPICE curves with shift=0
|
||||
* Drain current including subthreshold current */
|
||||
*/
|
||||
double slope = model->VDMOSksubthres;
|
||||
double lambda = model->VDMOSlambda;
|
||||
double theta = model->VDMOStheta;
|
||||
double shift = model->VDMOSsubshift;
|
||||
double mtr = model->VDMOSmtr;
|
||||
|
||||
double slope = model->VDMOSksubthres;
|
||||
double lambda = model->VDMOSlambda;
|
||||
double theta = model->VDMOStheta;
|
||||
double shift = model->VDMOSsubshift;
|
||||
double mtr = model->VDMOSmtr;
|
||||
/* scale vds with mtr (except with lambda) */
|
||||
double vdss = vds*mtr*here->VDMOSmode;
|
||||
double t0 = 1 + lambda*vds;
|
||||
double t1 = 1 + theta*vgs;
|
||||
double betap = Beta*t0/t1;
|
||||
double dbetapdvgs = -Beta*theta*t0/(t1*t1);
|
||||
double dbetapdvds = Beta*lambda/t1;
|
||||
double dbetapdT = dBeta_dT*t0/t1;
|
||||
|
||||
/* scale vds with mtr (except with lambda) */
|
||||
double vdss = vds*mtr*here->VDMOSmode;
|
||||
double t0 = 1 + lambda*vds;
|
||||
double t1 = 1 + theta*vgs;
|
||||
betap = Beta*t0/t1;
|
||||
double dbetapdvgs = -Beta*theta*t0/(t1*t1);
|
||||
double dbetapdvds = Beta*lambda/t1;
|
||||
double t2 = exp((vgst-shift)/slope);
|
||||
vgst = slope * log(1 + t2);
|
||||
double dvgstdvgs = t2/(t2+1);
|
||||
|
||||
double t2 = exp((vgst-shift)/slope);
|
||||
vgst = slope * log(1 + t2);
|
||||
double dvgstdvgs = t2/(t2+1);
|
||||
|
||||
if (vgst <= vdss) {
|
||||
/* saturation region */
|
||||
cdrain = betap*vgst*vgst*.5;
|
||||
here->VDMOSgm = betap*vgst*dvgstdvgs + 0.5*dbetapdvgs*vgst*vgst;
|
||||
here->VDMOSgds = .5*dbetapdvds*vgst*vgst;
|
||||
}
|
||||
else {
|
||||
/* linear region */
|
||||
cdrain = betap * vdss * (vgst - .5 * vdss);
|
||||
here->VDMOSgm = betap*vdss*dvgstdvgs + vdss*dbetapdvgs*(vgst-.5*vdss);
|
||||
here->VDMOSgds = vdss*dbetapdvds*(vgst-.5*vdss) + betap*mtr*(vgst-.5*vdss) - .5*vdss*betap*mtr;
|
||||
}
|
||||
if (vgst <= vdss) {
|
||||
/* saturation region */
|
||||
cdrain = betap * vgst*vgst * .5;
|
||||
here->VDMOSgm = betap*vgst*dvgstdvgs + 0.5*dbetapdvgs*vgst*vgst;
|
||||
here->VDMOSgds = .5*dbetapdvds*vgst*vgst;
|
||||
dIds_dT = dbetapdT * vgst*vgst * .5;
|
||||
}
|
||||
else if (model->VDMOSsubslGiven) {
|
||||
/* numerical differentiation for gd and gm with a delta of 2 mV */
|
||||
double vdsm = vds * here->VDMOSmode;
|
||||
double delta = 0.001;
|
||||
cdrain = cweakinv2(model->VDMOSsubsl, model->VDMOSsubshift, vgst, vdsm, model->VDMOSlambda,
|
||||
Beta, vt, model->VDMOSmtr, model->VDMOStheta);
|
||||
/* gd */
|
||||
double vds1 = vdsm + delta;
|
||||
double cdrp = cweakinv2(model->VDMOSsubsl, model->VDMOSsubshift, vgst, vds1, model->VDMOSlambda,
|
||||
Beta, vt, model->VDMOSmtr, model->VDMOStheta);
|
||||
vds1 = vdsm - delta;
|
||||
double cdrm = cweakinv2(model->VDMOSsubsl, model->VDMOSsubshift, vgst, vds1, model->VDMOSlambda,
|
||||
Beta, vt, model->VDMOSmtr, model->VDMOStheta);
|
||||
here->VDMOSgds = (cdrp - cdrm) / (2. * delta);
|
||||
/* gm */
|
||||
double vgst1 = vgst + delta;
|
||||
cdrp = cweakinv2(model->VDMOSsubsl, model->VDMOSsubshift, vgst1, vdsm, model->VDMOSlambda,
|
||||
Beta, vt, model->VDMOSmtr, model->VDMOStheta);
|
||||
vgst1 = vgst - delta;
|
||||
cdrm = cweakinv2(model->VDMOSsubsl, model->VDMOSsubshift, vgst1, vdsm, model->VDMOSlambda,
|
||||
Beta, vt, model->VDMOSmtr, model->VDMOStheta);
|
||||
here->VDMOSgm = (cdrp - cdrm) / (2. * delta);
|
||||
} else {
|
||||
double onfg, fgate, Betam, dfgdvg;
|
||||
onfg = 1.0+model->VDMOStheta*vgst;
|
||||
fgate = 1.0/onfg;
|
||||
Betam = Beta * fgate;
|
||||
dfgdvg = -model->VDMOStheta*fgate*fgate;
|
||||
if (vgst <= 0) {
|
||||
/*
|
||||
* cutoff region
|
||||
*/
|
||||
cdrain = 0;
|
||||
here->VDMOSgm = 0;
|
||||
here->VDMOSgds = 0;
|
||||
} else {
|
||||
/* scale vds with mtr */
|
||||
double mtr = model->VDMOSmtr;
|
||||
betap = Betam*(1 + model->VDMOSlambda*(vds*here->VDMOSmode));
|
||||
if (vgst <= (vds * here->VDMOSmode) * mtr) {
|
||||
/*
|
||||
* saturation region
|
||||
*/
|
||||
cdrain = betap*vgst*vgst*.5;
|
||||
here->VDMOSgm = betap*vgst * fgate + dfgdvg * cdrain;
|
||||
here->VDMOSgds = model->VDMOSlambda*Betam*vgst*vgst*.5;
|
||||
} else {
|
||||
/*
|
||||
* linear region
|
||||
*/
|
||||
cdrain = betap * (vds * here->VDMOSmode) * mtr *
|
||||
(vgst - .5 * (vds*here->VDMOSmode) * mtr);
|
||||
here->VDMOSgm = betap * (vds * here->VDMOSmode) * mtr * fgate + dfgdvg * cdrain;
|
||||
here->VDMOSgds = betap * (vgst - (vds * here->VDMOSmode) * mtr) +
|
||||
model->VDMOSlambda * Betam *
|
||||
(vds * here->VDMOSmode) * mtr *
|
||||
(vgst - .5 * (vds * here->VDMOSmode) * mtr);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* linear region */
|
||||
cdrain = betap * vdss * (vgst - .5 * vdss);
|
||||
here->VDMOSgm = betap*vdss*dvgstdvgs + vdss*dbetapdvgs*(vgst-.5*vdss);
|
||||
here->VDMOSgds = vdss*dbetapdvds*(vgst-.5*vdss) + betap*mtr*(vgst-.5*vdss) - .5*vdss*betap*mtr;
|
||||
dIds_dT = dbetapdT * vdss * (vgst - .5 * vdss);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -398,119 +422,7 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
|
||||
*(ckt->CKTstate0 + here->VDMOSvgs) = vgs;
|
||||
*(ckt->CKTstate0 + here->VDMOSvds) = vds;
|
||||
|
||||
|
||||
/*
|
||||
* vdmos capacitor model
|
||||
*/
|
||||
if (ckt->CKTmode & (MODETRAN | MODETRANOP | MODEINITSMSIG)) {
|
||||
/*
|
||||
* calculate gate - drain, gate - source capacitors
|
||||
* drain-source capacitor is evaluated with the bulk diode below
|
||||
*/
|
||||
/*
|
||||
* this just evaluates at the current time,
|
||||
* expects you to remember values from previous time
|
||||
* returns 1/2 of non-constant portion of capacitance
|
||||
* you must add in the other half from previous time
|
||||
* and the constant part
|
||||
*/
|
||||
DevCapVDMOS(vgd, cgdmin, cgdmax, a, cgs,
|
||||
(ckt->CKTstate0 + here->VDMOScapgs),
|
||||
(ckt->CKTstate0 + here->VDMOScapgd),
|
||||
&CGBdummy);
|
||||
|
||||
vgs1 = *(ckt->CKTstate1 + here->VDMOSvgs);
|
||||
vgd1 = vgs1 - *(ckt->CKTstate1 + here->VDMOSvds);
|
||||
if (ckt->CKTmode & (MODETRANOP | MODEINITSMSIG)) {
|
||||
capgs = 2 * *(ckt->CKTstate0 + here->VDMOScapgs);
|
||||
capgd = 2 * *(ckt->CKTstate0 + here->VDMOScapgd);
|
||||
} else {
|
||||
capgs = (*(ckt->CKTstate0 + here->VDMOScapgs) +
|
||||
*(ckt->CKTstate1 + here->VDMOScapgs));
|
||||
capgd = (*(ckt->CKTstate0 + here->VDMOScapgd) +
|
||||
*(ckt->CKTstate1 + here->VDMOScapgd));
|
||||
}
|
||||
/*
|
||||
|
||||
*/
|
||||
|
||||
#ifndef PREDICTOR
|
||||
if (ckt->CKTmode & (MODEINITPRED | MODEINITTRAN)) {
|
||||
*(ckt->CKTstate0 + here->VDMOSqgs) =
|
||||
(1 + xfact) * *(ckt->CKTstate1 + here->VDMOSqgs)
|
||||
- xfact * *(ckt->CKTstate2 + here->VDMOSqgs);
|
||||
*(ckt->CKTstate0 + here->VDMOSqgd) =
|
||||
(1 + xfact) * *(ckt->CKTstate1 + here->VDMOSqgd)
|
||||
- xfact * *(ckt->CKTstate2 + here->VDMOSqgd);
|
||||
} else {
|
||||
#endif /*PREDICTOR*/
|
||||
if (ckt->CKTmode & MODETRAN) {
|
||||
*(ckt->CKTstate0 + here->VDMOSqgs) = (vgs - vgs1)*capgs +
|
||||
*(ckt->CKTstate1 + here->VDMOSqgs);
|
||||
*(ckt->CKTstate0 + here->VDMOSqgd) = (vgd - vgd1)*capgd +
|
||||
*(ckt->CKTstate1 + here->VDMOSqgd);
|
||||
} else {
|
||||
/* TRANOP only */
|
||||
*(ckt->CKTstate0 + here->VDMOSqgs) = vgs*capgs;
|
||||
*(ckt->CKTstate0 + here->VDMOSqgd) = vgd*capgd;
|
||||
}
|
||||
#ifndef PREDICTOR
|
||||
}
|
||||
#endif /*PREDICTOR*/
|
||||
}
|
||||
#ifndef NOBYPASS
|
||||
bypass :
|
||||
#endif
|
||||
|
||||
if ((ckt->CKTmode & (MODEINITTRAN)) ||
|
||||
(!(ckt->CKTmode & (MODETRAN)))) {
|
||||
/*
|
||||
* initialize to zero charge conductances
|
||||
* and current
|
||||
*/
|
||||
gcgs = 0;
|
||||
ceqgs = 0;
|
||||
gcgd = 0;
|
||||
ceqgd = 0;
|
||||
} else {
|
||||
if (capgs == 0) *(ckt->CKTstate0 + here->VDMOScqgs) = 0;
|
||||
if (capgd == 0) *(ckt->CKTstate0 + here->VDMOScqgd) = 0;
|
||||
/*
|
||||
* calculate equivalent conductances and currents for
|
||||
* meyer"s capacitors
|
||||
*/
|
||||
error = NIintegrate(ckt, &gcgs, &ceqgs, capgs, here->VDMOSqgs);
|
||||
if (error) return(error);
|
||||
error = NIintegrate(ckt, &gcgd, &ceqgd, capgd, here->VDMOSqgd);
|
||||
if (error) return(error);
|
||||
ceqgs = ceqgs - gcgs*vgs + ckt->CKTag[0] *
|
||||
*(ckt->CKTstate0 + here->VDMOSqgs);
|
||||
ceqgd = ceqgd - gcgd*vgd + ckt->CKTag[0] *
|
||||
*(ckt->CKTstate0 + here->VDMOSqgd);
|
||||
}
|
||||
|
||||
/*
|
||||
* load current vector
|
||||
*/
|
||||
if (here->VDMOSmode >= 0) {
|
||||
xnrm = 1;
|
||||
xrev = 0;
|
||||
cdreq = model->VDMOStype*(cdrain - here->VDMOSgds*vds -
|
||||
here->VDMOSgm*vgs);
|
||||
} else {
|
||||
xnrm = 0;
|
||||
xrev = 1;
|
||||
cdreq = -(model->VDMOStype)*(cdrain - here->VDMOSgds*(-vds) -
|
||||
here->VDMOSgm*vgd);
|
||||
}
|
||||
*(ckt->CKTrhs + here->VDMOSgNodePrime) -=
|
||||
(model->VDMOStype * (ceqgs + ceqgd));
|
||||
*(ckt->CKTrhs + here->VDMOSdNodePrime) +=
|
||||
(-cdreq + model->VDMOStype * ceqgd);
|
||||
*(ckt->CKTrhs + here->VDMOSsNodePrime) +=
|
||||
cdreq + model->VDMOStype * ceqgs;
|
||||
|
||||
*(ckt->CKTstate0 + here->VDMOSdeltemp) = delTemp;
|
||||
|
||||
/* quasi saturation
|
||||
* according to Vincenzo d'Alessandro's Quasi-Saturation Model, simplified:
|
||||
|
|
@ -522,17 +434,194 @@ bypass :
|
|||
double vdsn = model->VDMOStype * (
|
||||
*(ckt->CKTrhsOld + here->VDMOSdNode) -
|
||||
*(ckt->CKTrhsOld + here->VDMOSsNode));
|
||||
double rd = model->VDMOSdrainResistance + model->VDMOSqsResistance *
|
||||
(vdsn / (vdsn + fabs(model->VDMOSqsVoltage)));
|
||||
here->VDMOSdrainConductance = 1 / rd;
|
||||
double rd = rd0T + rd1T * (vdsn / (vdsn + fabs(model->VDMOSqsVoltage)));
|
||||
if (rd > 0)
|
||||
here->VDMOSdrainConductance = 1 / rd + ckt->CKTgmin;
|
||||
else
|
||||
here->VDMOSdrainConductance = 1 / rd0T;
|
||||
} else {
|
||||
if (rd0T > 0)
|
||||
here->VDMOSdrainConductance = 1 / rd0T;
|
||||
}
|
||||
|
||||
if (selfheat) {
|
||||
GmT = dIds_dT;
|
||||
here->VDMOSgmT = GmT;
|
||||
} else {
|
||||
GmT = 0.0;
|
||||
here->VDMOSgmT = 0.0;
|
||||
}
|
||||
|
||||
if (selfheat) {
|
||||
/* note that sign is switched because power flows out
|
||||
of device into the temperature node. */
|
||||
here->VDMOSgtempg = -model->VDMOStype*here->VDMOSgm * Vds;
|
||||
here->VDMOSgtempT = -GmT * Vds;
|
||||
here->VDMOSgtempd = -model->VDMOStype* (here->VDMOSgds * Vds + cdrain);
|
||||
here->VDMOScth = - cdrain * Vds
|
||||
- 1/here->VDMOSdrainConductance * cdrain*cdrain
|
||||
- model->VDMOStype * (here->VDMOSgtempg * Vgs + here->VDMOSgtempd * Vds)
|
||||
- here->VDMOSgtempT * delTemp;
|
||||
}
|
||||
|
||||
/*
|
||||
* vdmos capacitor model
|
||||
*/
|
||||
if (ckt->CKTmode & (MODETRAN | MODETRANOP | MODEINITSMSIG)) {
|
||||
/*
|
||||
* calculate gate - drain, gate - source capacitors
|
||||
* drain-source capacitor is evaluated with the body diode below
|
||||
*/
|
||||
/*
|
||||
* this just evaluates at the current time,
|
||||
* expects you to remember values from previous time
|
||||
* returns 1/2 of non-constant portion of capacitance
|
||||
* you must add in the other half from previous time
|
||||
* and the constant part
|
||||
*/
|
||||
DevCapVDMOS(vgd, cgdmin, cgdmax, a, cgs,
|
||||
(ckt->CKTstate0 + here->VDMOScapgs),
|
||||
(ckt->CKTstate0 + here->VDMOScapgd));
|
||||
*(ckt->CKTstate0 + here->VDMOScapth) = model->VDMOScthj; /* always constant */
|
||||
|
||||
vgs1 = *(ckt->CKTstate1 + here->VDMOSvgs);
|
||||
vgd1 = vgs1 - *(ckt->CKTstate1 + here->VDMOSvds);
|
||||
delTemp1 = *(ckt->CKTstate1 + here->VDMOSdeltemp);
|
||||
if (ckt->CKTmode & (MODETRANOP | MODEINITSMSIG)) {
|
||||
capgs = 2 * *(ckt->CKTstate0 + here->VDMOScapgs);
|
||||
capgd = 2 * *(ckt->CKTstate0 + here->VDMOScapgd);
|
||||
capth = 2 * *(ckt->CKTstate0 + here->VDMOScapth);
|
||||
} else {
|
||||
capgs = (*(ckt->CKTstate0 + here->VDMOScapgs) +
|
||||
*(ckt->CKTstate1 + here->VDMOScapgs));
|
||||
capgd = (*(ckt->CKTstate0 + here->VDMOScapgd) +
|
||||
*(ckt->CKTstate1 + here->VDMOScapgd));
|
||||
capth = (*(ckt->CKTstate0 + here->VDMOScapth) +
|
||||
*(ckt->CKTstate1 + here->VDMOScapth));
|
||||
}
|
||||
|
||||
#ifndef PREDICTOR
|
||||
if (ckt->CKTmode & (MODEINITPRED | MODEINITTRAN)) {
|
||||
*(ckt->CKTstate0 + here->VDMOSqgs) =
|
||||
(1 + xfact) * *(ckt->CKTstate1 + here->VDMOSqgs)
|
||||
- xfact * *(ckt->CKTstate2 + here->VDMOSqgs);
|
||||
*(ckt->CKTstate0 + here->VDMOSqgd) =
|
||||
(1 + xfact) * *(ckt->CKTstate1 + here->VDMOSqgd)
|
||||
- xfact * *(ckt->CKTstate2 + here->VDMOSqgd);
|
||||
*(ckt->CKTstate0 + here->VDMOSqth) =
|
||||
(1 + xfact) * *(ckt->CKTstate1 + here->VDMOSqth)
|
||||
- xfact * *(ckt->CKTstate2 + here->VDMOSqth);
|
||||
} else {
|
||||
#endif /*PREDICTOR*/
|
||||
if (ckt->CKTmode & MODETRAN) {
|
||||
*(ckt->CKTstate0 + here->VDMOSqgs) = (vgs - vgs1)*capgs +
|
||||
*(ckt->CKTstate1 + here->VDMOSqgs);
|
||||
*(ckt->CKTstate0 + here->VDMOSqgd) = (vgd - vgd1)*capgd +
|
||||
*(ckt->CKTstate1 + here->VDMOSqgd);
|
||||
*(ckt->CKTstate0 + here->VDMOSqth) = (delTemp-delTemp1)*capth +
|
||||
*(ckt->CKTstate1 + here->VDMOSqth);
|
||||
} else {
|
||||
/* TRANOP only */
|
||||
*(ckt->CKTstate0 + here->VDMOSqgs) = vgs*capgs;
|
||||
*(ckt->CKTstate0 + here->VDMOSqgd) = vgd*capgd;
|
||||
*(ckt->CKTstate0 + here->VDMOSqth) = delTemp*capth;
|
||||
}
|
||||
#ifndef PREDICTOR
|
||||
}
|
||||
#endif /*PREDICTOR*/
|
||||
}
|
||||
#ifndef NOBYPASS
|
||||
bypass:
|
||||
#endif
|
||||
if ((ckt->CKTmode & (MODEINITTRAN)) ||
|
||||
(!(ckt->CKTmode & (MODETRAN)))) {
|
||||
/*
|
||||
* initialize to zero charge conductances
|
||||
* and current
|
||||
*/
|
||||
gcgs = 0;
|
||||
ceqgs = 0;
|
||||
gcgd = 0;
|
||||
ceqgd = 0;
|
||||
gcTt = 0.0;
|
||||
ceqqth = 0.0;
|
||||
} else {
|
||||
if (capgs == 0) *(ckt->CKTstate0 + here->VDMOScqgs) = 0;
|
||||
if (capgd == 0) *(ckt->CKTstate0 + here->VDMOScqgd) = 0;
|
||||
if (capth == 0) *(ckt->CKTstate0 + here->VDMOScqth) = 0;
|
||||
/*
|
||||
* calculate equivalent conductances and currents for
|
||||
* vdmos capacitors
|
||||
*/
|
||||
error = NIintegrate(ckt, &gcgs, &ceqgs, capgs, here->VDMOSqgs);
|
||||
if (error) return(error);
|
||||
error = NIintegrate(ckt, &gcgd, &ceqgd, capgd, here->VDMOSqgd);
|
||||
if (error) return(error);
|
||||
ceqgs = ceqgs - gcgs*vgs + ckt->CKTag[0] *
|
||||
*(ckt->CKTstate0 + here->VDMOSqgs);
|
||||
ceqgd = ceqgd - gcgd*vgd + ckt->CKTag[0] *
|
||||
*(ckt->CKTstate0 + here->VDMOSqgd);
|
||||
if (selfheat)
|
||||
{
|
||||
error = NIintegrate(ckt, &gcTt, &ceqqth, 0.0, here->VDMOSqth);
|
||||
gcTt = model->VDMOScthj * ckt->CKTag[0];
|
||||
ceqqth = *(ckt->CKTstate0 + here->VDMOScqth) - gcTt * delTemp;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* load current vector
|
||||
*/
|
||||
|
||||
if (selfheat) {
|
||||
if (here->VDMOSmode >= 0) {
|
||||
GmT = model->VDMOStype * here->VDMOSgmT;
|
||||
gTtg = here->VDMOSgtempg;
|
||||
gTtdp = here->VDMOSgtempd;
|
||||
gTtt = here->VDMOSgtempT;
|
||||
gTtsp = - (gTtg + gTtdp);
|
||||
} else {
|
||||
GmT = -model->VDMOStype * here->VDMOSgmT;
|
||||
gTtg = here->VDMOSgtempg;
|
||||
gTtsp = here->VDMOSgtempd;
|
||||
gTtt = here->VDMOSgtempT;
|
||||
gTtdp = - (gTtg + gTtsp);
|
||||
}
|
||||
} else {
|
||||
GmT = 0.0;
|
||||
gTtg = 0.0;
|
||||
gTtdp = 0.0;
|
||||
gTtt = 0.0;
|
||||
gTtsp = 0.0;
|
||||
}
|
||||
|
||||
if (here->VDMOSmode >= 0) {
|
||||
xnrm = 1;
|
||||
xrev = 0;
|
||||
cdreq = model->VDMOStype*(cdrain - here->VDMOSgds*vds
|
||||
- here->VDMOSgm*vgs)
|
||||
- GmT * delTemp;
|
||||
} else {
|
||||
xnrm = 0;
|
||||
xrev = 1;
|
||||
cdreq = -(model->VDMOStype)*(cdrain - here->VDMOSgds*(-vds)
|
||||
- here->VDMOSgm*vgd)
|
||||
- GmT * delTemp;
|
||||
}
|
||||
|
||||
*(ckt->CKTrhs + here->VDMOSgNodePrime) -= (model->VDMOStype * (ceqgs + ceqgd));
|
||||
*(ckt->CKTrhs + here->VDMOSdNodePrime) += (-cdreq + model->VDMOStype * ceqgd);
|
||||
*(ckt->CKTrhs + here->VDMOSsNodePrime) += cdreq + model->VDMOStype * ceqgs;
|
||||
if (selfheat) {
|
||||
*(ckt->CKTrhs + here->VDMOStempNode) -= here->VDMOScth + ceqqth; /* dissipated power + Cthj current */
|
||||
*(ckt->CKTrhs + here->VDMOSvcktTbranch) = ckt->CKTtemp-CONSTCtoK; /* ckt temperature */
|
||||
}
|
||||
|
||||
/*
|
||||
* load y matrix
|
||||
*/
|
||||
*(here->VDMOSDdPtr) += (here->VDMOSdrainConductance + here->VDMOSdsConductance);
|
||||
*(here->VDMOSGgPtr) += (here->VDMOSgateConductance); //((gcgd + gcgs + gcgb));
|
||||
*(here->VDMOSGgPtr) += (here->VDMOSgateConductance);
|
||||
*(here->VDMOSSsPtr) += (here->VDMOSsourceConductance + here->VDMOSdsConductance);
|
||||
*(here->VDMOSDPdpPtr) +=
|
||||
(here->VDMOSdrainConductance + here->VDMOSgds +
|
||||
|
|
@ -560,26 +649,40 @@ bypass :
|
|||
*(here->VDMOSDsPtr) += (-here->VDMOSdsConductance);
|
||||
*(here->VDMOSSdPtr) += (-here->VDMOSdsConductance);
|
||||
|
||||
if (selfheat)
|
||||
{
|
||||
(*(here->VDMOSDPtempPtr) += GmT);
|
||||
(*(here->VDMOSSPtempPtr) += -GmT);
|
||||
(*(here->VDMOSGPtempPtr) += 0.0);
|
||||
(*(here->VDMOSTemptempPtr) += gTtt + 1/model->VDMOSrthjc + gcTt);
|
||||
(*(here->VDMOSTempgpPtr) += gTtg);
|
||||
(*(here->VDMOSTempdpPtr) += gTtdp);
|
||||
(*(here->VDMOSTempspPtr) += gTtsp);
|
||||
(*(here->VDMOSTemptcasePtr) += -1/model->VDMOSrthjc);
|
||||
(*(here->VDMOSTcasetempPtr) += -1/model->VDMOSrthjc);
|
||||
(*(here->VDMOSTcasetcasePtr) += 1/model->VDMOSrthjc + 1/model->VDMOSrthca);
|
||||
(*(here->VDMOSTptpPtr) += 1/model->VDMOSrthca);
|
||||
(*(here->VDMOSTptcasePtr) += -1/model->VDMOSrthca);
|
||||
(*(here->VDMOSTcasetpPtr) += -1/model->VDMOSrthca);
|
||||
(*(here->VDMOSCktTtpPtr) += 1.0);
|
||||
(*(here->VDMOSTpcktTPtr) += 1.0);
|
||||
}
|
||||
|
||||
/* bulk diode model
|
||||
/* body diode model
|
||||
* Delivers reverse conduction and forward breakdown
|
||||
* of VDMOS transistor
|
||||
*/
|
||||
|
||||
double vd; /* current diode voltage */
|
||||
double vdtemp;
|
||||
double vte;
|
||||
double vtebrk, vbrknp;
|
||||
double cd, cdb, csat, cdeq;
|
||||
double czero;
|
||||
double czof2;
|
||||
double capd;
|
||||
double gd, gdb, gspr;
|
||||
double delvd; /* change in diode voltage temporary */
|
||||
double diffcharge, deplcharge, diffcap, deplcap;
|
||||
double evd, evrev;
|
||||
double evrev;
|
||||
#ifndef NOBYPASS
|
||||
double tol; /* temporary for tolerence calculations */
|
||||
double tol; /* temporary for tolerance calculations */
|
||||
#endif
|
||||
|
||||
cd = 0.0;
|
||||
|
|
@ -588,11 +691,11 @@ bypass :
|
|||
gdb = 0.0;
|
||||
csat = here->VDIOtSatCur;
|
||||
gspr = here->VDIOtConductance;
|
||||
vte = model->VDMOSDn * vt;
|
||||
vte = model->VDMOSn * vt;
|
||||
vtebrk = model->VDIObrkdEmissionCoeff * vt;
|
||||
vbrknp = here->VDIOtBrkdwnV;
|
||||
|
||||
Check = 1;
|
||||
Check_diode = 1;
|
||||
if (ckt->CKTmode & MODEINITSMSIG) {
|
||||
vd = *(ckt->CKTstate0 + here->VDIOvoltage);
|
||||
} else if (ckt->CKTmode & MODEINITTRAN) {
|
||||
|
|
@ -646,29 +749,31 @@ bypass :
|
|||
/*
|
||||
* limit new junction voltage
|
||||
*/
|
||||
if ((model->VDMOSDbvGiven) &&
|
||||
if ((model->VDMOSbvGiven) &&
|
||||
(vd < MIN(0, -vbrknp + 10 * vtebrk))) {
|
||||
double vdtemp;
|
||||
vdtemp = -(vd + vbrknp);
|
||||
vdtemp = DEVpnjlim(vdtemp,
|
||||
-(*(ckt->CKTstate0 + here->VDIOvoltage) +
|
||||
vbrknp), vtebrk,
|
||||
here->VDIOtVcrit, &Check);
|
||||
here->VDIOtVcrit, &Check_diode);
|
||||
vd = -(vdtemp + vbrknp);
|
||||
} else {
|
||||
vd = DEVpnjlim(vd, *(ckt->CKTstate0 + here->VDIOvoltage),
|
||||
vte, here->VDIOtVcrit, &Check);
|
||||
vte, here->VDIOtVcrit, &Check_diode);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* compute dc current and derivatives
|
||||
*/
|
||||
if (vd >= -3 * vte) { /* bottom current forward */
|
||||
double evd;
|
||||
|
||||
evd = exp(vd / vte);
|
||||
cdb = csat*(evd - 1);
|
||||
gdb = csat*evd / vte;
|
||||
|
||||
} else if ((!(model->VDMOSDbvGiven)) ||
|
||||
} else if ((!(model->VDMOSbvGiven)) ||
|
||||
vd >= -vbrknp) { /* reverse */
|
||||
|
||||
arg = 3 * vte / (vd*CONSTe);
|
||||
|
|
@ -696,6 +801,7 @@ bypass :
|
|||
/*
|
||||
* charge storage elements
|
||||
*/
|
||||
double czero, czof2, diffcharge, deplcharge, diffcap, deplcap;
|
||||
czero = here->VDIOtJctCap;
|
||||
if (vd < here->VDIOtDepCap) {
|
||||
arg = 1 - vd / here->VDIOtJctPot;
|
||||
|
|
@ -751,7 +857,7 @@ bypass :
|
|||
* check convergence
|
||||
*/
|
||||
|
||||
if (Check == 1) {
|
||||
if ((Check_mos == 1) || (Check_diode == 1)) {
|
||||
ckt->CKTnoncon++;
|
||||
ckt->CKTtroubleElt = (GENinstance *)here;
|
||||
}
|
||||
|
|
@ -761,7 +867,7 @@ bypass :
|
|||
*(ckt->CKTstate0 + here->VDIOconduct) = gd;
|
||||
|
||||
#ifndef NOBYPASS
|
||||
load :
|
||||
load:
|
||||
#endif
|
||||
/*
|
||||
* load current vector
|
||||
|
|
@ -789,47 +895,3 @@ load :
|
|||
}
|
||||
return(OK);
|
||||
}
|
||||
|
||||
|
||||
/* scaling function, sine function interpolating between 0 and 1
|
||||
* nf2: empirical setting of sine 'speed'
|
||||
*/
|
||||
|
||||
static double
|
||||
scalef(double nf2, double vgst)
|
||||
{
|
||||
double vgstsin = vgst / nf2;
|
||||
if (vgstsin > 1)
|
||||
return 1;
|
||||
else if (vgstsin < -1)
|
||||
return 0;
|
||||
else
|
||||
return 0.5 * sin(vgstsin * M_PI / 2) + 0.5;
|
||||
}
|
||||
|
||||
|
||||
/* Calculate D/S current including weak inversion.
|
||||
* Uses a single function covering weak-moderate-stong inversion, as well
|
||||
* as linear and saturation regions, with an interpolation method according to
|
||||
* Tvividis, McAndrew: "Operation and Modeling of the MOS Transistor", Oxford, 2011, p. 209.
|
||||
* A single parameter n sets the slope of the weak inversion current. The weak inversion
|
||||
* current is independent from vds, as in long channel devices.
|
||||
* The following modification has been added for VDMOS compatibility:
|
||||
* n and lambda are depending on vgst with a sine function interpolating between 0 and 1.
|
||||
*/
|
||||
|
||||
static double
|
||||
cweakinv2(double slope, double shift, double vgst, double vds, double lambda, double beta, double vt, double mtr, double theta)
|
||||
{
|
||||
double betam = beta / (1.0+theta*vgst);
|
||||
vgst += shift * (1 - scalef(0.5, vgst));
|
||||
double n = slope / 2.3 / 0.0256; /* Tsividis, p. 208 */
|
||||
double n1 = n + (1 - n) * scalef(0.7, vgst); /* n < n1 < 1 */
|
||||
double first = log(1 + exp(vgst / (2 * n1 * vt)));
|
||||
double second = log(1 + exp((vgst - vds * mtr * n1) / (2 * n1 * vt)));
|
||||
double cds =
|
||||
betam * n1 * 2 * vt * vt * (1 + scalef(1, vgst) * lambda * vds) *
|
||||
(first * first - second * second);
|
||||
return cds;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ VDMOSmAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value)
|
|||
case VDMOS_MOD_TNOM:
|
||||
value->rValue = model->VDMOStnom-CONSTCtoK;
|
||||
return(OK);
|
||||
case VDMOS_MOD_VTO:
|
||||
value->rValue = model->VDMOSvt0;
|
||||
case VDMOS_MOD_VTH:
|
||||
value->rValue = model->VDMOSvth0;
|
||||
return(OK);
|
||||
case VDMOS_MOD_KP:
|
||||
value->rValue = model->VDMOStransconductance;
|
||||
|
|
@ -57,9 +57,6 @@ VDMOSmAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value)
|
|||
case VDMOS_MOD_MTRIODE:
|
||||
value->rValue = model->VDMOSmtr;
|
||||
return(OK);
|
||||
case VDMOS_MOD_SUBSLOPE:
|
||||
value->rValue = model->VDMOSsubsl;
|
||||
return(OK);
|
||||
case VDMOS_MOD_SUBSHIFT:
|
||||
value->rValue = model->VDMOSsubshift;
|
||||
return(OK);
|
||||
|
|
@ -93,7 +90,7 @@ VDMOSmAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value)
|
|||
value->rValue = model->VDIOjctSatCur;
|
||||
return(OK);
|
||||
case VDMOS_MOD_N:
|
||||
value->rValue = model->VDMOSDn;
|
||||
value->rValue = model->VDMOSn;
|
||||
return(OK);
|
||||
case VDMOS_MOD_VJ:
|
||||
value->rValue = model->VDIOjunctionPot;
|
||||
|
|
@ -105,10 +102,10 @@ VDMOSmAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value)
|
|||
value->rValue = model->VDIOgradCoeff;
|
||||
return(OK);
|
||||
case VDMOS_MOD_BV:
|
||||
value->rValue = model->VDMOSDbv;
|
||||
value->rValue = model->VDMOSbv;
|
||||
return(OK);
|
||||
case VDMOS_MOD_IBV:
|
||||
value->rValue = model->VDMOSDibv;
|
||||
value->rValue = model->VDMOSibv;
|
||||
return(OK);
|
||||
case VDMOS_MOD_NBV:
|
||||
value->rValue = model->VDIObrkdEmissionCoeff;
|
||||
|
|
@ -123,10 +120,46 @@ VDMOSmAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value)
|
|||
value->rValue = model->VDIOtransitTime;
|
||||
return(OK);
|
||||
case VDMOS_MOD_EG:
|
||||
value->rValue = model->VDMOSDeg;
|
||||
value->rValue = model->VDMOSeg;
|
||||
return(OK);
|
||||
case VDMOS_MOD_XTI:
|
||||
value->rValue = model->VDMOSDxti;
|
||||
value->rValue = model->VDMOSxti;
|
||||
return(OK);
|
||||
case VDMOS_MOD_RTHJC:
|
||||
value->rValue = model->VDMOSrthjc;
|
||||
return(OK);
|
||||
case VDMOS_MOD_RTHCA:
|
||||
value->rValue = model->VDMOSrthca;
|
||||
return(OK);
|
||||
case VDMOS_MOD_CTHJ:
|
||||
value->rValue = model->VDMOScthj;
|
||||
return(OK);
|
||||
case VDMOS_MOD_MU:
|
||||
value->rValue = model->VDMOSmu;
|
||||
return(OK);
|
||||
case VDMOS_MOD_TEXP0:
|
||||
value->rValue = model->VDMOStexp0;
|
||||
return(OK);
|
||||
case VDMOS_MOD_TEXP1:
|
||||
value->rValue = model->VDMOStexp1;
|
||||
return(OK);
|
||||
case VDMOS_MOD_TCVTH:
|
||||
value->rValue = model->VDMOStcvth;
|
||||
return(OK);
|
||||
case VDMOS_MOD_VGS_MAX:
|
||||
value->rValue = model->VDMOSvgsMax;
|
||||
return(OK);
|
||||
case VDMOS_MOD_VGD_MAX:
|
||||
value->rValue = model->VDMOSvgdMax;
|
||||
return(OK);
|
||||
case VDMOS_MOD_VDS_MAX:
|
||||
value->rValue = model->VDMOSvdsMax;
|
||||
return(OK);
|
||||
case VDMOS_MOD_VGSR_MAX:
|
||||
value->rValue = model->VDMOSvgsrMax;
|
||||
return(OK);
|
||||
case VDMOS_MOD_VGDR_MAX:
|
||||
value->rValue = model->VDMOSvgdrMax;
|
||||
return(OK);
|
||||
default:
|
||||
return(E_BADPARM);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
VDMOS: 2018 Holger Vogt, 2020 Dietmar Warning
|
||||
**********/
|
||||
|
||||
#include "ngspice/ngspice.h"
|
||||
|
|
@ -19,9 +20,9 @@ VDMOSmParam(int param, IFvalue *value, GENmodel *inModel)
|
|||
model->VDMOStnom = value->rValue + CONSTCtoK;
|
||||
model->VDMOStnomGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_VTO:
|
||||
model->VDMOSvt0 = value->rValue;
|
||||
model->VDMOSvt0Given = TRUE;
|
||||
case VDMOS_MOD_VTH:
|
||||
model->VDMOSvth0 = value->rValue;
|
||||
model->VDMOSvth0Given = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_KP:
|
||||
model->VDMOStransconductance = value->rValue;
|
||||
|
|
@ -54,20 +55,14 @@ VDMOSmParam(int param, IFvalue *value, GENmodel *inModel)
|
|||
case VDMOS_MOD_RQ:
|
||||
model->VDMOSqsResistance = value->rValue;
|
||||
model->VDMOSqsResistanceGiven = TRUE;
|
||||
if (model->VDMOSqsVoltageGiven)
|
||||
model->VDMOSqsGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_VQ:
|
||||
model->VDMOSqsVoltage = value->rValue;
|
||||
model->VDMOSqsVoltageGiven = TRUE;
|
||||
if (model->VDMOSqsResistanceGiven)
|
||||
model->VDMOSqsGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_RB:
|
||||
model->VDIOresistance = value->rValue;
|
||||
model->VDIOresistanceGiven = TRUE;
|
||||
model->VDIOresistTemp1 = 0;
|
||||
model->VDIOresistTemp2 = 0;
|
||||
break;
|
||||
case VDMOS_MOD_IS:
|
||||
model->VDIOjctSatCur = value->rValue;
|
||||
|
|
@ -137,10 +132,6 @@ VDMOSmParam(int param, IFvalue *value, GENmodel *inModel)
|
|||
model->VDMOSmtr = value->rValue;
|
||||
model->VDMOSmtrGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_SUBSLOPE:
|
||||
model->VDMOSsubsl = value->rValue;
|
||||
model->VDMOSsubslGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_SUBSHIFT:
|
||||
model->VDMOSsubshift = value->rValue;
|
||||
model->VDMOSsubshiftGiven = TRUE;
|
||||
|
|
@ -150,12 +141,12 @@ VDMOSmParam(int param, IFvalue *value, GENmodel *inModel)
|
|||
model->VDMOSksubthresGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_BV:
|
||||
model->VDMOSDbv = value->rValue;
|
||||
model->VDMOSDbvGiven = TRUE;
|
||||
model->VDMOSbv = value->rValue;
|
||||
model->VDMOSbvGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_IBV:
|
||||
model->VDMOSDibv = value->rValue;
|
||||
model->VDMOSDibvGiven = TRUE;
|
||||
model->VDMOSibv = value->rValue;
|
||||
model->VDMOSibvGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_NBV:
|
||||
model->VDIObrkdEmissionCoeff = value->rValue;
|
||||
|
|
@ -166,8 +157,8 @@ VDMOSmParam(int param, IFvalue *value, GENmodel *inModel)
|
|||
model->VDMOSrdsGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_N:
|
||||
model->VDMOSDn = value->rValue;
|
||||
model->VDMOSDnGiven = TRUE;
|
||||
model->VDMOSn = value->rValue;
|
||||
model->VDMOSnGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_TT:
|
||||
model->VDIOtransitTime = value->rValue;
|
||||
|
|
@ -176,12 +167,60 @@ VDMOSmParam(int param, IFvalue *value, GENmodel *inModel)
|
|||
model->VDIOtranTimeTemp2 = 0;
|
||||
break;
|
||||
case VDMOS_MOD_EG:
|
||||
model->VDMOSDeg = value->rValue;
|
||||
model->VDMOSDegGiven = TRUE;
|
||||
model->VDMOSeg = value->rValue;
|
||||
model->VDMOSegGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_XTI:
|
||||
model->VDMOSDxti = value->rValue;
|
||||
model->VDMOSDxtiGiven = TRUE;
|
||||
model->VDMOSxti = value->rValue;
|
||||
model->VDMOSxtiGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_RTHJC:
|
||||
model->VDMOSrthjc = value->rValue;
|
||||
model->VDMOSrthjcGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_RTHCA:
|
||||
model->VDMOSrthca = value->rValue;
|
||||
model->VDMOSrthcaGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_CTHJ:
|
||||
model->VDMOScthj = value->rValue;
|
||||
model->VDMOScthjGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_MU:
|
||||
model->VDMOSmu = value->rValue;
|
||||
model->VDMOSmuGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_TEXP0:
|
||||
model->VDMOStexp0 = value->rValue;
|
||||
model->VDMOStexp0Given = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_TEXP1:
|
||||
model->VDMOStexp1 = value->rValue;
|
||||
model->VDMOStexp1Given = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_TCVTH:
|
||||
model->VDMOStcvth = value->rValue;
|
||||
model->VDMOStcvthGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_VGS_MAX:
|
||||
model->VDMOSvgsMax = value->rValue;
|
||||
model->VDMOSvgsMaxGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_VGD_MAX:
|
||||
model->VDMOSvgdMax = value->rValue;
|
||||
model->VDMOSvgdMaxGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_VDS_MAX:
|
||||
model->VDMOSvdsMax = value->rValue;
|
||||
model->VDMOSvdsMaxGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_VGSR_MAX:
|
||||
model->VDMOSvgsrMax = value->rValue;
|
||||
model->VDMOSvgsrMaxGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_VGDR_MAX:
|
||||
model->VDMOSvgdrMax = value->rValue;
|
||||
model->VDMOSvgdrMaxGiven = TRUE;
|
||||
break;
|
||||
default:
|
||||
return(E_BADPARM);
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ VDMOSnoise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt,
|
|||
double noizDens[VDMOSNSRCS];
|
||||
double lnNdens[VDMOSNSRCS];
|
||||
int i;
|
||||
double tempRatioSH;
|
||||
|
||||
/* define the names of the noise sources */
|
||||
|
||||
|
|
@ -90,17 +91,21 @@ VDMOSnoise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt,
|
|||
switch (mode) {
|
||||
|
||||
case N_DENS:
|
||||
if ((inst->VDMOStnodeoutGiven) && (model->VDMOSrthjcGiven))
|
||||
tempRatioSH = inst->VDMOSTempSH / ckt->CKTtemp;
|
||||
else
|
||||
tempRatioSH = 1.0;
|
||||
NevalSrc(&noizDens[VDMOSRDNOIZ],&lnNdens[VDMOSRDNOIZ],
|
||||
ckt,THERMNOISE,inst->VDMOSdNodePrime,inst->VDMOSdNode,
|
||||
inst->VDMOSdrainConductance);
|
||||
inst->VDMOSdrainConductance * tempRatioSH);
|
||||
|
||||
NevalSrc(&noizDens[VDMOSRSNOIZ],&lnNdens[VDMOSRSNOIZ],
|
||||
ckt,THERMNOISE,inst->VDMOSsNodePrime,inst->VDMOSsNode,
|
||||
inst->VDMOSsourceConductance);
|
||||
inst->VDMOSsourceConductance * tempRatioSH);
|
||||
|
||||
NevalSrc(&noizDens[VDMOSIDNOIZ],&lnNdens[VDMOSIDNOIZ],
|
||||
ckt,THERMNOISE,inst->VDMOSdNodePrime,inst->VDMOSsNodePrime,
|
||||
(2.0/3.0 * fabs(inst->VDMOSgm)));
|
||||
(2.0/3.0 * fabs(inst->VDMOSgm)) * tempRatioSH);
|
||||
|
||||
NevalSrc(&noizDens[VDMOSFLNOIZ], NULL, ckt,
|
||||
N_GAIN,inst->VDMOSdNodePrime, inst->VDMOSsNodePrime,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
VDMOS: 2018 Holger Vogt, 2020 Dietmar Warning
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
|
@ -60,6 +61,10 @@ VDMOSparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
|
|||
here->VDMOSicVGS = value->rValue;
|
||||
here->VDMOSicVGSGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_TNODEOUT:
|
||||
here->VDMOStnodeout = (value->iValue != 0);
|
||||
here->VDMOStnodeoutGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_IC:
|
||||
switch(value->v.numValue){
|
||||
case 2:
|
||||
|
|
|
|||
|
|
@ -44,8 +44,13 @@ VDMOSpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s)
|
|||
capgd = ( 2* *(ckt->CKTstate0+here->VDMOScapgd));
|
||||
xgs = capgs;
|
||||
xgd = capgd;
|
||||
/*printf("vdmos: xgs=%g, xgd=%g\n",
|
||||
xgs,xgd);*/
|
||||
|
||||
/* body diode */
|
||||
double gspr, geq, xceq;
|
||||
gspr = here->VDIOtConductance;
|
||||
geq = *(ckt->CKTstate0 + here->VDIOconduct);
|
||||
xceq = *(ckt->CKTstate0 + here->VDIOcapCurrent);
|
||||
|
||||
/*
|
||||
* load matrix
|
||||
*/
|
||||
|
|
@ -67,21 +72,34 @@ VDMOSpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s)
|
|||
*(here->VDMOSDdPtr) += here->VDMOSdrainConductance;
|
||||
*(here->VDMOSSsPtr) += here->VDMOSsourceConductance;
|
||||
*(here->VDMOSDPdpPtr) += here->VDMOSdrainConductance+
|
||||
here->VDMOSgds+
|
||||
xrev*(here->VDMOSgm);
|
||||
here->VDMOSgds+xrev*(here->VDMOSgm);
|
||||
*(here->VDMOSSPspPtr) += here->VDMOSsourceConductance+
|
||||
here->VDMOSgds+
|
||||
xnrm*(here->VDMOSgm);
|
||||
here->VDMOSgds+xnrm*(here->VDMOSgm);
|
||||
*(here->VDMOSDdpPtr) -= here->VDMOSdrainConductance;
|
||||
*(here->VDMOSSspPtr) -= here->VDMOSsourceConductance;
|
||||
*(here->VDMOSDPdPtr) -= here->VDMOSdrainConductance;
|
||||
*(here->VDMOSDPgPtr) += (xnrm-xrev)*here->VDMOSgm;
|
||||
*(here->VDMOSDPspPtr) -= here->VDMOSgds+
|
||||
xnrm*(here->VDMOSgm);
|
||||
*(here->VDMOSSPgPtr) -= (xnrm-xrev)*here->VDMOSgm;
|
||||
*(here->VDMOSDPgpPtr) += (xnrm-xrev)*here->VDMOSgm;
|
||||
*(here->VDMOSDPspPtr) -= here->VDMOSgds+xnrm*(here->VDMOSgm);
|
||||
*(here->VDMOSSPgpPtr) -= (xnrm-xrev)*here->VDMOSgm;
|
||||
*(here->VDMOSSPsPtr) -= here->VDMOSsourceConductance;
|
||||
*(here->VDMOSSPdpPtr) -= here->VDMOSgds+
|
||||
xrev*(here->VDMOSgm);
|
||||
*(here->VDMOSSPdpPtr) -= here->VDMOSgds+xrev*(here->VDMOSgm);
|
||||
/* gate resistor */
|
||||
*(here->VDMOSGgPtr) += (here->VDMOSgateConductance);
|
||||
*(here->VDMOSGPgpPtr) += (here->VDMOSgateConductance);
|
||||
*(here->VDMOSGgpPtr) -= here->VDMOSgateConductance;
|
||||
*(here->VDMOSGPgPtr) -= here->VDMOSgateConductance;
|
||||
/* body diode */
|
||||
*(here->VDMOSSsPtr) += gspr;
|
||||
*(here->VDMOSDdPtr) += geq + xceq * s->real;
|
||||
*(here->VDMOSDdPtr +1 ) += xceq * s->imag;
|
||||
*(here->VDIORPrpPtr) += geq + gspr + xceq * s->real;
|
||||
*(here->VDIORPrpPtr +1) += xceq * s->imag;
|
||||
*(here->VDIOSrpPtr) -= gspr;
|
||||
*(here->VDIODrpPtr) -= geq + xceq * s->real;
|
||||
*(here->VDIODrpPtr +1) -= xceq * s->imag;
|
||||
*(here->VDIORPsPtr) -= gspr;
|
||||
*(here->VDIORPdPtr) -= geq + xceq * s->real;
|
||||
*(here->VDIORPdPtr +1 ) -= xceq * s->imag;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
VDMOS: 2018 Holger Vogt, 2020 Dietmar Warning
|
||||
**********/
|
||||
|
||||
/* load the VDMOS device structure with those pointers needed later
|
||||
|
|
@ -27,87 +28,136 @@ VDMOSsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
|
|||
/* loop through all the VDMOS device models */
|
||||
for (; model != NULL; model = VDMOSnextModel(model)) {
|
||||
|
||||
if (!model->VDMOStypeGiven) {
|
||||
if (!model->VDMOStypeGiven)
|
||||
model->VDMOStype = NMOS;
|
||||
}
|
||||
if (!model->VDIOjctSatCurGiven) {
|
||||
|
||||
if (!model->VDIOjctSatCurGiven)
|
||||
model->VDIOjctSatCur = 1e-14;
|
||||
}
|
||||
if (!model->VDMOStransconductanceGiven) {
|
||||
|
||||
if (!model->VDMOStransconductanceGiven)
|
||||
model->VDMOStransconductance = 1;
|
||||
}
|
||||
if (!model->VDMOSvt0Given) {
|
||||
model->VDMOSvt0 = 0;
|
||||
}
|
||||
if (!model->VDIOjunctionPotGiven) {
|
||||
|
||||
if (!model->VDMOSvth0Given)
|
||||
model->VDMOSvth0 = 0;
|
||||
|
||||
if (!model->VDIOjunctionPotGiven)
|
||||
model->VDIOjunctionPot = .8;
|
||||
}
|
||||
if (!model->VDIOgradCoeffGiven) {
|
||||
|
||||
if (!model->VDIOgradCoeffGiven)
|
||||
model->VDIOgradCoeff = .5;
|
||||
}
|
||||
if (!model->VDIOdepletionCapCoeffGiven) {
|
||||
|
||||
if (!model->VDIOdepletionCapCoeffGiven)
|
||||
model->VDIOdepletionCapCoeff = .5;
|
||||
}
|
||||
if (!model->VDMOSphiGiven) {
|
||||
|
||||
if (!model->VDMOSphiGiven)
|
||||
model->VDMOSphi = .6;
|
||||
}
|
||||
if (!model->VDMOSlambdaGiven) {
|
||||
|
||||
if (!model->VDMOSlambdaGiven)
|
||||
model->VDMOSlambda = 0;
|
||||
}
|
||||
if (!model->VDMOSthetaGiven) {
|
||||
|
||||
if (!model->VDMOSthetaGiven)
|
||||
model->VDMOStheta = 0;
|
||||
}
|
||||
if (!model->VDMOSfNcoefGiven) {
|
||||
|
||||
if (!model->VDMOSfNcoefGiven)
|
||||
model->VDMOSfNcoef = 0;
|
||||
}
|
||||
if (!model->VDMOSfNexpGiven) {
|
||||
|
||||
if (!model->VDMOSfNexpGiven)
|
||||
model->VDMOSfNexp = 1;
|
||||
}
|
||||
if (!model->VDMOScgdminGiven) {
|
||||
|
||||
if (!model->VDMOScgdminGiven)
|
||||
model->VDMOScgdmin = 0;
|
||||
}
|
||||
if (!model->VDMOScgdmaxGiven) {
|
||||
|
||||
if (!model->VDMOScgdmaxGiven)
|
||||
model->VDMOScgdmax = 0;
|
||||
}
|
||||
if (!model->VDMOScgsGiven) {
|
||||
|
||||
if (!model->VDMOScgsGiven)
|
||||
model->VDMOScgs = 0;
|
||||
}
|
||||
if (!model->VDMOSaGiven) {
|
||||
|
||||
if (!model->VDMOSaGiven)
|
||||
model->VDMOSa = 1.;
|
||||
}
|
||||
if (!model->VDMOSsubslGiven) {
|
||||
model->VDMOSsubsl = 0;
|
||||
}
|
||||
if (!model->VDMOSsubshiftGiven) {
|
||||
|
||||
if (!model->VDMOSsubshiftGiven)
|
||||
model->VDMOSsubshift = 0;
|
||||
}
|
||||
if (!model->VDMOSksubthresGiven) {
|
||||
model->VDMOSksubthres = 0;
|
||||
}
|
||||
if (!model->VDMOSmtrGiven) {
|
||||
|
||||
if (!model->VDMOSksubthresGiven)
|
||||
model->VDMOSksubthres = 0.1;
|
||||
|
||||
if (!model->VDMOSmtrGiven)
|
||||
model->VDMOSmtr = 1.;
|
||||
}
|
||||
if (!model->VDMOSDbvGiven) {
|
||||
model->VDMOSDbv = 1.0e30;
|
||||
}
|
||||
if (!model->VDMOSDibvGiven) {
|
||||
model->VDMOSDibv = 1.0e-10;
|
||||
}
|
||||
if (!model->VDIObrkdEmissionCoeffGiven) {
|
||||
|
||||
if (!model->VDMOSbvGiven)
|
||||
model->VDMOSbv = 1.0e30;
|
||||
|
||||
if (!model->VDMOSibvGiven)
|
||||
model->VDMOSibv = 1.0e-10;
|
||||
|
||||
if (!model->VDIObrkdEmissionCoeffGiven)
|
||||
model->VDIObrkdEmissionCoeff = 1.;
|
||||
}
|
||||
if (!model->VDMOSrdsGiven) {
|
||||
model->VDMOSrds = 1.0e30;
|
||||
}
|
||||
if (!model->VDMOSDnGiven) {
|
||||
model->VDMOSDn = 1.;
|
||||
}
|
||||
if (!model->VDIOtransitTimeGiven) {
|
||||
|
||||
if (!model->VDMOSdrainResistanceGiven)
|
||||
model->VDMOSdrainResistance = 1.0e-03;
|
||||
|
||||
if (!model->VDMOSsourceResistanceGiven)
|
||||
model->VDMOSsourceResistance = 1.0e-03;
|
||||
|
||||
if (!model->VDMOSgateResistanceGiven)
|
||||
model->VDMOSgateResistance = 1.0e-03;
|
||||
|
||||
if (!model->VDMOSrdsGiven)
|
||||
model->VDMOSrds = 1.0e+15;
|
||||
|
||||
if (!model->VDIOresistanceGiven)
|
||||
model->VDIOresistance = 1.0e-03;
|
||||
|
||||
if (!model->VDMOSnGiven)
|
||||
model->VDMOSn = 1.;
|
||||
|
||||
if (!model->VDIOtransitTimeGiven)
|
||||
model->VDIOtransitTime = 0.;
|
||||
}
|
||||
if (!model->VDMOSDegGiven) {
|
||||
model->VDMOSDeg = 1.11;
|
||||
}
|
||||
|
||||
if (!model->VDMOSegGiven)
|
||||
model->VDMOSeg = 1.11;
|
||||
|
||||
if (!model->VDMOSrthjcGiven)
|
||||
model->VDMOSrthjc = 1.0e-03;
|
||||
|
||||
if (!model->VDMOSrthcaGiven)
|
||||
model->VDMOSrthca = 100;
|
||||
|
||||
if (!model->VDMOScthjGiven)
|
||||
model->VDMOScthj = 10e-06;
|
||||
|
||||
if (!model->VDMOSmuGiven)
|
||||
model->VDMOSmu = -1.5;
|
||||
|
||||
if (!model->VDMOStcvthGiven)
|
||||
model->VDMOStcvth = 0.0;
|
||||
|
||||
if (!model->VDMOStexp0Given)
|
||||
model->VDMOStexp0 = 1.5;
|
||||
|
||||
if (!model->VDMOStexp1Given)
|
||||
model->VDMOStexp1 = 0.3;
|
||||
|
||||
if (!model->VDMOSvgsMaxGiven)
|
||||
model->VDMOSvgsMax = 1e99;
|
||||
|
||||
if (!model->VDMOSvgdMaxGiven)
|
||||
model->VDMOSvgdMax = 1e99;
|
||||
|
||||
if (!model->VDMOSvdsMaxGiven)
|
||||
model->VDMOSvdsMax = 1e99;
|
||||
|
||||
if (!model->VDMOSvgsrMaxGiven)
|
||||
model->VDMOSvgsrMax = 1e99;
|
||||
|
||||
if (!model->VDMOSvgdrMaxGiven)
|
||||
model->VDMOSvgdrMax = 1e99;
|
||||
|
||||
if ((model->VDMOSqsResistanceGiven) && (model->VDMOSqsVoltageGiven))
|
||||
model->VDMOSqsGiven = 1;
|
||||
else
|
||||
model->VDMOSqsGiven = 0;
|
||||
|
||||
/* loop through all the instances of the model */
|
||||
for (here = VDMOSinstances(model); here != NULL;
|
||||
|
|
@ -129,6 +179,45 @@ VDMOSsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
|
|||
if (!here->VDMOSvonGiven) {
|
||||
here->VDMOSvon = 0;
|
||||
}
|
||||
if(!here->VDMOSmGiven) {
|
||||
here->VDMOSm = 1;
|
||||
}
|
||||
if(!here->VDMOSlGiven) {
|
||||
here->VDMOSl = 1;
|
||||
}
|
||||
if(!here->VDMOSwGiven) {
|
||||
here->VDMOSw = 1;
|
||||
}
|
||||
if (model->VDMOSdrainResistance != 0) {
|
||||
here->VDMOSdrainConductance = here->VDMOSm / model->VDMOSdrainResistance;
|
||||
} else {
|
||||
here->VDMOSdrainConductance = here->VDMOSm / 1.0e-03;
|
||||
}
|
||||
if (model->VDMOSsourceResistance != 0) {
|
||||
here->VDMOSsourceConductance = here->VDMOSm / model->VDMOSsourceResistance;
|
||||
} else {
|
||||
here->VDMOSsourceConductance = here->VDMOSm / 1.0e-03;
|
||||
}
|
||||
if (model->VDMOSgateResistance != 0) {
|
||||
here->VDMOSgateConductance = here->VDMOSm / model->VDMOSgateResistance;
|
||||
} else {
|
||||
here->VDMOSgateConductance = here->VDMOSm / 1.0e-03;
|
||||
}
|
||||
if (model->VDMOSrdsGiven) {
|
||||
if (model->VDMOSrds != 0) {
|
||||
here->VDMOSdsConductance = here->VDMOSm / model->VDMOSrds;
|
||||
} else {
|
||||
here->VDMOSdsConductance = 1e-15;
|
||||
}
|
||||
} else {
|
||||
here->VDMOSdsConductance = 1e-15;
|
||||
}
|
||||
if (model->VDIOresistance != 0) {
|
||||
here->VDIOconductance = here->VDMOSm / model->VDIOresistance;
|
||||
} else {
|
||||
here->VDIOconductance = here->VDMOSm / 1.0e-03;
|
||||
}
|
||||
|
||||
if (model->VDMOSdrainResistance != 0) {
|
||||
if (here->VDMOSdNodePrime == 0) {
|
||||
error = CKTmkVolt(ckt, &tmp, here->VDMOSname, "drain");
|
||||
|
|
@ -153,6 +242,29 @@ VDMOSsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
|
|||
here->VDMOSdNodePrime = here->VDMOSdNode;
|
||||
}
|
||||
|
||||
if (model->VDMOSgateResistance != 0 ) {
|
||||
if (here->VDMOSgNodePrime == 0) {
|
||||
error = CKTmkVolt(ckt, &tmp, here->VDMOSname, "gate");
|
||||
if (error) return(error);
|
||||
here->VDMOSgNodePrime = tmp->number;
|
||||
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
CKTnode *tmpNode;
|
||||
IFuid tmpName;
|
||||
|
||||
if (CKTinst2Node(ckt, here, 2, &tmpNode, &tmpName) == OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset = tmpNode->nodeset;
|
||||
tmp->nsGiven = tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
here->VDMOSgNodePrime = here->VDMOSgNode;
|
||||
}
|
||||
|
||||
if (model->VDMOSsourceResistance != 0) {
|
||||
if (here->VDMOSsNodePrime == 0) {
|
||||
error = CKTmkVolt(ckt, &tmp, here->VDMOSname, "source");
|
||||
|
|
@ -177,32 +289,9 @@ VDMOSsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
|
|||
here->VDMOSsNodePrime = here->VDMOSsNode;
|
||||
}
|
||||
|
||||
if (model->VDMOSgateResistance != 0 ) {
|
||||
if (here->VDMOSgNodePrime == 0) {
|
||||
error = CKTmkVolt(ckt, &tmp, here->VDMOSname, "gate");
|
||||
if (error) return(error);
|
||||
here->VDMOSgNodePrime = tmp->number;
|
||||
|
||||
if (ckt->CKTcopyNodesets) {
|
||||
CKTnode *tmpNode;
|
||||
IFuid tmpName;
|
||||
|
||||
if (CKTinst2Node(ckt, here, 3, &tmpNode, &tmpName) == OK) {
|
||||
if (tmpNode->nsGiven) {
|
||||
tmp->nodeset = tmpNode->nodeset;
|
||||
tmp->nsGiven = tmpNode->nsGiven;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
here->VDMOSgNodePrime = here->VDMOSgNode;
|
||||
}
|
||||
|
||||
if (model->VDIOresistance != 0 ) {
|
||||
if (here->VDIOposPrimeNode == 0) {
|
||||
error = CKTmkVolt(ckt, &tmp, here->VDMOSname, "bulk diode");
|
||||
error = CKTmkVolt(ckt, &tmp, here->VDMOSname, "body diode");
|
||||
if (error) return(error);
|
||||
here->VDIOposPrimeNode = tmp->number;
|
||||
|
||||
|
|
@ -223,6 +312,31 @@ VDMOSsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
|
|||
here->VDIOposPrimeNode = here->VDMOSsNode;
|
||||
}
|
||||
|
||||
if ((here->VDMOStnodeoutGiven) && (model->VDMOSrthjcGiven)) {
|
||||
if (here->VDMOStempNode == -1) {
|
||||
error = CKTmkVolt(ckt,&tmp,here->VDMOSname,"Tj");
|
||||
if (error) return(error);
|
||||
here->VDMOStempNode = tmp->number;
|
||||
}
|
||||
if (here->VDMOStcaseNode == -1) {
|
||||
error = CKTmkVolt(ckt,&tmp,here->VDMOSname,"Tc");
|
||||
if (error) return(error);
|
||||
here->VDMOStcaseNode = tmp->number;
|
||||
}
|
||||
if(here->VDMOSvcktTbranch == 0) {
|
||||
error = CKTmkCur(ckt,&tmp,here->VDMOSname,"VcktTemp");
|
||||
if(error) return(error);
|
||||
here->VDMOSvcktTbranch = tmp->number;
|
||||
}
|
||||
if (here->VDMOStNodePrime == 0) {
|
||||
error = CKTmkVolt(ckt, &tmp, here->VDMOSname, "cktTemp");
|
||||
if (error) return(error);
|
||||
here->VDMOStNodePrime = tmp->number;
|
||||
}
|
||||
} else {
|
||||
here->VDMOStempNode = 0;
|
||||
here->VDMOStcaseNode = 0;
|
||||
}
|
||||
|
||||
/* macro to make elements with built in test for out of memory */
|
||||
#define TSTALLOC(ptr,first,second) \
|
||||
|
|
@ -230,6 +344,25 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
|||
return(E_NOMEM);\
|
||||
} } while(0)
|
||||
|
||||
if ((here->VDMOStnodeoutGiven) && (model->VDMOSrthjcGiven)) {
|
||||
TSTALLOC(VDMOSTemptempPtr, VDMOStempNode, VDMOStempNode);
|
||||
TSTALLOC(VDMOSTempdpPtr, VDMOStempNode, VDMOSdNodePrime);
|
||||
TSTALLOC(VDMOSTempspPtr, VDMOStempNode, VDMOSsNodePrime);
|
||||
TSTALLOC(VDMOSTempgpPtr, VDMOStempNode, VDMOSgNodePrime);
|
||||
TSTALLOC(VDMOSGPtempPtr, VDMOSgNodePrime, VDMOStempNode);
|
||||
TSTALLOC(VDMOSDPtempPtr, VDMOSdNodePrime, VDMOStempNode);
|
||||
TSTALLOC(VDMOSSPtempPtr, VDMOSsNodePrime, VDMOStempNode);
|
||||
|
||||
TSTALLOC(VDMOSTcasetcasePtr, VDMOStcaseNode, VDMOStcaseNode); /* Rthjc between tj and tcase*/
|
||||
TSTALLOC(VDMOSTcasetempPtr, VDMOStcaseNode, VDMOStempNode);
|
||||
TSTALLOC(VDMOSTemptcasePtr, VDMOStempNode, VDMOStcaseNode);
|
||||
TSTALLOC(VDMOSTptpPtr, VDMOStNodePrime, VDMOStNodePrime); /* Rthca between tcase and Vsrc */
|
||||
TSTALLOC(VDMOSTptcasePtr, VDMOStNodePrime, VDMOStempNode);
|
||||
TSTALLOC(VDMOSTcasetpPtr, VDMOStempNode, VDMOStNodePrime);
|
||||
TSTALLOC(VDMOSCktTcktTPtr, VDMOSvcktTbranch, VDMOSvcktTbranch); /* Vsrc=cktTemp to gnd */
|
||||
TSTALLOC(VDMOSCktTtpPtr, VDMOSvcktTbranch, VDMOStNodePrime);
|
||||
TSTALLOC(VDMOSTpcktTPtr, VDMOStNodePrime, VDMOSvcktTbranch);
|
||||
}
|
||||
TSTALLOC(VDMOSDdPtr, VDMOSdNode, VDMOSdNode);
|
||||
TSTALLOC(VDMOSGgPtr, VDMOSgNode, VDMOSgNode);
|
||||
TSTALLOC(VDMOSSsPtr, VDMOSsNode, VDMOSsNode);
|
||||
|
|
@ -294,6 +427,16 @@ VDMOSunsetup(GENmodel *inModel, CKTcircuit *ckt)
|
|||
&& here->VDIOposPrimeNode != here->VDMOSsNode)
|
||||
CKTdltNNum(ckt, here->VDIOposPrimeNode);
|
||||
here->VDIOposPrimeNode = 0;
|
||||
|
||||
if ((here->VDMOStnodeoutGiven) && (model->VDMOSrthjcGiven)) {
|
||||
if (here->VDMOStNodePrime > 0)
|
||||
CKTdltNNum(ckt, here->VDMOStNodePrime);
|
||||
here->VDMOStNodePrime = 0;
|
||||
if (here->VDMOSvcktTbranch > 0)
|
||||
CKTdltNNum(ckt, here->VDMOSvcktTbranch);
|
||||
here->VDMOSvcktTbranch = 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,142 @@
|
|||
/**********
|
||||
Copyright 2013 Dietmar Warning. All rights reserved.
|
||||
Author: 2013 Dietmar Warning
|
||||
**********/
|
||||
|
||||
#include "ngspice/ngspice.h"
|
||||
#include "ngspice/cktdefs.h"
|
||||
#include "vdmosdefs.h"
|
||||
#include "ngspice/trandefs.h"
|
||||
#include "ngspice/sperror.h"
|
||||
#include "ngspice/suffix.h"
|
||||
#include "ngspice/cpdefs.h"
|
||||
|
||||
|
||||
int
|
||||
VDMOSsoaCheck(CKTcircuit *ckt, GENmodel *inModel)
|
||||
{
|
||||
VDMOSmodel *model = (VDMOSmodel *) inModel;
|
||||
VDMOSinstance *here;
|
||||
double vgs, vgd, vds; /* actual mos voltages */
|
||||
int maxwarns;
|
||||
static int warns_vgs = 0, warns_vgd = 0, warns_vds = 0;
|
||||
|
||||
if (!ckt) {
|
||||
warns_vgs = 0;
|
||||
warns_vgd = 0;
|
||||
warns_vds = 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
maxwarns = ckt->CKTsoaMaxWarns;
|
||||
|
||||
for (; model; model = VDMOSnextModel(model)) {
|
||||
|
||||
for (here = VDMOSinstances(model); here; here = VDMOSnextInstance(here)) {
|
||||
|
||||
vgs = ckt->CKTrhsOld [here->VDMOSgNode] -
|
||||
ckt->CKTrhsOld [here->VDMOSsNodePrime];
|
||||
|
||||
vgd = ckt->CKTrhsOld [here->VDMOSgNode] -
|
||||
ckt->CKTrhsOld [here->VDMOSdNodePrime];
|
||||
|
||||
vds = ckt->CKTrhsOld [here->VDMOSdNodePrime] -
|
||||
ckt->CKTrhsOld [here->VDMOSsNodePrime];
|
||||
|
||||
if (!model->VDMOSvgsrMaxGiven) {
|
||||
if (fabs(vgs) > model->VDMOSvgsMax)
|
||||
if (warns_vgs < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*) here,
|
||||
"Vgs=%g has exceeded Vgs_max=%g\n",
|
||||
vgs, model->VDMOSvgsMax);
|
||||
warns_vgs++;
|
||||
}
|
||||
} else {
|
||||
if (model->VDMOStype > 0) {
|
||||
if (vgs > model->VDMOSvgsMax)
|
||||
if (warns_vgs < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*) here,
|
||||
"Vgs=%g has exceeded Vgs_max=%g\n",
|
||||
vgs, model->VDMOSvgsMax);
|
||||
warns_vgs++;
|
||||
}
|
||||
if (-1*vgs > model->VDMOSvgsrMax)
|
||||
if (warns_vgs < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*) here,
|
||||
"Vgs=%g has exceeded Vgsr_max=%g\n",
|
||||
vgs, model->VDMOSvgsrMax);
|
||||
warns_vgs++;
|
||||
}
|
||||
} else {
|
||||
if (vgs > model->VDMOSvgsrMax)
|
||||
if (warns_vgs < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*) here,
|
||||
"Vgs=%g has exceeded Vgsr_max=%g\n",
|
||||
vgs, model->VDMOSvgsrMax);
|
||||
warns_vgs++;
|
||||
}
|
||||
if (-1*vgs > model->VDMOSvgsMax)
|
||||
if (warns_vgs < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*) here,
|
||||
"Vgs=%g has exceeded Vgs_max=%g\n",
|
||||
vgs, model->VDMOSvgsMax);
|
||||
warns_vgs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!model->VDMOSvgdrMaxGiven) {
|
||||
if (fabs(vgd) > model->VDMOSvgdMax)
|
||||
if (warns_vgd < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*) here,
|
||||
"Vgd=%g has exceeded Vgd_max=%g\n",
|
||||
vgd, model->VDMOSvgdMax);
|
||||
warns_vgd++;
|
||||
}
|
||||
} else {
|
||||
if (model->VDMOStype > 0) {
|
||||
if (vgd > model->VDMOSvgdMax)
|
||||
if (warns_vgd < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*) here,
|
||||
"Vgd=%g has exceeded Vgd_max=%g\n",
|
||||
vgd, model->VDMOSvgdMax);
|
||||
warns_vgd++;
|
||||
}
|
||||
if (-1*vgd > model->VDMOSvgdrMax)
|
||||
if (warns_vgd < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*) here,
|
||||
"Vgd=%g has exceeded Vgdr_max=%g\n",
|
||||
vgd, model->VDMOSvgdrMax);
|
||||
warns_vgd++;
|
||||
}
|
||||
} else {
|
||||
if (vgd > model->VDMOSvgdrMax)
|
||||
if (warns_vgd < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*) here,
|
||||
"Vgd=%g has exceeded Vgdr_max=%g\n",
|
||||
vgd, model->VDMOSvgdrMax);
|
||||
warns_vgd++;
|
||||
}
|
||||
if (-1*vgd > model->VDMOSvgdMax)
|
||||
if (warns_vgd < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*) here,
|
||||
"Vgd=%g has exceeded Vgd_max=%g\n",
|
||||
vgd, model->VDMOSvgdMax);
|
||||
warns_vgd++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fabs(vds) > model->VDMOSvdsMax)
|
||||
if (warns_vds < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*) here,
|
||||
"Vds=%g has exceeded Vds_max=%g\n",
|
||||
vds, model->VDMOSvdsMax);
|
||||
warns_vds++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
VDMOS: 2018 Holger Vogt, 2020 Dietmar Warning
|
||||
**********/
|
||||
|
||||
#include "ngspice/ngspice.h"
|
||||
|
|
@ -21,7 +22,7 @@ VDMOStemp(GENmodel *inModel, CKTcircuit *ckt)
|
|||
double fact1,fact2;
|
||||
double kt,kt1;
|
||||
double arg1;
|
||||
double ratio,ratio4;
|
||||
double ratio;
|
||||
double phio;
|
||||
double pbfact1,pbfact;
|
||||
double vt,vtnom;
|
||||
|
|
@ -45,22 +46,21 @@ VDMOStemp(GENmodel *inModel, CKTcircuit *ckt)
|
|||
pbfact1 = -2*vtnom *(1.5*log(fact1)+CHARGE*arg1);
|
||||
|
||||
/* now model parameter preprocessing */
|
||||
|
||||
if (model->VDMOSphi <= 0.0) {
|
||||
SPfrontEnd->IFerrorf(ERR_FATAL,
|
||||
"%s: Phi is not positive.", model->VDMOSmodName);
|
||||
return(E_BADPARM);
|
||||
}
|
||||
|
||||
model->VDMOSoxideCapFactor = 0;
|
||||
model->VDMOSoxideCapFactor = 3.9 * 8.854214871e-12 / 1e-07; /* use default Tox of 100nm */
|
||||
|
||||
/* bulk diode model */
|
||||
/* body diode model */
|
||||
/* limit activation energy to min of .1 */
|
||||
if (model->VDMOSDeg<.1) {
|
||||
if (model->VDMOSeg<.1) {
|
||||
SPfrontEnd->IFerrorf(ERR_WARNING,
|
||||
"%s: bulk diode activation energy too small, limited to 0.1",
|
||||
"%s: body diode activation energy too small, limited to 0.1",
|
||||
model->VDMOSmodName);
|
||||
model->VDMOSDeg = .1;
|
||||
model->VDMOSeg = .1;
|
||||
}
|
||||
/* limit depletion cap coeff to max of .95 */
|
||||
if (model->VDIOdepletionCapCoeff>.95) {
|
||||
|
|
@ -72,12 +72,7 @@ VDMOStemp(GENmodel *inModel, CKTcircuit *ckt)
|
|||
/* set lower limit of saturation current */
|
||||
if (model->VDIOjctSatCur < ckt->CKTepsmin)
|
||||
model->VDIOjctSatCur = ckt->CKTepsmin;
|
||||
if ((!model->VDIOresistanceGiven) || (model->VDIOresistance == 0)) {
|
||||
model->VDIOconductance = 0.0;
|
||||
}
|
||||
else {
|
||||
model->VDIOconductance = 1 / model->VDIOresistance;
|
||||
}
|
||||
|
||||
xfc = log(1 - model->VDIOdepletionCapCoeff);
|
||||
|
||||
/* loop through all instances of the model */
|
||||
|
|
@ -86,15 +81,29 @@ VDMOStemp(GENmodel *inModel, CKTcircuit *ckt)
|
|||
double arg; /* 1 - fc */
|
||||
|
||||
/* perform the parameter defaulting */
|
||||
|
||||
if(!here->VDMOSdtempGiven) {
|
||||
here->VDMOSdtemp = 0.0;
|
||||
}
|
||||
if(!here->VDMOStempGiven) {
|
||||
here->VDMOStemp = ckt->CKTtemp + here->VDMOSdtemp;
|
||||
}
|
||||
vt = here->VDMOStemp * CONSTKoverQ;
|
||||
|
||||
double dt = here->VDMOStemp - model->VDMOStnom;
|
||||
|
||||
/* vdmos temperature model */
|
||||
ratio = here->VDMOStemp/model->VDMOStnom;
|
||||
here->VDMOStTransconductance = model->VDMOStransconductance
|
||||
* here->VDMOSm * here->VDMOSw / here->VDMOSl
|
||||
* pow(ratio, model->VDMOSmu);
|
||||
|
||||
here->VDMOStVth = model->VDMOSvth0 - model->VDMOStype * model->VDMOStcvth * dt;
|
||||
|
||||
here->VDMOSdrainResistance = model->VDMOSdrainResistance / here->VDMOSm * pow(ratio, model->VDMOStexp0);
|
||||
|
||||
if (model->VDMOSqsGiven)
|
||||
here->VDMOSqsResistance = model->VDMOSqsResistance / here->VDMOSm * pow(ratio, model->VDMOStexp1);
|
||||
|
||||
vt = here->VDMOStemp * CONSTKoverQ;
|
||||
fact2 = here->VDMOStemp/REFTEMP;
|
||||
kt = here->VDMOStemp * CONSTboltz;
|
||||
egfet = 1.16-(7.02e-4*here->VDMOStemp*here->VDMOStemp)/
|
||||
|
|
@ -102,82 +111,15 @@ VDMOStemp(GENmodel *inModel, CKTcircuit *ckt)
|
|||
arg = -egfet/(kt+kt)+1.1150877/(CONSTboltz*(REFTEMP+REFTEMP));
|
||||
pbfact = -2*vt *(1.5*log(fact2)+CHARGE*arg);
|
||||
|
||||
if(!here->VDMOSmGiven) {
|
||||
here->VDMOSm = 1;
|
||||
}
|
||||
if(!here->VDMOSlGiven) {
|
||||
here->VDMOSl = 1;
|
||||
}
|
||||
if(!here->VDMOSwGiven) {
|
||||
here->VDMOSw = 1;
|
||||
}
|
||||
|
||||
ratio4 = ratio * sqrt(ratio);
|
||||
here->VDMOStTransconductance = model->VDMOStransconductance / ratio4;
|
||||
phio = (model->VDMOSphi - pbfact1) / fact1;
|
||||
here->VDMOStPhi = fact2 * phio + pbfact;
|
||||
here->VDMOStVto = model->VDMOSvt0;
|
||||
here->VDMOStPhi = fact2 * phio + pbfact; /* needed for distortion analysis */
|
||||
|
||||
here->VDMOSf2d = 0;
|
||||
here->VDMOSf3d = 0;
|
||||
here->VDMOSf4d = 0;
|
||||
|
||||
here->VDMOSf2s = 0;
|
||||
here->VDMOSf3s = 0;
|
||||
here->VDMOSf4s = 0;
|
||||
|
||||
|
||||
if (model->VDMOSdrainResistanceGiven) {
|
||||
if (model->VDMOSdrainResistance != 0) {
|
||||
here->VDMOSdrainConductance = here->VDMOSm /
|
||||
model->VDMOSdrainResistance;
|
||||
}
|
||||
else {
|
||||
here->VDMOSdrainConductance = 0;
|
||||
}
|
||||
} else {
|
||||
here->VDMOSdrainConductance = 0;
|
||||
}
|
||||
if(model->VDMOSsourceResistanceGiven) {
|
||||
if(model->VDMOSsourceResistance != 0) {
|
||||
here->VDMOSsourceConductance = here->VDMOSm /
|
||||
model->VDMOSsourceResistance;
|
||||
} else {
|
||||
here->VDMOSsourceConductance = 0;
|
||||
}
|
||||
} else {
|
||||
here->VDMOSsourceConductance = 0;
|
||||
}
|
||||
if (model->VDMOSgateResistanceGiven) {
|
||||
if (model->VDMOSgateResistance != 0) {
|
||||
here->VDMOSgateConductance = here->VDMOSm /
|
||||
model->VDMOSgateResistance;
|
||||
} else {
|
||||
here->VDMOSgateConductance = 0;
|
||||
}
|
||||
} else {
|
||||
here->VDMOSgateConductance = 0;
|
||||
}
|
||||
if (model->VDMOSrdsGiven) {
|
||||
if (model->VDMOSrds != 0) {
|
||||
here->VDMOSdsConductance = here->VDMOSm /
|
||||
model->VDMOSrds;
|
||||
}
|
||||
else {
|
||||
here->VDMOSdsConductance = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
here->VDMOSdsConductance = 0;
|
||||
}
|
||||
|
||||
/* bulk diode model */
|
||||
/* body diode temperature model */
|
||||
double pbo, gmaold;
|
||||
double gmanew, factor;
|
||||
double tBreakdownVoltage, vte, cbv;
|
||||
double xbv, xcbv, tol, iter, dt;
|
||||
double xbv, xcbv, tol, iter;
|
||||
|
||||
dt = here->VDMOStemp - model->VDMOStnom;
|
||||
/* Junction grading temperature adjust */
|
||||
factor = 1.0 + (model->VDIOgradCoeffTemp1 * dt)
|
||||
+ (model->VDIOgradCoeffTemp2 * dt * dt);
|
||||
|
|
@ -185,7 +127,7 @@ VDMOStemp(GENmodel *inModel, CKTcircuit *ckt)
|
|||
|
||||
pbo = (model->VDIOjunctionPot - pbfact1) / fact1;
|
||||
gmaold = (model->VDIOjunctionPot - pbo) / pbo;
|
||||
here->VDIOtJctCap = model->VDIOjunctionCap /
|
||||
here->VDIOtJctCap = here->VDMOSm * model->VDIOjunctionCap /
|
||||
(1 + here->VDIOtGradingCoeff*
|
||||
(400e-6*(model->VDMOStnom - REFTEMP) - gmaold));
|
||||
here->VDIOtJctPot = pbfact + fact2*pbo;
|
||||
|
|
@ -193,10 +135,10 @@ VDMOStemp(GENmodel *inModel, CKTcircuit *ckt)
|
|||
here->VDIOtJctCap *= 1 + here->VDIOtGradingCoeff*
|
||||
(400e-6*(here->VDMOStemp - REFTEMP) - gmanew);
|
||||
|
||||
here->VDIOtSatCur = model->VDIOjctSatCur * exp(
|
||||
here->VDIOtSatCur = here->VDMOSm * model->VDIOjctSatCur * exp(
|
||||
((here->VDMOStemp / model->VDMOStnom) - 1) *
|
||||
model->VDMOSDeg / (model->VDMOSDn*vt) +
|
||||
model->VDMOSDxti / model->VDMOSDn *
|
||||
model->VDMOSeg / (model->VDMOSn*vt) +
|
||||
model->VDMOSxti / model->VDMOSn *
|
||||
log(here->VDMOStemp / model->VDMOStnom));
|
||||
|
||||
/* the defintion of f1, just recompute after temperature adjusting
|
||||
|
|
@ -209,14 +151,14 @@ VDMOStemp(GENmodel *inModel, CKTcircuit *ckt)
|
|||
here->VDIOtJctPot;
|
||||
|
||||
/* and Vcrit */
|
||||
vte = model->VDMOSDn*vt;
|
||||
vte = model->VDMOSn*vt;
|
||||
|
||||
here->VDIOtVcrit = vte * log(vte / (CONSTroot2*here->VDIOtSatCur));
|
||||
|
||||
/* limit junction potential to max of 1/FC */
|
||||
if (here->VDIOtDepCap > 1.0) {
|
||||
here->VDIOtJctPot = 1.0 / model->VDMOSDn;
|
||||
here->VDIOtDepCap = model->VDMOSDn*here->VDIOtJctPot;
|
||||
if (here->VDIOtDepCap > 2.5) {
|
||||
here->VDIOtJctPot = 2.5 / model->VDMOSn;
|
||||
here->VDIOtDepCap = model->VDMOSn*here->VDIOtJctPot;
|
||||
SPfrontEnd->IFerrorf(ERR_WARNING,
|
||||
"%s: junction potential VJ too large, limited to %f",
|
||||
model->VDMOSmodName, here->VDIOtJctPot);
|
||||
|
|
@ -224,16 +166,16 @@ VDMOStemp(GENmodel *inModel, CKTcircuit *ckt)
|
|||
|
||||
/* and now to compute the breakdown voltage, again, using
|
||||
* temperature adjusted basic parameters */
|
||||
if (model->VDMOSDbvGiven) {
|
||||
if (model->VDMOSbvGiven) {
|
||||
/* tlev == 0 */
|
||||
tBreakdownVoltage = fabs(model->VDMOSDbv);
|
||||
tBreakdownVoltage = fabs(model->VDMOSbv);
|
||||
|
||||
cbv = model->VDMOSDibv;
|
||||
cbv = model->VDMOSibv;
|
||||
|
||||
if (cbv < here->VDIOtSatCur * tBreakdownVoltage / vt) {
|
||||
cbv = here->VDIOtSatCur * tBreakdownVoltage / vt;
|
||||
#ifdef TRACE
|
||||
SPfrontEnd->IFerrorf(ERR_WARNING, "%s: breakdown current increased to %g to resolve", here->DIOname, cbv);
|
||||
SPfrontEnd->IFerrorf(ERR_WARNING, "%s: breakdown current increased to %g to resolve", here->VDMOSname, cbv);
|
||||
SPfrontEnd->IFerrorf(ERR_WARNING,
|
||||
"incompatibility with specified saturation current");
|
||||
#endif
|
||||
|
|
@ -252,7 +194,7 @@ VDMOStemp(GENmodel *inModel, CKTcircuit *ckt)
|
|||
if (fabs(xcbv - cbv) <= tol) goto matched;
|
||||
}
|
||||
#ifdef TRACE
|
||||
SPfrontEnd->IFerrorf(ERR_WARNING, "%s: unable to match forward and reverse diode regions: bv = %g, ibv = %g", here->DIOname, xbv, xcbv);
|
||||
SPfrontEnd->IFerrorf(ERR_WARNING, "%s: unable to match forward and reverse diode regions: bv = %g, ibv = %g", here->VDMOSname, xbv, xcbv);
|
||||
#endif
|
||||
}
|
||||
matched:
|
||||
|
|
@ -264,13 +206,8 @@ VDMOStemp(GENmodel *inModel, CKTcircuit *ckt)
|
|||
+ (model->VDIOtranTimeTemp2 * dt * dt);
|
||||
here->VDIOtTransitTime = model->VDIOtransitTime * factor;
|
||||
|
||||
/* Series resistance temperature adjust */
|
||||
here->VDIOtConductance = model->VDIOconductance;
|
||||
if (model->VDIOresistanceGiven && model->VDIOresistance != 0.0) {
|
||||
factor = 1.0 + (model->VDIOresistTemp1) * dt
|
||||
+ (model->VDIOresistTemp2 * dt * dt);
|
||||
here->VDIOtConductance = model->VDIOconductance / factor;
|
||||
}
|
||||
/* Series resistance temperature adjust (not implemented yet) */
|
||||
here->VDIOtConductance = here->VDIOconductance;
|
||||
|
||||
here->VDIOtF2 = exp((1 + here->VDIOtGradingCoeff)*xfc);
|
||||
here->VDIOtF3 = 1 - model->VDIOdepletionCapCoeff*
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ IFparm VSRCpTable[] = { /* parameters */
|
|||
IOP ("trnoise", VSRC_TRNOISE, IF_REALVEC,"Transient noise description"),
|
||||
IOP ("trrandom", VSRC_TRRANDOM, IF_REALVEC,"random source description"),
|
||||
#ifdef SHARED_MODULE
|
||||
IOP ("external", VSRC_EXTERNAL, IF_REALVEC,"external source description"),
|
||||
IOP ("external", VSRC_EXTERNAL, IF_STRING,"external source description"),
|
||||
#endif
|
||||
OPU ("pos_node",VSRC_POS_NODE, IF_INTEGER,"Positive node of source"),
|
||||
OPU ("neg_node",VSRC_NEG_NODE, IF_INTEGER,"Negative node of source"),
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ model_numnodes(int type)
|
|||
|
||||
if (type == INPtypelook("VDMOS")) /* 3 ; VDMOSnames */
|
||||
{
|
||||
return 3;
|
||||
return 5;
|
||||
}
|
||||
|
||||
return 4;
|
||||
|
|
|
|||
|
|
@ -2106,6 +2106,7 @@
|
|||
<ClCompile Include="..\src\spicelib\devices\vdmos\vdmospar.c" />
|
||||
<ClCompile Include="..\src\spicelib\devices\vdmos\vdmospzld.c" />
|
||||
<ClCompile Include="..\src\spicelib\devices\vdmos\vdmosset.c" />
|
||||
<ClCompile Include="..\src\spicelib\devices\vdmos\vdmossoachk.c" />
|
||||
<ClCompile Include="..\src\spicelib\devices\vdmos\vdmostemp.c" />
|
||||
<ClCompile Include="..\src\spicelib\devices\vdmos\vdmostrun.c" />
|
||||
<ClCompile Include="..\src\spicelib\devices\vsrc\vsrc.c" />
|
||||
|
|
|
|||
|
|
@ -58,59 +58,59 @@
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='console_debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='console_release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='console_debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='console_release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseOMP|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseOMP|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='console_release_omp|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='console_release_omp|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
|
@ -1316,6 +1316,7 @@ lib /machine:x64 /def:..\..\fftw-3.3-dll64\libfftw3-3.def /out:$(IntDir)libfftw3
|
|||
<ClInclude Include=".\src\include\stdint.h" />
|
||||
<ClInclude Include=".\tmp-bison\inpptree-parser.h" />
|
||||
<ClInclude Include=".\tmp-bison\parse-bison.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="..\src\frontend\parse-bison.y;..\src\spicelib\parser\inpptree-parser.y">
|
||||
|
|
@ -1449,6 +1450,9 @@ lib /machine:x64 /def:..\..\fftw-3.3-dll64\libfftw3-3.def /out:$(IntDir)libfftw3
|
|||
<ClCompile Include="..\src\frontend\fourier.c" />
|
||||
<ClCompile Include="..\src\frontend\ftesopt.c" />
|
||||
<ClCompile Include="..\src\frontend\gens.c" />
|
||||
<ClCompile Include="..\src\frontend\get_phys_mem_size.c" />
|
||||
<ClCompile Include="..\src\frontend\get_resident_set_size.c" />
|
||||
<ClCompile Include="..\src\frontend\get_avail_mem_size.c" />
|
||||
<ClCompile Include="..\src\frontend\hcomp.c" />
|
||||
<ClCompile Include="..\src\frontend\help\help.c" />
|
||||
<ClCompile Include="..\src\frontend\help\provide.c" />
|
||||
|
|
@ -2543,6 +2547,7 @@ lib /machine:x64 /def:..\..\fftw-3.3-dll64\libfftw3-3.def /out:$(IntDir)libfftw3
|
|||
<ClCompile Include="..\src\spicelib\devices\vdmos\vdmospar.c" />
|
||||
<ClCompile Include="..\src\spicelib\devices\vdmos\vdmospzld.c" />
|
||||
<ClCompile Include="..\src\spicelib\devices\vdmos\vdmosset.c" />
|
||||
<ClCompile Include="..\src\spicelib\devices\vdmos\vdmossoachk.c" />
|
||||
<ClCompile Include="..\src\spicelib\devices\vdmos\vdmostemp.c" />
|
||||
<ClCompile Include="..\src\spicelib\devices\vdmos\vdmostrun.c" />
|
||||
<ClCompile Include="..\src\spicelib\devices\vsrc\vsrc.c" />
|
||||
|
|
|
|||
|
|
@ -2555,6 +2555,7 @@
|
|||
<ClCompile Include="..\src\spicelib\devices\vdmos\vdmospar.c" />
|
||||
<ClCompile Include="..\src\spicelib\devices\vdmos\vdmospzld.c" />
|
||||
<ClCompile Include="..\src\spicelib\devices\vdmos\vdmosset.c" />
|
||||
<ClCompile Include="..\src\spicelib\devices\vdmos\vdmossoachk.c" />
|
||||
<ClCompile Include="..\src\spicelib\devices\vdmos\vdmostemp.c" />
|
||||
<ClCompile Include="..\src\spicelib\devices\vdmos\vdmostrun.c" />
|
||||
<ClCompile Include="..\src\spicelib\devices\vsrc\vsrc.c" />
|
||||
|
|
|
|||
Loading…
Reference in New Issue