diff --git a/DEVICES b/DEVICES index ecffdce58..27a0a7d3a 100644 --- a/DEVICES +++ b/DEVICES @@ -299,11 +299,16 @@ VBIC - Bipolar Junction Transistor Level: 4 Status: - This is the VBIC model. Colin mcAndrews ert al. - Spice 3 porting Dietmar Warning - only 3 terminals - no xcess pahse - no other + This is the Vertical Bipolar InterCompany model. + The author of VBIC is Colin McAndrew + Spice3 Implementation: Dietmar Warning DAnalyse GmbH + + Web Site: + http://www.designers-guide.com/VBIC/index.html + + Notes: This is the three terminals model, without excess phase + and thermal network. + *************************************************************************** ***************************** FET Devices *************************** @@ -579,8 +584,8 @@ HiSIM - Hiroshima-university STARC IGFET Model Initial Release. Ver: 1.2.0 Class: M - Level: TBD - Status: TO BE TESTED + Level: 64 + Status: This is the HiSIM model available from Hiroshima University (Ultra-Small Device Engineering Laboratory) diff --git a/contrib/vbic/README b/contrib/vbic/README new file mode 100644 index 000000000..b0b70d3e4 --- /dev/null +++ b/contrib/vbic/README @@ -0,0 +1,4 @@ +Two scripts from Colin McAndrew for vbic model. + +sgp2vbic - converts a Spice Gummel-Poon model card to a vbic model card. +vbis2sgb - converts a vbic model card to a Spice Gummel-Poom model card. diff --git a/contrib/vbic/sgp2vbic b/contrib/vbic/sgp2vbic new file mode 100644 index 000000000..443dca31d --- /dev/null +++ b/contrib/vbic/sgp2vbic @@ -0,0 +1,322 @@ +#!/bin/sh -- # perl +eval 'exec perl -S -x -w $0 ${1+"$@"}' +if 0; + +# +# sgp2vbic: program to convert an SGP .model card to VBIC +# +# Vers Date Who Comments +# ==== ========== ============= ======== +# 2.0 06/01/00 Colin McAndrew translated from shell/nawk version +# + +sub usage() { + print " +$prog: convert SGP .model card to VBIC .model card + +Usage: $prog [options] modelFile + +Files: + modelFile file with SGP .model card + +Options: + -d debug mode + -h print this help message + -i print detailed information + -v verbose mode + -vbeif Vbe do fwd Early voltage map at Vbe ($Vbeif) + -vceif Vce do fwd Early voltage map at Vce ($Vceif) + -vbcir Vbc do rev Early voltage map at Vbc ($Vbcir) + -vecir Vec do rev Early voltage map at Vec ($Vecir) +"; +} # End of: sub usage + +sub info() { + print " +This program maps an SGP .model card into a VBIC .model card. +For many parameters there is a 1-to-1 mapping between the two, +and the default VBIC parameters are such that the model extensions +that are not part of SGP are turned off. + +There are two fundamental and non-mappable differences between +the two models. First, the IRB emitter crowding based resistance +modulation model is not supported in VBIC. This parameter is +ignored. Second, the Early effect model is different, the bias +dependence is substantially better in VBIC than in SGP. This means +the models can be made to match only at specific biases. +These biases can be specified by the -vxxi[fr] flags. +"; +} # End of: sub info + +# +# Set program names and variables. +# + +$\="\n"; +$,=" "; +$Debug=""; +$Verbose=""; +$Number='([+-]?[0-9]+[.]?[0-9]*|[+-]?[0-9]+[.]?[0-9]*[eE][+-]?[0-9]+|[+-]?[.][0-9]+|[+-]?[.][0-9]+[eE][+-]?[0-9]+)'; +@prog=split("/",$0); +$prog=$prog[$#prog]; +$Pi=atan2(0,-1); +$Vbeif=0.6; +$Vceif=2.5; +$Vbcir=0.5; +$Vecir=2.5; + +# +# Parse command line arguments, allow argument +# flags to be any case. +# + +for (;;){ + if ($#ARGV < 0) { + last; + } elsif ($ARGV[0] =~ /^-d/i) { + $Debug="-d";$Verbose="-v"; + } elsif ($ARGV[0] =~ /^-h/i) { + &usage();exit(0); + } elsif ($ARGV[0] =~ /^-i/i) { + &info();exit(0); + } elsif ($ARGV[0] =~ /^-v$/i) { + $Verbose="-v"; + } elsif ($ARGV[0] =~ /^-vbeif$/i) { + shift(@ARGV); + if (!defined($ARGV[0])) { + die("ERROR: no value specified for -vbeif flag, stopped"); + } + $Vbeif=$ARGV[0]; + if ($Vbeif !~ /$Number/) { + die("ERROR: value for -vbeif flag must be a number, stopped"); + } + } elsif ($ARGV[0] =~ /^-vceif$/i) { + shift(@ARGV); + if (!defined($ARGV[0])) { + die("ERROR: no value specified for -vceif flag, stopped"); + } + $Vceif=$ARGV[0]; + if ($Vceif !~ /$Number/) { + die("ERROR: value for -vceif flag must be a number, stopped"); + } + } elsif ($ARGV[0] =~ /^-vbcir$/i) { + shift(@ARGV); + if (!defined($ARGV[0])) { + die("ERROR: no value specified for -vbcir flag, stopped"); + } + $Vbcir=$ARGV[0]; + if ($Vbcir !~ /$Number/) { + die("ERROR: value for -vbcir flag must be a number, stopped"); + } + } elsif ($ARGV[0] =~ /^-vecir$/i) { + shift(@ARGV); + if (!defined($ARGV[0])) { + die("ERROR: no value specified for -vecir flag, stopped"); + } + $Vecir=$ARGV[0]; + if ($Vecir !~ /$Number/) { + die("ERROR: value for -vecir flag must be a number, stopped"); + } + } elsif ($ARGV[0] =~ /^-/) { + &usage(); + die("ERROR: unknown flag $ARGV[0], stopped"); + } else { + last; + } + shift(@ARGV); +} +if ($#ARGV < 0) { + &usage();exit(1); # exit if no file name is specified +} + +$ModelFile=$ARGV[0]; + +sub QCDEPL { + my($vj,$p,$m,$f)=@_; + my($w,$xx,$cj,$qj); + + $w=1.0-$vj/$p; + if($w>=1.0-$f){ + $cj=$w**(-$m); + $qj=$p*(1.0-$w*$cj)/(1.0-$m); + } else { + $xx=(1.0-$f)**(-(1.0+$m)); + $cj=$xx*(1.0-$f*(1.0+$m)+$m*$vj/$p); + $qj=$xx*((1.0-$f*(1.0+$m))*($vj-$f*$p)+0.5*$m*($vj*$vj-$f*$f*$p*$p)/$p)+$p*(1.0-$xx*(1.0-$f)**2)/(1.0-$m); + } + return($qj,$cj); +} + +# +# Parse model file +# + +open(IF,"$ModelFile") || + die("ERROR: cannot open file $ModelFile, stopped"); +$inModel="no"; +while () { + chomp;tr/A-Z/a-z/; + if ($_ =~ /^\s*$/) {next;} + if ($_ =~ /^\s*\*/) {next;} + last if ($_ !~ /^\+/ && $inModel eq "yes"); + if ($_ =~ /^\s*\.mod/) { + $inModel="yes";$model=$_;next; + } + if ($inModel eq "yes") { + $_=~s/^\+\s*/ /;$model.=$_;next; + } +} +close(IF); +$model=~s/\s*=\s*/=/g; + +# +# Set SGP parameters from .model card +# + +$val{"is"}=1.0e-16; +$val{"bf"}=100.0; +$val{"nf"}=1.0; +$val{"vaf"}=0.0; +$val{"ikf"}=0.0; +$val{"ise"}=0.0; +$val{"ne"}=1.5; +$val{"br"}=1.0; +$val{"nr"}=1.0; +$val{"var"}=0.0; +$val{"ikr"}=0.0; +$val{"isc"}=0.0; +$val{"nc"}=2.0; +$val{"rb"}=0.0; +$val{"rbm"}=0.0; +$val{"re"}=0.0; +$val{"rc"}=0.0; +$val{"cje"}=0.0; +$val{"vje"}=0.75; +$val{"mje"}=0.33; +$val{"cjc"}=0.0; +$val{"vjc"}=0.75; +$val{"mjc"}=0.33; +$val{"xcjc"}=1.0; +$val{"cjs"}=0.0; +$val{"vjs"}=0.75; +$val{"mjs"}=0.0; +$val{"fc"}=0.5; +$val{"tf"}=0.0; +$val{"xtf"}=0.0; +$val{"vtf"}=0.0; +$val{"itf"}=0.0; +$val{"ptf"}=0.0; +$val{"tr"}=0.0; +$val{"kf"}=0.0; +$val{"af"}=1.0; +$val{"eg"}=1.11; +$val{"xtb"}=0.0; +$val{"xti"}=3.0; +$alias{"va"}="vaf"; +$alias{"ik"}="ikf"; +$alias{"c2"}="ise"; +$alias{"vb"}="var"; +$alias{"c4"}="isc"; +$alias{"pe"}="vje"; +$alias{"me"}="mje"; +$alias{"pc"}="vjc"; +$alias{"mc"}="mjc"; +$alias{"ccs"}="cjs"; +$alias{"ps"}="vjs"; +$alias{"ms"}="mjs"; +$alias{"pt"}="xti"; + +@Field=split(/\s+/,$model); +$name=$Field[1]; +for ($i=3;$i<=$#Field;++$i) { + die("ERROR: term $Field[$i] is not in name=value format, stopped") + if ($Field[$i] !~ /=/); + ($param,$value)=split(/=/,$Field[$i]); + die("ERROR: parameter $param must be a number, stopped") + if ($value !~ /$Number/); + if (defined($alias{$param})) {$param=$alias{$param};} + if ($param eq "irb") { + print STDERR "* WARNING: IRB parameter is not supported in vbic"; + next; + } + if (!defined($val{$param})) { + print STDERR "* WARNING: parameter $param is not supported in vbic"; + next; + } + $val{$param}=$value; + if ($param eq "rbm") {$done{"rbm"}="yes";} +} +if (!defined($done{"rbm"})) {$val{"rbm"}=$val{"rb"};} +if($val{"ise"}>1) {$val{"ise"}=$val{"ise"}*$val{"is"};} +if($val{"isc"}>1) {$val{"isc"}=$val{"isc"}*$val{"is"};} +$Vbcif=$Vbeif-$Vceif; +$Vbeir=$Vbcir-$Vecir; +($qjbef,$cj )=&QCDEPL($Vbeif,$val{"vje"},$val{"mje"},$val{"fc"}); +($qjbcf,$cjbcf)=&QCDEPL($Vbcif,$val{"vjc"},$val{"mjc"},$val{"fc"}); +($qjber,$cjber)=&QCDEPL($Vbeir,$val{"vje"},$val{"mje"},$val{"fc"}); +($qjbcr,$cj )=&QCDEPL($Vbcir,$val{"vjc"},$val{"mjc"},$val{"fc"}); +$ivaf=$val{"vaf"};if($ivaf>0){$ivaf=1/$ivaf;} +$ivar=$val{"var"};if($ivar>0){$ivar=1/$ivar;} +$godIf=$ivaf/(1-$Vbeif*$ivar-$Vbcif*$ivaf); +if($godIf<1e-10) {$godIf=1e-10;} +$godIr=$ivar/(1-$Vbeir*$ivar-$Vbcir*$ivaf); +if($godIr<1e-10) {$godIr=1e-10;} +$a11=$qjbcf-$cjbcf/$godIf; +$a12=$qjbef; +$r1=-1.0; +$a21=$qjbcr; +$a22=$qjber-$cjber/$godIr; +$r2=-1.0; +$det=$a11*$a22-$a12*$a21; +$ivef=($r1*$a22-$r2*$a12)/$det; +$iver=($r2*$a11-$r1*$a21)/$det; +$vef=1/$ivef;$ver=1/$iver; + +print '.model '.$name.' vbic ++ rcx = '.$val{"rc"}.' ++ rci = '."0.0".' ++ rbx = '.$val{"rbm"}.' ++ rbi = '.($val{"rb"}-$val{"rbm"}).' ++ re = '.$val{"re"}.' ++ is = '.$val{"is"}.' ++ nf = '.$val{"nf"}.' ++ nr = '.$val{"nr"}.' ++ fc = '.$val{"fc"}.' ++ cje = '.$val{"cje"}.' ++ pe = '.$val{"vje"}.' ++ me = '.$val{"mje"}.' ++ cjc = '.($val{"cjc"}*$val{"xcjc"}).' ++ cjep = '.($val{"cjc"}*(1.0-$val{"xcjc"})).' ++ pc = '.$val{"vjc"}.' ++ mc = '.$val{"mjc"}.' ++ cjcp = '.$val{"cjs"}.' ++ ps = '.$val{"vjs"}.' ++ ms = '.$val{"mjs"}.' ++ ibei = '.($val{"is"}/$val{"bf"}).' ++ nei = '.$val{"nf"}.' ++ iben = '.$val{"ise"}.' ++ nen = '.$val{"ne"}.' ++ ibci = '.($val{"is"}/$val{"br"}).' ++ nci = '.$val{"nr"}.' ++ ibcn = '.$val{"isc"}.' ++ ncn = '.$val{"nc"}.' ++ vef = '.$vef.' ++ ver = '.$ver.' ++ ikf = '.$val{"ikf"}.' ++ ikr = '.$val{"ikr"}.' ++ tf = '.$val{"tf"}.' ++ xtf = '.$val{"xtf"}.' ++ vtf = '.$val{"vtf"}.' ++ itf = '.$val{"itf"}.' ++ tr = '.$val{"tr"}.' ++ td = '.($val{"tf"}*$val{"ptf"}*$Pi/180.0).' ++ ea = '.$val{"eg"}.' ++ eaie = '.$val{"eg"}.' ++ eaic = '.$val{"eg"}.' ++ eane = '.$val{"eg"}.' ++ eanc = '.$val{"eg"}.' ++ xis = '.$val{"xti"}.' ++ xii = '.($val{"xti"}-$val{"xtb"}).' ++ xin = '.($val{"xti"}-$val{"ne"}*$val{"xtb"}).' ++ kfn = '.$val{"kf"}.' ++ afn = '.$val{"af"}; diff --git a/contrib/vbic/vbic2sgp b/contrib/vbic/vbic2sgp new file mode 100644 index 000000000..8d4a95083 --- /dev/null +++ b/contrib/vbic/vbic2sgp @@ -0,0 +1,311 @@ +#!/bin/sh -- # perl +eval 'exec perl -S -x -w $0 ${1+"$@"}' +if 0; + +# +# vbic2sgp: program to convert a VBIC .model card to SGP +# +# Vers Date Who Comments +# ==== ========== ============= ======== +# 1.0 07/17/00 Colin McAndrew modified sgp2vbic +# + +sub usage() { + print " +$prog: convert VBIC .model card to SGP .model card + +Usage: $prog [options] modelFile + +Files: + modelFile file with VBIC .model card + +Options: + -d debug mode + -h print this help message + -i print detailed information + -v verbose mode + -vbeif Vbe do fwd Early voltage map at Vbe ($Vbeif) + -vceif Vce do fwd Early voltage map at Vce ($Vceif) + -vbcir Vbc do rev Early voltage map at Vbc ($Vbcir) + -vecir Vec do rev Early voltage map at Vec ($Vecir) +"; +} # End of: sub usage + +sub info() { + print " +This program maps a VBIC .model card into an SGP .model card. +For many parameters there is a 1-to-1 mapping between the two, +and the default VBIC parameters are such that the model extensions +that are not part of SGP are turned off. However if the extensions +in VBIC are used, clearly they are not translated into SGP. + +In particular, note that using the separate ideality coefficients +for base current in VBIC will give a model that will NOT translate +into SGP properly. A simple calculation of BF(SGP)=IS(VBIC)/IBEI(VBIC) +is done, that will not be accurate if NEI(VBIC) is not equal to NF(VBIC). + +The Early effect model is different between VBIC and SGP, the bias +dependence is substantially better in VBIC than in SGP. This means +the models can be made to match only at specific biases. +These biases can be specified by the -vxxi[fr] flags. +"; +} # End of: sub info + +# +# Set program names and variables. +# + +$\="\n"; +$,=" "; +$Debug=""; +$Verbose=""; +$Number='([+-]?[0-9]+[.]?[0-9]*|[+-]?[0-9]+[.]?[0-9]*[eE][+-]?[0-9]+|[+-]?[.][0-9]+|[+-]?[.][0-9]+[eE][+-]?[0-9]+)'; +@prog=split("/",$0); +$prog=$prog[$#prog]; +$Pi=atan2(0,-1); +$Vbeif=0.6; +$Vceif=2.5; +$Vbcir=0.5; +$Vecir=2.5; + +# +# Parse command line arguments, allow argument +# flags to be any case. +# + +for (;;){ + if ($#ARGV < 0) { + last; + } elsif ($ARGV[0] =~ /^-d/i) { + $Debug="-d";$Verbose="-v"; + } elsif ($ARGV[0] =~ /^-h/i) { + &usage();exit(0); + } elsif ($ARGV[0] =~ /^-i/i) { + &info();exit(0); + } elsif ($ARGV[0] =~ /^-v$/i) { + $Verbose="-v"; + } elsif ($ARGV[0] =~ /^-vbeif$/i) { + shift(@ARGV); + if (!defined($ARGV[0])) { + die("ERROR: no value specified for -vbeif flag, stopped"); + } + $Vbeif=$ARGV[0]; + if ($Vbeif !~ /$Number/) { + die("ERROR: value for -vbeif flag must be a number, stopped"); + } + } elsif ($ARGV[0] =~ /^-vceif$/i) { + shift(@ARGV); + if (!defined($ARGV[0])) { + die("ERROR: no value specified for -vceif flag, stopped"); + } + $Vceif=$ARGV[0]; + if ($Vceif !~ /$Number/) { + die("ERROR: value for -vceif flag must be a number, stopped"); + } + } elsif ($ARGV[0] =~ /^-vbcir$/i) { + shift(@ARGV); + if (!defined($ARGV[0])) { + die("ERROR: no value specified for -vbcir flag, stopped"); + } + $Vbcir=$ARGV[0]; + if ($Vbcir !~ /$Number/) { + die("ERROR: value for -vbcir flag must be a number, stopped"); + } + } elsif ($ARGV[0] =~ /^-vecir$/i) { + shift(@ARGV); + if (!defined($ARGV[0])) { + die("ERROR: no value specified for -vecir flag, stopped"); + } + $Vecir=$ARGV[0]; + if ($Vecir !~ /$Number/) { + die("ERROR: value for -vecir flag must be a number, stopped"); + } + } elsif ($ARGV[0] =~ /^-/) { + &usage(); + die("ERROR: unknown flag $ARGV[0], stopped"); + } else { + last; + } + shift(@ARGV); +} +if ($#ARGV < 0) { + &usage();exit(1); # exit if no file name is specified +} + +$ModelFile=$ARGV[0]; + +sub QCDEPL { + my($vj,$p,$m,$f)=@_; + my($w,$xx,$cj,$qj); + + $w=1.0-$vj/$p; + if($w>=1.0-$f){ + $cj=$w**(-$m); + $qj=$p*(1.0-$w*$cj)/(1.0-$m); + } else { + $xx=(1.0-$f)**(-(1.0+$m)); + $cj=$xx*(1.0-$f*(1.0+$m)+$m*$vj/$p); + $qj=$xx*((1.0-$f*(1.0+$m))*($vj-$f*$p)+0.5*$m*($vj*$vj-$f*$f*$p*$p)/$p)+$p*(1.0-$xx*(1.0-$f)**2)/(1.0-$m); + } + return($qj,$cj); +} + +# +# Parse model file +# + +open(IF,"$ModelFile") || + die("ERROR: cannot open file $ModelFile, stopped"); +$inModel="no"; +while () { + chomp;tr/A-Z/a-z/; + if ($_ =~ /^\s*$/) {next;} + if ($_ =~ /^\s*\*/) {next;} + last if ($_ !~ /^\+/ && $inModel eq "yes"); + if ($_ =~ /^\s*\.mod/) { + $inModel="yes";$model=$_;next; + } + if ($inModel eq "yes") { + $_=~s/^\+\s*/ /;$model.=$_;next; + } +} +close(IF); +$model=~s/\s*=\s*/=/g; + +# +# Set VBIC parameters from .model card +# + +$val{"is"}=1.0e-16; +$val{"nf"}=1.0; +$val{"nr"}=1.0; +$val{"ibei"}=1.0e-18; +$val{"nei"}=1.0; +$val{"vef"}=0.0; +$val{"ikf"}=0.0; +$val{"iben"}=0.0; +$val{"nen"}=1.5; +$val{"ibci"}=1.0e-16; +$val{"nci"}=1.0; +$val{"ver"}=0.0; +$val{"ikr"}=0.0; +$val{"ibcn"}=0.0; +$val{"ncn"}=2.0; +$val{"rbx"}=0.0; +$val{"rbi"}=0.0; +$val{"re"}=0.0; +$val{"rcx"}=0.0; +$val{"rci"}=0.0; +$val{"cje"}=0.0; +$val{"vje"}=0.75; +$val{"mje"}=0.33; +$val{"fc"}=0.9; +$val{"cjc"}=0.0; +$val{"cjep"}=0.0; +$val{"vjc"}=0.75; +$val{"mjc"}=0.33; +$val{"cjcp"}=0.0; +$val{"vjs"}=0.75; +$val{"mjs"}=0.0; +$val{"tf"}=0.0; +$val{"xtf"}=0.0; +$val{"vtf"}=0.0; +$val{"itf"}=0.0; +$val{"tr"}=0.0; +$val{"td"}=0.0; +$val{"kfn"}=0.0; +$val{"afn"}=1.0; +$val{"ea"}=1.12; +$val{"eaie"}=1.12; +$val{"eaic"}=1.12; +$val{"eane"}=1.12; +$val{"eanc"}=1.12; +$val{"xis"}=3; +$val{"xii"}=3; +$val{"xin"}=3; +$alias{"ik"}="ikf"; +$alias{"pe"}="vje"; +$alias{"me"}="mje"; +$alias{"pc"}="vjc"; +$alias{"mc"}="mjc"; +$alias{"ps"}="vjs"; +$alias{"ms"}="mjs"; + +@Field=split(/\s+/,$model); +$name=$Field[1]; +for ($i=3;$i<=$#Field;++$i) { + die("ERROR: term $Field[$i] is not in name=value format, stopped") + if ($Field[$i] !~ /=/); + ($param,$value)=split(/=/,$Field[$i]); + die("ERROR: parameter $param must be a number, stopped") + if ($value !~ /$Number/); + if (defined($alias{$param})) {$param=$alias{$param};} + if (!defined($val{$param})) { + print STDERR "* WARNING: parameter $param is not supported in sgp"; + next; + } + $val{$param}=$value; +} +$Vbcif=$Vbeif-$Vceif; +$Vbeir=$Vbcir-$Vecir; +($qjbef,$cj )=&QCDEPL($Vbeif,$val{"vje"},$val{"mje"},$val{"fc"}); +($qjbcf,$cjbcf)=&QCDEPL($Vbcif,$val{"vjc"},$val{"mjc"},$val{"fc"}); +($qjber,$cjber)=&QCDEPL($Vbeir,$val{"vje"},$val{"mje"},$val{"fc"}); +($qjbcr,$cj )=&QCDEPL($Vbcir,$val{"vjc"},$val{"mjc"},$val{"fc"}); +$ivef=$val{"vef"};if($ivef>0){$ivef=1/$ivef;} +$iver=$val{"ver"};if($iver>0){$iver=1/$iver;} +$godIf=$cjbcf*$ivef/(1+$qjbef*$iver+$qjbcf*$ivef); +if($godIf<1e-10) {$godIf=1e-10;} +$godIr=$cjber*$iver/(1+$qjber*$iver+$qjbcr*$ivef); +if($godIr<1e-10) {$godIr=1e-10;} +$a11=-$Vbcif-1.0/$godIf; +$a12=-$Vbeif; +$r1 =-1.0; +$a21=-$Vbcir; +$a22=-$Vbeir-1.0/$godIr; +$r2 =-1.0; +$det=$a11*$a22-$a12*$a21; +$ivaf=($r1*$a22-$r2*$a12)/$det; +$ivar=($r2*$a11-$r1*$a21)/$det; +$vaf=1/$ivaf;$var=1/$ivar; + +print '.model '.$name.' sgp ++ rc = '.($val{"rcx"}+$val{"rci"}).' ++ rbm = '.$val{"rbx"}.' ++ rb = '.($val{"rbx"}+$val{"rbi"}).' ++ re = '.$val{"re"}.' ++ is = '.$val{"is"}.' ++ nf = '.$val{"nf"}.' ++ nr = '.$val{"nr"}.' ++ fc = '.$val{"fc"}.' ++ cje = '.$val{"cje"}.' ++ vje = '.$val{"vje"}.' ++ mje = '.$val{"mje"}.' ++ cjc = '.($val{"cjc"}+$val{"cjep"}).' ++ xcjc = '.($val{"cjc"}/($val{"cjc"}+$val{"cjep"})).' ++ pjc = '.$val{"vjc"}.' ++ mjc = '.$val{"mjc"}.' ++ cjs = '.$val{"cjcp"}.' ++ pjs = '.$val{"vjs"}.' ++ mjs = '.$val{"mjs"}.' ++ bf = '.($val{"is"}/$val{"ibei"}).' ++ ise = '.$val{"iben"}.' ++ ne = '.$val{"nen"}.' ++ br = '.($val{"is"}/$val{"ibci"}).' ++ isc = '.$val{"ibcn"}.' ++ nc = '.$val{"ncn"}.' ++ vaf = '.$vaf.' ++ var = '.$var.' ++ ikf = '.$val{"ikf"}.' ++ ikr = '.$val{"ikr"}.' ++ tf = '.$val{"tf"}.' ++ xtf = '.$val{"xtf"}.' ++ vtf = '.$val{"vtf"}.' ++ itf = '.$val{"itf"}.' ++ tr = '.$val{"tr"}.' ++ ptf = '.($val{"td"}*180.0/($val{"tf"}*$Pi)).' ++ eg = '.$val{"ea"}.' ++ xti = '.$val{"xis"}.' ++ xtb = '.($val{"xis"}-$val{"xii"}).' ++ kf = '.$val{"kfn"}.' ++ af = '.$val{"afn"}; diff --git a/src/Makefile.am b/src/Makefile.am index 6be5a9007..1c4103da9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -124,7 +124,7 @@ ngnutmeg_LDADD = \ frontend/help/libhlp.a \ maths/cmaths/libcmaths.a \ maths/poly/libpoly.a \ - misc/libmisc.a + misc/libmisc.a ## help: @@ -146,7 +146,7 @@ ngsconvert_LDADD = \ frontend/libfte.a \ frontend/parser/libparser.a \ misc/libmisc.a - + ## proc2mod: ngproc2mod_SOURCES = ngproc2mod.c diff --git a/src/spicelib/devices/Makefile.am b/src/spicelib/devices/Makefile.am index 3a4b11350..f081b712f 100644 --- a/src/spicelib/devices/Makefile.am +++ b/src/spicelib/devices/Makefile.am @@ -44,6 +44,7 @@ SUBDIRS = \ tra \ txl \ urc \ + vbic \ vccs \ vcvs \ vsrc \ diff --git a/src/spicelib/devices/dev.c b/src/spicelib/devices/dev.c index de796f511..099e3d04b 100644 --- a/src/spicelib/devices/dev.c +++ b/src/spicelib/devices/dev.c @@ -39,7 +39,7 @@ #ifdef XSPICE /*saj headers for xspice*/ #include /* for strcpy, strcat*/ -#include /* to load librarys*/ +#include /* to load libraries*/ #include "dllitf.h" /* the coreInfo Structure*/ #include "evtudn.h" /*Use defined nodes */ @@ -55,7 +55,7 @@ int add_udn(int,Evt_Udn_Info_t **); #define DEVICES_USED "asrc bjt bjt2 bsim1 bsim2 bsim3 bsim3v2 bsim3v1 bsim4 bsim3soipd bsim3soifd \ bsim3soidd cap cccs ccvs csw dio hfet hfet2 ind isrc jfet ltra mes mesa mos1 \ - mos2 mos3 mos6 mos9 res soi3 sw tra urc vccs vcvs vsrc (ekv)" + mos2 mos3 mos6 mos9 res soi3 sw tra urc vbic vccs vcvs vsrc (ekv)" /* @@ -116,6 +116,7 @@ int add_udn(int,Evt_Udn_Info_t **); #include "tra/traitf.h" #include "txl/txlitf.h" #include "urc/urcitf.h" +#include "vbic/vbicitf.h" #include "vccs/vccsitf.h" #include "vcvs/vcvsitf.h" #include "vsrc/vsrcitf.h" @@ -137,17 +138,17 @@ int add_udn(int,Evt_Udn_Info_t **); #include "ekv/ekvitf.h" #ifdef XSPICE - static int DEVNUM = 52; + static int DEVNUM = 53; #else - #define DEVNUM 52 + #define DEVNUM 53 #endif #else #ifdef XSPICE - static int DEVNUM = 51; + static int DEVNUM = 52; #else - #define DEVNUM 51 + #define DEVNUM 52 #endif #endif @@ -157,15 +158,15 @@ int add_udn(int,Evt_Udn_Info_t **); #ifdef HAVE_EKV #include "ekv/ekvitf.h" #ifdef XSPICE - static int DEVNUM = 47; + static int DEVNUM = 48; #else - #define DEVNUM 47 + #define DEVNUM 48 #endif #else #ifdef XSPICE - static int DEVNUM = 46; + static int DEVNUM = 47; #else - #define DEVNUM 46 + #define DEVNUM 47 #endif #endif @@ -248,28 +249,30 @@ spice_init_devices(void) DEVices[40] = get_sw_info(); DEVices[41] = get_tra_info(); DEVices[42] = get_txl_info(); - DEVices[43] = get_vccs_info(); - DEVices[44] = get_vcvs_info(); - DEVices[45] = get_vsrc_info(); + DEVices[43] = get_vbic_info(); + DEVices[44] = get_vccs_info(); + DEVices[45] = get_vcvs_info(); + DEVices[46] = get_vsrc_info(); + #ifdef CIDER - DEVices[46] = get_nbjt_info(); - DEVices[47] = get_nbjt2_info(); - DEVices[48] = get_numd_info(); - DEVices[49] = get_numd2_info(); - DEVices[50] = get_numos_info(); + DEVices[47] = get_nbjt_info(); + DEVices[48] = get_nbjt2_info(); + DEVices[49] = get_numd_info(); + DEVices[50] = get_numd2_info(); + DEVices[51] = get_numos_info(); #ifdef HAVE_EKV - DEVices[51] = get_ekv_info(); - assert(52 == DEVNUM); + DEVices[52] = get_ekv_info(); + assert(53 == DEVNUM); #else /* NOT EKV */ - assert(51 == DEVNUM); + assert(52 == DEVNUM); #endif /* HAVE_EKV */ #else /* NOT CIDER */ #ifdef HAVE_EKV - DEVices[46] = get_ekv_info(); - assert(47 == DEVNUM); + DEVices[47] = get_ekv_info(); + assert(48 == DEVNUM); #else - assert(46 == DEVNUM); + assert(47 == DEVNUM); #endif #endif /* CIDER */ return; @@ -299,11 +302,11 @@ devices(void) #ifdef DEVLIB /*not yet usable*/ #ifdef HAVE_EKV -#define DEVICES_USED {"asrc", "bjt", "bjt2", "bsim1", "bsim2", "bsim3", "bsim3v2", "bsim3v1", "bsim4", "bsim3soipd", "bsim3soifd", \ +#define DEVICES_USED {"asrc", "bjt", "bjt2", "vbic", "bsim1", "bsim2", "bsim3", "bsim3v2", "bsim3v1", "bsim4", "bsim3soipd", "bsim3soifd", \ "bsim3soidd", "cap", "cccs", "ccvs", "csw", "dio", "hfet", "hfet2", "ind", "isrc", "jfet", "ltra", "mes", "mesa" ,"mos1", \ "mos2", "mos3", "mos6", "mos9", "res", "soi3", "sw", "tra", "urc", "vccs", "vcvs", "vsrc", "ekv" } #else -#define DEVICES_USED {"asrc", "bjt", "bjt2", "bsim1", "bsim2", "bsim3", "bsim3v2", "bsim3v1", "bsim4", "bsim3soipd", "bsim3soifd", \ +#define DEVICES_USED {"asrc", "bjt", "bjt2", "vbic", "bsim1", "bsim2", "bsim3", "bsim3v2", "bsim3v1", "bsim4", "bsim3soipd", "bsim3soifd", \ "bsim3soidd", "cap", "cccs", "ccvs", "csw", "dio", "hfet", "hfet2", "ind", "isrc", "jfet", "ltra", "mes", "mesa" ,"mos1", \ "mos2", "mos3", "mos6", "mos9", "res", "soi3", "sw", "tra", "urc", "vccs", "vcvs", "vsrc"} #endif diff --git a/src/spicelib/devices/vbic/Makefile.am b/src/spicelib/devices/vbic/Makefile.am new file mode 100644 index 000000000..329dac8b1 --- /dev/null +++ b/src/spicelib/devices/vbic/Makefile.am @@ -0,0 +1,33 @@ +## Process this file with automake to produce Makefile.in + +noinst_LIBRARIES = libvbic.a + +libvbic_a_SOURCES = \ + vbic.c \ + vbicacld.c \ + vbicask.c \ + vbicconv.c \ + vbicdefs.h \ + vbicdel.c \ + vbicdest.c \ + vbicext.h \ + vbicgetic.c \ + vbicinit.c \ + vbicinit.h \ + vbicitf.h \ + vbicload.c \ + vbicmask.c \ + vbicmdel.c \ + vbicmpar.c \ + vbicnoise.c \ + vbicparam.c \ + vbicpzld.c \ + vbicsetup.c \ + vbictemp.c \ + vbictrunc.c + + + +INCLUDES = -I$(top_srcdir)/src/include + +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/spicelib/devices/vbic/vbic.c b/src/spicelib/devices/vbic/vbic.c new file mode 100644 index 000000000..fe383ece0 --- /dev/null +++ b/src/spicelib/devices/vbic/vbic.c @@ -0,0 +1,194 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1995 Colin McAndrew Motorola +Spice3 Implementation: 2003 Dietmar Warning DAnalyse GmbH +**********/ + +/* + * This file defines the VBIC data structures that are + * available to the next level(s) up the calling hierarchy + */ + +#include "ngspice.h" +#include "devdefs.h" +#include "vbicdefs.h" +#include "suffix.h" + +IFparm VBICpTable[] = { /* parameters */ + IOPU("area", VBIC_AREA, IF_REAL, "Area factor"), + IOPU("off", VBIC_OFF, IF_FLAG, "Device initially off"), + IP("ic", VBIC_IC, IF_REALVEC, "Initial condition vector"), + IOPAU("icvbe", VBIC_IC_VBE, IF_REAL, "Initial B-E voltage"), + IOPAU("icvce", VBIC_IC_VCE, IF_REAL, "Initial C-E voltage"), + IOPU("temp", VBIC_TEMP, IF_REAL, "Instance temperature"), + IOPU("dtemp", VBIC_DTEMP, IF_REAL, "Instance delta temperature"), + IOPU("m", VBIC_M, IF_REAL, "Multiplier"), + + OPU("collnode", VBIC_QUEST_COLLNODE, IF_INTEGER, "Number of collector node"), + OPU("basenode", VBIC_QUEST_BASENODE, IF_INTEGER, "Number of base node"), + OPU("emitnode", VBIC_QUEST_EMITNODE, IF_INTEGER, "Number of emitter node"), + OPU("collCXnode",VBIC_QUEST_COLLCXNODE,IF_INTEGER, "Internal collector node"), + OPU("collCInode",VBIC_QUEST_COLLCINODE,IF_INTEGER, "Internal collector node"), + OPU("baseBXnode",VBIC_QUEST_BASEBXNODE,IF_INTEGER, "Internal base node"), + OPU("baseBInode",VBIC_QUEST_BASEBINODE,IF_INTEGER, "Internal base node"), + OPU("baseBPnode",VBIC_QUEST_BASEBPNODE,IF_INTEGER, "Internal base node"), + OPU("emitEInode",VBIC_QUEST_EMITEINODE,IF_INTEGER, "Internal emitter node"), + OP("vbe", VBIC_QUEST_VBE, IF_REAL, "B-E voltage"), + OP("vbc", VBIC_QUEST_VBC, IF_REAL, "B-C voltage"), + OP("ic", VBIC_QUEST_CC, IF_REAL, "Collector current"), + OP("ib", VBIC_QUEST_CB, IF_REAL, "Base current"), + OP("ie", VBIC_QUEST_CE, IF_REAL, "Emitter current"), + OP("gm", VBIC_QUEST_GM, IF_REAL, "Small signal transconductance dIc/dVbe"), + OP("go", VBIC_QUEST_GO, IF_REAL, "Small signal output conductance dIc/dVbc"), + OP("gpi", VBIC_QUEST_GPI, IF_REAL, "Small signal input conductance dIb/dVbe"), + OP("gmu", VBIC_QUEST_GMU, IF_REAL, "Small signal conductance dIb/dVbc"), + OP("gx", VBIC_QUEST_GX, IF_REAL, "Conductance from base to internal base"), + OP("cbe", VBIC_QUEST_CBE, IF_REAL, "Internal base to emitter capacitance"), + OP("cbex", VBIC_QUEST_CBEX, IF_REAL, "External base to emitter capacitance"), + OP("cbc", VBIC_QUEST_CBC, IF_REAL, "Internal base to collector capacitance"), + OP("cbcx", VBIC_QUEST_CBCX, IF_REAL, "External Base to collector capacitance"), + OP("p", VBIC_QUEST_POWER,IF_REAL, "Power dissipation"), + OPU("geqcb",VBIC_QUEST_GEQCB,IF_REAL, "Internal C-B-base cap. equiv. cond."), + OPU("geqbx",VBIC_QUEST_GEQBX,IF_REAL, "External C-B-base cap. equiv. cond."), + OPU("qbe", VBIC_QUEST_QBE, IF_REAL, "Charge storage B-E junction"), + OPU("cqbe", VBIC_QUEST_CQBE, IF_REAL, "Cap. due to charge storage in B-E jct."), + OPU("qbc", VBIC_QUEST_QBC, IF_REAL, "Charge storage B-C junction"), + OPU("cqbc", VBIC_QUEST_CQBC, IF_REAL, "Cap. due to charge storage in B-C jct."), + OPU("qbx", VBIC_QUEST_QBX, IF_REAL, "Charge storage B-X junction"), + OPU("cqbx", VBIC_QUEST_CQBX, IF_REAL, "Cap. due to charge storage in B-X jct."), + OPU("sens_dc", VBIC_QUEST_SENS_DC, IF_REAL, "DC sensitivity "), + OPU("sens_real",VBIC_QUEST_SENS_REAL, IF_REAL, "Real part of AC sensitivity"), + OPU("sens_imag",VBIC_QUEST_SENS_IMAG,IF_REAL, "DC sens. & imag part of AC sens."), + OPU("sens_mag", VBIC_QUEST_SENS_MAG, IF_REAL, "Sensitivity of AC magnitude"), + OPU("sens_ph", VBIC_QUEST_SENS_PH, IF_REAL, "Sensitivity of AC phase"), + OPU("sens_cplx",VBIC_QUEST_SENS_CPLX, IF_COMPLEX, "AC sensitivity") +}; + +IFparm VBICmPTable[] = { /* model parameters */ + OP("type", VBIC_MOD_TYPE, IF_STRING, "NPN or PNP"), + IOPU("npn", VBIC_MOD_NPN, IF_FLAG, "NPN type device"), + IOPU("pnp", VBIC_MOD_PNP, IF_FLAG, "PNP type device"), + IOP("tnom", VBIC_MOD_TNOM, IF_REAL, "Parameter measurement temperature"), + IOP("rcx", VBIC_MOD_RCX, IF_REAL, "Extrinsic coll resistance"), + IOP("rci", VBIC_MOD_RCI, IF_REAL, "Intrinsic coll resistance"), + IOP("vo", VBIC_MOD_VO, IF_REAL, "Epi drift saturation voltage"), + IOP("gamm", VBIC_MOD_GAMM, IF_REAL, "Epi doping parameter"), + IOP("hrcf", VBIC_MOD_HRCF, IF_REAL, "High current RC factor"), + IOP("rbx", VBIC_MOD_RBX, IF_REAL, "Extrinsic base resistance"), + IOP("rbi", VBIC_MOD_RBI, IF_REAL, "Intrinsic base resistance"), + IOP("re", VBIC_MOD_RE, IF_REAL, "Intrinsic emitter resistance"), + IOP("rs", VBIC_MOD_RS, IF_REAL, "Intrinsic substrate resistance"), + IOP("rbp", VBIC_MOD_RBP, IF_REAL, "Parasitic base resistance"), + IOP("is", VBIC_MOD_IS, IF_REAL, "Transport saturation current"), + IOP("nf", VBIC_MOD_NF, IF_REAL, "Forward emission coefficient"), + IOP("nr", VBIC_MOD_NR, IF_REAL, "Reverse emission coefficient"), + IOP("fc", VBIC_MOD_FC, IF_REAL, "Fwd bias depletion capacitance limit"), + IOP("cbeo", VBIC_MOD_CBEO, IF_REAL, "Extrinsic B-E overlap capacitance"), + IOP("cje", VBIC_MOD_CJE, IF_REAL, "Zero bias B-E depletion capacitance"), + IOP("pe", VBIC_MOD_PE, IF_REAL, "B-E built in potential"), + IOP("me", VBIC_MOD_ME, IF_REAL, "B-E junction grading coefficient"), + IOP("aje", VBIC_MOD_AJE, IF_REAL, "B-E capacitance smoothing factor"), + IOP("cbco", VBIC_MOD_CBCO, IF_REAL, "Extrinsic B-C overlap capacitance"), + IOP("cjc", VBIC_MOD_CJC, IF_REAL, "Zero bias B-C depletion capacitance"), + IOP("qco", VBIC_MOD_QCO, IF_REAL, "Epi charge parameter"), + IOP("cjep", VBIC_MOD_CJEP, IF_REAL, "B-C extrinsic zero bias capacitance"), + IOP("pc", VBIC_MOD_PC, IF_REAL, "B-C built in potential"), + IOP("mc", VBIC_MOD_MC, IF_REAL, "B-C junction grading coefficient"), + IOP("ajc", VBIC_MOD_AJC, IF_REAL, "B-C capacitance smoothing factor"), + IOP("cjcp", VBIC_MOD_CJCP, IF_REAL, "Zero bias S-C capacitance"), + IOP("ps", VBIC_MOD_PS, IF_REAL, "S-C junction built in potential"), + IOP("ms", VBIC_MOD_MS, IF_REAL, "S-C junction grading coefficient"), + IOP("ajs", VBIC_MOD_AJS, IF_REAL, "S-C capacitance smoothing factor"), + IOP("ibei", VBIC_MOD_IBEI, IF_REAL, "Ideal B-E saturation current"), + IOP("wbe", VBIC_MOD_WBE, IF_REAL, "Portion of IBEI from Vbei, 1-WBE from Vbex"), + IOP("nei", VBIC_MOD_NEI, IF_REAL, "Ideal B-E emission coefficient"), + IOP("iben", VBIC_MOD_IBEN, IF_REAL, "Non-ideal B-E saturation current"), + IOP("nen", VBIC_MOD_NEN, IF_REAL, "Non-ideal B-E emission coefficient"), + IOP("ibci", VBIC_MOD_IBCI, IF_REAL, "Ideal B-C saturation current"), + IOP("nci", VBIC_MOD_NCI, IF_REAL, "Ideal B-C emission coefficient"), + IOP("ibcn", VBIC_MOD_IBCN, IF_REAL, "Non-ideal B-C saturation current"), + IOP("ncn", VBIC_MOD_NCN, IF_REAL, "Non-ideal B-C emission coefficient"), + IOP("avc1", VBIC_MOD_AVC1, IF_REAL, "B-C weak avalanche parameter 1"), + IOP("avc2", VBIC_MOD_AVC2, IF_REAL, "B-C weak avalanche parameter 2"), + IOP("isp", VBIC_MOD_ISP, IF_REAL, "Parasitic transport saturation current"), + IOP("wsp", VBIC_MOD_WSP, IF_REAL, "Portion of ICCP"), + IOP("nfp", VBIC_MOD_NFP, IF_REAL, "Parasitic fwd emission coefficient"), + IOP("ibeip", VBIC_MOD_IBEIP, IF_REAL, "Ideal parasitic B-E saturation current"), + IOP("ibenp", VBIC_MOD_IBENP, IF_REAL, "Non-ideal parasitic B-E saturation current"), + IOP("ibcip", VBIC_MOD_IBCIP, IF_REAL, "Ideal parasitic B-C saturation current"), + IOP("ncip", VBIC_MOD_NCIP, IF_REAL, "Ideal parasitic B-C emission coefficient"), + IOP("ibcnp", VBIC_MOD_IBCNP, IF_REAL, "Nonideal parasitic B-C saturation current"), + IOP("ncnp", VBIC_MOD_NCNP, IF_REAL, "Nonideal parasitic B-C emission coefficient"), + IOP("vef", VBIC_MOD_VEF, IF_REAL, "Forward Early voltage"), + IOP("ver", VBIC_MOD_VER, IF_REAL, "Reverse Early voltage"), + IOP("ikf", VBIC_MOD_IKF, IF_REAL, "Forward knee current"), + IOP("ikr", VBIC_MOD_IKR, IF_REAL, "Reverse knee current"), + IOP("ikp", VBIC_MOD_IKP, IF_REAL, "Parasitic knee current"), + IOP("tf", VBIC_MOD_TF, IF_REAL, "Ideal forward transit time"), + IOP("qtf", VBIC_MOD_QTF, IF_REAL, "Variation of TF with base-width modulation"), + IOP("xtf", VBIC_MOD_XTF, IF_REAL, "Coefficient for bias dependence of TF"), + IOP("vtf", VBIC_MOD_VTF, IF_REAL, "Voltage giving VBC dependence of TF"), + IOP("itf", VBIC_MOD_ITF, IF_REAL, "High current dependence of TF"), + IOP("tr", VBIC_MOD_TR, IF_REAL, "Ideal reverse transit time"), + IOP("td", VBIC_MOD_TD, IF_REAL, "Forward excess-phase delay time"), + IOP("kfn", VBIC_MOD_KFN, IF_REAL, "B-E Flicker Noise Coefficient"), + IOP("afn", VBIC_MOD_AFN, IF_REAL, "B-E Flicker Noise Exponent"), + IOP("bfn", VBIC_MOD_BFN, IF_REAL, "B-E Flicker Noise 1/f dependence"), + IOP("xre", VBIC_MOD_XRE, IF_REAL, "Temperature exponent of RE"), + IOP("xrbi", VBIC_MOD_XRBI, IF_REAL, "Temperature exponent of RBI"), + IOP("xrci", VBIC_MOD_XRCI, IF_REAL, "Temperature exponent of RCI"), + IOP("xrs", VBIC_MOD_XRS, IF_REAL, "Temperature exponent of RS"), + IOP("xvo", VBIC_MOD_XVO, IF_REAL, "Temperature exponent of VO"), + IOP("ea", VBIC_MOD_EA, IF_REAL, "Activation energy for IS"), + IOP("eaie", VBIC_MOD_EAIE, IF_REAL, "Activation energy for IBEI"), + IOP("eaic", VBIC_MOD_EAIS, IF_REAL, "Activation energy for IBCI/IBEIP"), + IOP("eais", VBIC_MOD_EAIS, IF_REAL, "Activation energy for IBCIP"), + IOP("eane", VBIC_MOD_EANE, IF_REAL, "Activation energy for IBEN"), + IOP("eanc", VBIC_MOD_EANC, IF_REAL, "Activation energy for IBCN/IBENP"), + IOP("eans", VBIC_MOD_EANS, IF_REAL, "Activation energy for IBCNP"), + IOP("xis", VBIC_MOD_XIS, IF_REAL, "Temperature exponent of IS"), + IOP("xii", VBIC_MOD_XII, IF_REAL, "Temperature exponent of IBEI,IBCI,IBEIP,IBCIP"), + IOP("xin", VBIC_MOD_XIN, IF_REAL, "Temperature exponent of IBEN,IBCN,IBENP,IBCNP"), + IOP("tnf", VBIC_MOD_TNF, IF_REAL, "Temperature exponent of NF"), + IOP("tavc", VBIC_MOD_TAVC, IF_REAL, "Temperature exponent of AVC2"), + IOP("rth", VBIC_MOD_RTH, IF_REAL, "Thermal resistance"), + IOP("cth", VBIC_MOD_CTH, IF_REAL, "Thermal capacitance"), + IOP("vrt", VBIC_MOD_VRT, IF_REAL, "Punch-through voltage of internal B-C junction"), + IOP("art", VBIC_MOD_ART, IF_REAL, "Smoothing parameter for reach-through"), + IOP("ccso", VBIC_MOD_CCSO, IF_REAL, "Fixed C-S capacitance"), + IOP("qbm", VBIC_MOD_QBM, IF_REAL, "Select SGP qb formulation"), + IOP("nkf", VBIC_MOD_NKF, IF_REAL, "High current beta rolloff"), + IOP("xikf", VBIC_MOD_XIKF, IF_REAL, "Temperature exponent of IKF"), + IOP("xrcx", VBIC_MOD_XRCX, IF_REAL, "Temperature exponent of RCX"), + IOP("xrbx", VBIC_MOD_XRBX, IF_REAL, "Temperature exponent of RBX"), + IOP("xrbp", VBIC_MOD_XRBP, IF_REAL, "Temperature exponent of RBP"), + IOP("isrr", VBIC_MOD_ISRR, IF_REAL, "Separate IS for fwd and rev"), + IOP("xisr", VBIC_MOD_XISR, IF_REAL, "Temperature exponent of ISR"), + IOP("dear", VBIC_MOD_DEAR, IF_REAL, "Delta activation energy for ISRR"), + IOP("eap", VBIC_MOD_EAP, IF_REAL, "Exitivation energy for ISP"), + IOP("vbbe", VBIC_MOD_VBBE, IF_REAL, "B-E breakdown voltage"), + IOP("nbbe", VBIC_MOD_NBBE, IF_REAL, "B-E breakdown emission coefficient"), + IOP("ibbe", VBIC_MOD_IBBE, IF_REAL, "B-E breakdown current"), + IOP("tvbbe1",VBIC_MOD_TVBBE1,IF_REAL, "Linear temperature coefficient of VBBE"), + IOP("tvbbe2",VBIC_MOD_TVBBE2,IF_REAL, "Quadratic temperature coefficient of VBBE"), + IOP("tnbbe", VBIC_MOD_TNBBE, IF_REAL, "Temperature coefficient of NBBE"), + IOP("ebbe", VBIC_MOD_EBBE, IF_REAL, "exp(-VBBE/(NBBE*Vtv))"), + IOP("dtemp", VBIC_MOD_DTEMP, IF_REAL, "Locale Temperature difference"), + IOP("vers", VBIC_MOD_VERS, IF_REAL, "Revision Version"), + IOP("vref", VBIC_MOD_VREF, IF_REAL, "Reference Version"), +}; + +char *VBICnames[] = { + "collector", + "base", + "emitter", + "substrate" +}; + + +int VBICnSize = NUMELEMS(VBICnames); +int VBICpTSize = NUMELEMS(VBICpTable); +int VBICmPTSize = NUMELEMS(VBICmPTable); +int VBICiSize = sizeof(VBICinstance); +int VBICmSize = sizeof(VBICmodel); diff --git a/src/spicelib/devices/vbic/vbicacld.c b/src/spicelib/devices/vbic/vbicacld.c new file mode 100644 index 000000000..501609d8d --- /dev/null +++ b/src/spicelib/devices/vbic/vbicacld.c @@ -0,0 +1,245 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1995 Colin McAndrew Motorola +Spice3 Implementation: 2003 Dietmar Warning DAnalyse GmbH +**********/ + +/* + * Function to load the COMPLEX circuit matrix using the + * small signal parameters saved during a previous DC operating + * point analysis. + */ + +#include "ngspice.h" +#include "cktdefs.h" +#include "vbicdefs.h" +#include "sperror.h" +#include "suffix.h" + +int +VBICacLoad(GENmodel *inModel, CKTcircuit *ckt) +{ + VBICinstance *here; + VBICmodel *model = (VBICmodel*)inModel; + double Ibe_Vbei,Ibex_Vbex + ,Itzf_Vbei,Itzf_Vbci,Itzr_Vbci,Itzr_Vbei,Ibc_Vbci + ,Ibc_Vbei,Ibep_Vbep,Ircx_Vrcx,Irci_Vrci + ,Irci_Vbci,Irci_Vbcx,Irbx_Vrbx,Irbi_Vrbi,Irbi_Vbei + ,Irbi_Vbci,Ire_Vre,Irbp_Vrbp,Irbp_Vbep,Irbp_Vbci; + double XQbe_Vbei, XQbe_Vbci, XQbex_Vbex, XQbc_Vbci, + XQbcx_Vbcx, XQbep_Vbep, XQbep_Vbci; + + /* loop through all the models */ + for( ; model != NULL; model = model->VBICnextModel) { + + /* loop through all the instances of the model */ + for( here = model->VBICinstances; here!= NULL; + here = here->VBICnextInstance) { + + if (here->VBICowner != ARCHme) continue; + + Ircx_Vrcx = 1.0 / here->VBICtextCollResist * here->VBICarea * here->VBICm; + Irbx_Vrbx = 1.0 / here->VBICtextBaseResist * here->VBICarea * here->VBICm; + Ire_Vre = 1.0 / here->VBICtemitterResist * here->VBICarea * here->VBICm; + + Ibe_Vbei = *(ckt->CKTstate0 + here->VBICibe_Vbei); + Ibex_Vbex = *(ckt->CKTstate0 + here->VBICibex_Vbex); + Itzf_Vbei = *(ckt->CKTstate0 + here->VBICitzf_Vbei); + Itzf_Vbci = *(ckt->CKTstate0 + here->VBICitzf_Vbci); + Itzr_Vbci = *(ckt->CKTstate0 + here->VBICitzr_Vbci); + Itzr_Vbei = *(ckt->CKTstate0 + here->VBICitzr_Vbei); + Ibc_Vbci = *(ckt->CKTstate0 + here->VBICibc_Vbci); + Ibc_Vbei = *(ckt->CKTstate0 + here->VBICibc_Vbei); + Ibep_Vbep = *(ckt->CKTstate0 + here->VBICibep_Vbep); + Irci_Vrci = *(ckt->CKTstate0 + here->VBICirci_Vrci); + Irci_Vbci = *(ckt->CKTstate0 + here->VBICirci_Vbci); + Irci_Vbcx = *(ckt->CKTstate0 + here->VBICirci_Vbcx); + Irbi_Vrbi = *(ckt->CKTstate0 + here->VBICirbi_Vrbi); + Irbi_Vbei = *(ckt->CKTstate0 + here->VBICirbi_Vbei); + Irbi_Vbci = *(ckt->CKTstate0 + here->VBICirbi_Vbci); + Irbp_Vrbp = *(ckt->CKTstate0 + here->VBICirbp_Vrbp); + Irbp_Vbep = *(ckt->CKTstate0 + here->VBICirbp_Vbep); + Irbp_Vbci = *(ckt->CKTstate0 + here->VBICirbp_Vbci); + +/* +c The real part +*/ +/* +c Stamp element: Ibe +*/ + *(here->VBICbaseBIBaseBIPtr) += Ibe_Vbei; + *(here->VBICbaseBIEmitEIPtr) += -Ibe_Vbei; + *(here->VBICemitEIBaseBIPtr) += -Ibe_Vbei; + *(here->VBICemitEIEmitEIPtr) += Ibe_Vbei; +/* +c Stamp element: Ibex +*/ + *(here->VBICbaseBXBaseBXPtr) += Ibex_Vbex; + *(here->VBICbaseBXEmitEIPtr) += -Ibex_Vbex; + *(here->VBICemitEIBaseBXPtr) += -Ibex_Vbex; + *(here->VBICemitEIEmitEIPtr) += Ibex_Vbex; +/* +c Stamp element: Itzf +*/ + *(here->VBICcollCIBaseBIPtr) += Itzf_Vbei; + *(here->VBICcollCIEmitEIPtr) += -Itzf_Vbei; + *(here->VBICcollCIBaseBIPtr) += Itzf_Vbci; + *(here->VBICcollCICollCIPtr) += -Itzf_Vbci; + *(here->VBICemitEIBaseBIPtr) += -Itzf_Vbei; + *(here->VBICemitEIEmitEIPtr) += Itzf_Vbei; + *(here->VBICemitEIBaseBIPtr) += -Itzf_Vbci; + *(here->VBICemitEICollCIPtr) += Itzf_Vbci; +/* +c Stamp element: Itzr +*/ + *(here->VBICemitEIBaseBIPtr) += Itzr_Vbci; + *(here->VBICemitEICollCIPtr) += -Itzr_Vbci; + *(here->VBICemitEIBaseBIPtr) += Itzr_Vbei; + *(here->VBICemitEIEmitEIPtr) += -Itzr_Vbei; + *(here->VBICcollCIBaseBIPtr) += -Itzr_Vbci; + *(here->VBICcollCICollCIPtr) += Itzr_Vbci; + *(here->VBICcollCIBaseBIPtr) += -Itzr_Vbei; + *(here->VBICcollCIEmitEIPtr) += Itzr_Vbei; +/* +c Stamp element: Ibc +*/ + *(here->VBICbaseBIBaseBIPtr) += Ibc_Vbci; + *(here->VBICbaseBICollCIPtr) += -Ibc_Vbci; + *(here->VBICbaseBIBaseBIPtr) += Ibc_Vbei; + *(here->VBICbaseBIEmitEIPtr) += -Ibc_Vbei; + *(here->VBICcollCIBaseBIPtr) += -Ibc_Vbci; + *(here->VBICcollCICollCIPtr) += Ibc_Vbci; + *(here->VBICcollCIBaseBIPtr) += -Ibc_Vbei; + *(here->VBICcollCIEmitEIPtr) += Ibc_Vbei; +/* +c Stamp element: Ibep +*/ + *(here->VBICbaseBXBaseBXPtr) += Ibep_Vbep; + *(here->VBICbaseBXBaseBPPtr) += -Ibep_Vbep; + *(here->VBICbaseBPBaseBXPtr) += -Ibep_Vbep; + *(here->VBICbaseBPBaseBPPtr) += Ibep_Vbep; +/* +c Stamp element: Ircx +*/ + *(here->VBICcollCollPtr) += Ircx_Vrcx; + *(here->VBICcollCXCollCXPtr) += Ircx_Vrcx; + *(here->VBICcollCXCollPtr) += -Ircx_Vrcx; + *(here->VBICcollCollCXPtr) += -Ircx_Vrcx; +/* +c Stamp element: Irci +*/ + *(here->VBICcollCXCollCXPtr) += Irci_Vrci; + *(here->VBICcollCXCollCIPtr) += -Irci_Vrci; + *(here->VBICcollCXBaseBIPtr) += Irci_Vbci; + *(here->VBICcollCXCollCIPtr) += -Irci_Vbci; + *(here->VBICcollCXBaseBIPtr) += Irci_Vbcx; + *(here->VBICcollCXCollCXPtr) += -Irci_Vbcx; + *(here->VBICcollCICollCXPtr) += -Irci_Vrci; + *(here->VBICcollCICollCIPtr) += Irci_Vrci; + *(here->VBICcollCIBaseBIPtr) += -Irci_Vbci; + *(here->VBICcollCICollCIPtr) += Irci_Vbci; + *(here->VBICcollCIBaseBIPtr) += -Irci_Vbcx; + *(here->VBICcollCICollCXPtr) += Irci_Vbcx; +/* +c Stamp element: Irbx +*/ + *(here->VBICbaseBasePtr) += Irbx_Vrbx; + *(here->VBICbaseBXBaseBXPtr) += Irbx_Vrbx; + *(here->VBICbaseBXBasePtr) += -Irbx_Vrbx; + *(here->VBICbaseBaseBXPtr) += -Irbx_Vrbx; +/* +c Stamp element: Irbi +*/ + *(here->VBICbaseBXBaseBXPtr) += Irbi_Vrbi; + *(here->VBICbaseBXBaseBIPtr) += -Irbi_Vrbi; + *(here->VBICbaseBXBaseBIPtr) += Irbi_Vbei; + *(here->VBICbaseBXEmitEIPtr) += -Irbi_Vbei; + *(here->VBICbaseBXBaseBIPtr) += Irbi_Vbci; + *(here->VBICbaseBXCollCIPtr) += -Irbi_Vbci; + *(here->VBICbaseBIBaseBXPtr) += -Irbi_Vrbi; + *(here->VBICbaseBIBaseBIPtr) += Irbi_Vrbi; + *(here->VBICbaseBIBaseBIPtr) += -Irbi_Vbei; + *(here->VBICbaseBIEmitEIPtr) += Irbi_Vbei; + *(here->VBICbaseBIBaseBIPtr) += -Irbi_Vbci; + *(here->VBICbaseBICollCIPtr) += Irbi_Vbci; +/* +c Stamp element: Ire +*/ + *(here->VBICemitEmitPtr) += Ire_Vre; + *(here->VBICemitEIEmitEIPtr) += Ire_Vre; + *(here->VBICemitEIEmitPtr) += -Ire_Vre; + *(here->VBICemitEmitEIPtr) += -Ire_Vre; +/* +c Stamp element: Irbp +*/ + *(here->VBICbaseBPBaseBPPtr) += Irbp_Vrbp; + *(here->VBICbaseBPCollCXPtr) += -Irbp_Vrbp; + *(here->VBICbaseBPBaseBXPtr) += Irbp_Vbep; + *(here->VBICbaseBPBaseBPPtr) += -Irbp_Vbep; + *(here->VBICbaseBPBaseBIPtr) += Irbp_Vbci; + *(here->VBICbaseBPCollCIPtr) += -Irbp_Vbci; + *(here->VBICcollCXBaseBPPtr) += -Irbp_Vrbp; + *(here->VBICcollCXCollCXPtr) += Irbp_Vrbp; + *(here->VBICcollCXBaseBXPtr) += -Irbp_Vbep; + *(here->VBICcollCXBaseBPPtr) += Irbp_Vbep; + *(here->VBICcollCXBaseBIPtr) += -Irbp_Vbci; + *(here->VBICcollCXCollCIPtr) += Irbp_Vbci; +/* +c The complex part +*/ + XQbe_Vbei = *(ckt->CKTstate0 + here->VBICcqbe) * ckt->CKTomega; + XQbe_Vbci = *(ckt->CKTstate0 + here->VBICcqbeci) * ckt->CKTomega; + XQbex_Vbex = *(ckt->CKTstate0 + here->VBICcqbex) * ckt->CKTomega; + XQbc_Vbci = *(ckt->CKTstate0 + here->VBICcqbc) * ckt->CKTomega; + XQbcx_Vbcx = *(ckt->CKTstate0 + here->VBICcqbcx) * ckt->CKTomega; + XQbep_Vbep = *(ckt->CKTstate0 + here->VBICcqbep) * ckt->CKTomega; + XQbep_Vbci = *(ckt->CKTstate0 + here->VBICcqbepci) * ckt->CKTomega; +/* +c Stamp element: Qbe +*/ + *(here->VBICbaseBIBaseBIPtr + 1) += XQbe_Vbei; + *(here->VBICbaseBIEmitEIPtr + 1) += -XQbe_Vbei; + *(here->VBICbaseBIBaseBIPtr + 1) += XQbe_Vbci; + *(here->VBICbaseBICollCIPtr + 1) += -XQbe_Vbci; + *(here->VBICemitEIBaseBIPtr + 1) += -XQbe_Vbei; + *(here->VBICemitEIEmitEIPtr + 1) += XQbe_Vbei; + *(here->VBICemitEIBaseBIPtr + 1) += -XQbe_Vbci; + *(here->VBICemitEICollCIPtr + 1) += XQbe_Vbci; +/* +c Stamp element: Qbex +*/ + *(here->VBICbaseBXBaseBXPtr + 1) += XQbex_Vbex; + *(here->VBICbaseBXEmitEIPtr + 1) += -XQbex_Vbex; + *(here->VBICemitEIBaseBXPtr + 1) += -XQbex_Vbex; + *(here->VBICemitEIEmitEIPtr + 1) += XQbex_Vbex; +/* +c Stamp element: Qbc +*/ + *(here->VBICbaseBIBaseBIPtr + 1) += XQbc_Vbci; + *(here->VBICbaseBICollCIPtr + 1) += -XQbc_Vbci; + *(here->VBICcollCIBaseBIPtr + 1) += -XQbc_Vbci; + *(here->VBICcollCICollCIPtr + 1) += XQbc_Vbci; +/* +c Stamp element: Qbcx +*/ + *(here->VBICbaseBIBaseBIPtr + 1) += XQbcx_Vbcx; + *(here->VBICbaseBICollCXPtr + 1) += -XQbcx_Vbcx; + *(here->VBICcollCXBaseBIPtr + 1) += -XQbcx_Vbcx; + *(here->VBICcollCXCollCXPtr + 1) += XQbcx_Vbcx; +/* +c Stamp element: Qbep +*/ + *(here->VBICbaseBXBaseBXPtr + 1) += XQbep_Vbep; + *(here->VBICbaseBXBaseBPPtr + 1) += -XQbep_Vbep; + *(here->VBICbaseBXBaseBIPtr + 1) += XQbep_Vbci; + *(here->VBICbaseBXCollCIPtr + 1) += -XQbep_Vbci; + *(here->VBICbaseBPBaseBXPtr + 1) += -XQbep_Vbep; + *(here->VBICbaseBPBaseBPPtr + 1) += XQbep_Vbep; + *(here->VBICbaseBPBaseBIPtr + 1) += -XQbep_Vbci; + *(here->VBICbaseBPCollCIPtr + 1) += XQbep_Vbci; + + } + } + return(OK); +} diff --git a/src/spicelib/devices/vbic/vbicask.c b/src/spicelib/devices/vbic/vbicask.c new file mode 100644 index 000000000..5aca1fbb9 --- /dev/null +++ b/src/spicelib/devices/vbic/vbicask.c @@ -0,0 +1,198 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Mathew Lew and Thomas L. Quarles +Model Author: 1995 Colin McAndrew Motorola +Spice3 Implementation: 2003 Dietmar Warning DAnalyse GmbH +**********/ + +/* + * This routine gives access to the internal device + * parameters for VBICs + */ + +#include "ngspice.h" +#include "const.h" +#include "cktdefs.h" +#include "vbicdefs.h" +#include "ifsim.h" +#include "sperror.h" +#include "suffix.h" + +/*ARGSUSED*/ +int +VBICask(CKTcircuit *ckt, GENinstance *instPtr, int which, IFvalue *value, IFvalue *select) +{ + VBICinstance *here = (VBICinstance*)instPtr; + int itmp; + double vr; + double vi; + double sr; + double si; + double vm; + static char *msg = "Current and power not available for ac analysis"; + switch(which) { + case VBIC_AREA: + value->rValue = here->VBICarea; + return(OK); + case VBIC_OFF: + value->iValue = here->VBICoff; + return(OK); + case VBIC_IC_VBE: + value->rValue = here->VBICicVBE; + return(OK); + case VBIC_IC_VCE: + value->rValue = here->VBICicVCE; + return(OK); + case VBIC_TEMP: + value->rValue = here->VBICtemp - CONSTCtoK; + return(OK); + case VBIC_M: + value->rValue = here->VBICm; + return(OK); + case VBIC_QUEST_COLLNODE: + value->iValue = here->VBICcollNode; + return(OK); + case VBIC_QUEST_BASENODE: + value->iValue = here->VBICbaseNode; + return(OK); + case VBIC_QUEST_EMITNODE: + value->iValue = here->VBICemitNode; + return(OK); + case VBIC_QUEST_COLLCXNODE: + value->iValue = here->VBICcollCXNode; + return(OK); + case VBIC_QUEST_BASEBXNODE: + value->iValue = here->VBICbaseBXNode; + return(OK); + case VBIC_QUEST_EMITEINODE: + value->iValue = here->VBICemitEINode; + return(OK); + case VBIC_QUEST_VBE: + value->rValue = *(ckt->CKTstate0 + here->VBICvbei); + return(OK); + case VBIC_QUEST_VBC: + value->rValue = *(ckt->CKTstate0 + here->VBICvbci); + return(OK); + case VBIC_QUEST_CC: + value->rValue = *(ckt->CKTstate0 + here->VBICitzf) - + *(ckt->CKTstate0 + here->VBICitzr) - + *(ckt->CKTstate0 + here->VBICibc); + return(OK); + case VBIC_QUEST_CB: + value->rValue = *(ckt->CKTstate0 + here->VBICibe) + + *(ckt->CKTstate0 + here->VBICibc) + + *(ckt->CKTstate0 + here->VBICibep) + + *(ckt->CKTstate0 + here->VBICibex); + return(OK); + case VBIC_QUEST_CE: + value->rValue = - *(ckt->CKTstate0 + here->VBICibe) - + *(ckt->CKTstate0 + here->VBICibex) - + *(ckt->CKTstate0 + here->VBICitzf) + + *(ckt->CKTstate0 + here->VBICitzr); + return(OK); + case VBIC_QUEST_POWER: + value->rValue = fabs(*(ckt->CKTstate0 + here->VBICitzf) - *(ckt->CKTstate0 + here->VBICitzr)) + * fabs(*(ckt->CKTstate0 + here->VBICvbei) - *(ckt->CKTstate0 + here->VBICvbci)) + + fabs(*(ckt->CKTstate0 + here->VBICibe) * *(ckt->CKTstate0 + here->VBICvbei)) + + fabs(*(ckt->CKTstate0 + here->VBICibex) * *(ckt->CKTstate0 + here->VBICvbex)) + + fabs(*(ckt->CKTstate0 + here->VBICibc) * *(ckt->CKTstate0 + here->VBICvbci)); + return(OK); + case VBIC_QUEST_GM: + value->rValue = *(ckt->CKTstate0 + here->VBICitzf_Vbei); + return(OK); + case VBIC_QUEST_GO: + value->rValue = *(ckt->CKTstate0 + here->VBICitzf_Vbci); + return(OK); + case VBIC_QUEST_GPI: + value->rValue = *(ckt->CKTstate0 + here->VBICibe_Vbei); + return(OK); + case VBIC_QUEST_GMU: + value->rValue = *(ckt->CKTstate0 + here->VBICibc_Vbci); + return(OK); + case VBIC_QUEST_GX: + value->rValue = *(ckt->CKTstate0 + here->VBICirbi_Vrbi); + return(OK); + case VBIC_QUEST_CBE: + value->rValue = here->VBICcapbe; + return(OK); + case VBIC_QUEST_CBEX: + value->rValue = here->VBICcapbex; + return(OK); + case VBIC_QUEST_CBC: + value->rValue = here->VBICcapbc; + return(OK); + case VBIC_QUEST_CBCX: + value->rValue = here->VBICcapbcx; + return(OK); + case VBIC_QUEST_QBE: + value->rValue = *(ckt->CKTstate0 + here->VBICqbe); + return(OK); + case VBIC_QUEST_QBC: + value->rValue = *(ckt->CKTstate0 + here->VBICqbc); + return(OK); + case VBIC_QUEST_SENS_DC: + if(ckt->CKTsenInfo){ + value->rValue = *(ckt->CKTsenInfo->SEN_Sap[select->iValue + 1]+ + here->VBICsenParmNo); + } + return(OK); + case VBIC_QUEST_SENS_REAL: + if(ckt->CKTsenInfo){ + value->rValue = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ + here->VBICsenParmNo); + } + return(OK); + case VBIC_QUEST_SENS_IMAG: + if(ckt->CKTsenInfo){ + value->rValue = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ + here->VBICsenParmNo); + } + return(OK); + case VBIC_QUEST_SENS_MAG: + if(ckt->CKTsenInfo){ + vr = *(ckt->CKTrhsOld + select->iValue + 1); + vi = *(ckt->CKTirhsOld + select->iValue + 1); + vm = sqrt(vr*vr + vi*vi); + if(vm == 0){ + value->rValue = 0; + return(OK); + } + sr = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ + here->VBICsenParmNo); + si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ + here->VBICsenParmNo); + value->rValue = (vr * sr + vi * si)/vm; + } + return(OK); + case VBIC_QUEST_SENS_PH: + if(ckt->CKTsenInfo){ + vr = *(ckt->CKTrhsOld + select->iValue + 1); + vi = *(ckt->CKTirhsOld + select->iValue + 1); + vm = vr*vr + vi*vi; + if(vm == 0){ + value->rValue = 0; + return(OK); + } + sr = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ + here->VBICsenParmNo); + si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ + here->VBICsenParmNo); + + value->rValue = (vr * si - vi * sr)/vm; + } + return(OK); + case VBIC_QUEST_SENS_CPLX: + if(ckt->CKTsenInfo){ + itmp = select->iValue + 1; + value->cValue.real= *(ckt->CKTsenInfo->SEN_RHS[itmp]+ + here->VBICsenParmNo); + value->cValue.imag= *(ckt->CKTsenInfo->SEN_iRHS[itmp]+ + here->VBICsenParmNo); + } + return(OK); + default: + return(E_BADPARM); + } + /* NOTREACHED */ +} + diff --git a/src/spicelib/devices/vbic/vbicconv.c b/src/spicelib/devices/vbic/vbicconv.c new file mode 100644 index 000000000..c10c4687a --- /dev/null +++ b/src/spicelib/devices/vbic/vbicconv.c @@ -0,0 +1,177 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1995 Colin McAndrew Motorola +Spice3 Implementation: 2003 Dietmar Warning DAnalyse GmbH +**********/ + +/* + * This routine performs the device convergence test for + * VBICs in the circuit. + */ + +#include "ngspice.h" +#include "cktdefs.h" +#include "vbicdefs.h" +#include "sperror.h" +#include "suffix.h" + +int +VBICconvTest(GENmodel *inModel, CKTcircuit *ckt) +{ + VBICinstance *here; + VBICmodel *model = (VBICmodel *) inModel; + double tol; + double delvbei; + double delvbex; + double delvbci; + double delvbcx; + double delvbep; + double delvrci; + double delvrbi; + double delvrbp; + double ibehat; + double ibexhat; + double itzfhat; + double itzrhat; + double ibchat; + double ibephat; + double ircihat; + double irbihat; + double irbphat; + double Vbei, Vbex, Vbci, Vbcx, Vbep, Vrci, Vrbi, Vrbp; + double Ibe, Ibex, Itzf, Itzr, Ibc, Ibep, Irci, Irbi, Irbp; + + for( ; model != NULL; model = model->VBICnextModel) { + for(here=model->VBICinstances;here!=NULL; + here = here->VBICnextInstance) { + if (here->VBICowner != ARCHme) continue; + + Vbei=model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseBINode)- + *(ckt->CKTrhsOld+here->VBICemitEINode)); + Vbex=model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseBXNode)- + *(ckt->CKTrhsOld+here->VBICemitEINode)); + Vbci =model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseBINode)- + *(ckt->CKTrhsOld+here->VBICcollCINode)); + Vbcx =model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseBINode)- + *(ckt->CKTrhsOld+here->VBICcollCXNode)); + Vbep =model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseBXNode)- + *(ckt->CKTrhsOld+here->VBICbaseBPNode)); + Vrci =model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICcollCXNode)- + *(ckt->CKTrhsOld+here->VBICcollCINode)); + Vrbi =model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseBXNode)- + *(ckt->CKTrhsOld+here->VBICbaseBINode)); + Vrbp =model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseBPNode)- + *(ckt->CKTrhsOld+here->VBICcollCXNode)); + delvbei = Vbei - *(ckt->CKTstate0 + here->VBICvbei); + delvbex = Vbex - *(ckt->CKTstate0 + here->VBICvbex); + delvbci = Vbci - *(ckt->CKTstate0 + here->VBICvbci); + delvbcx = Vbcx - *(ckt->CKTstate0 + here->VBICvbcx); + delvbep = Vbep - *(ckt->CKTstate0 + here->VBICvbep); + delvrci = Vrci - *(ckt->CKTstate0 + here->VBICvrci); + delvrbi = Vrbi - *(ckt->CKTstate0 + here->VBICvrbi); + delvrbp = Vrbp - *(ckt->CKTstate0 + here->VBICvrbp); + ibehat = *(ckt->CKTstate0 + here->VBICibe) + + *(ckt->CKTstate0 + here->VBICibe_Vbei)*delvbei; + ibexhat = *(ckt->CKTstate0 + here->VBICibex) + + *(ckt->CKTstate0 + here->VBICibex_Vbex)*delvbex; + itzfhat = *(ckt->CKTstate0 + here->VBICitzf) + + *(ckt->CKTstate0 + here->VBICitzf_Vbei)*delvbei + *(ckt->CKTstate0 + here->VBICitzf_Vbci)*delvbci; + itzrhat = *(ckt->CKTstate0 + here->VBICitzr) + + *(ckt->CKTstate0 + here->VBICitzr_Vbei)*delvbei + *(ckt->CKTstate0 + here->VBICitzr_Vbci)*delvbci; + ibchat = *(ckt->CKTstate0 + here->VBICibc) + + *(ckt->CKTstate0 + here->VBICibc_Vbei)*delvbei + *(ckt->CKTstate0 + here->VBICibc_Vbci)*delvbci; + ibephat = *(ckt->CKTstate0 + here->VBICibep) + + *(ckt->CKTstate0 + here->VBICibep_Vbep)*delvbep; + ircihat = *(ckt->CKTstate0 + here->VBICirci) + *(ckt->CKTstate0 + here->VBICirci_Vrci)*delvrci + + *(ckt->CKTstate0 + here->VBICirci_Vbcx)*delvbcx + *(ckt->CKTstate0 + here->VBICirci_Vbci)*delvbci; + irbihat = *(ckt->CKTstate0 + here->VBICirbi) + *(ckt->CKTstate0 + here->VBICirbi_Vrbi)*delvrbi + + *(ckt->CKTstate0 + here->VBICirbi_Vbei)*delvbei + *(ckt->CKTstate0 + here->VBICirbi_Vbci)*delvbci; + irbphat = *(ckt->CKTstate0 + here->VBICirbp) + *(ckt->CKTstate0 + here->VBICirbp_Vrbp)*delvrbp + + *(ckt->CKTstate0 + here->VBICirbp_Vbep)*delvbep + *(ckt->CKTstate0 + here->VBICirbp_Vbci)*delvbci; + Ibe = *(ckt->CKTstate0 + here->VBICibe); + Ibex = *(ckt->CKTstate0 + here->VBICibex); + Itzf = *(ckt->CKTstate0 + here->VBICitzf); + Itzr = *(ckt->CKTstate0 + here->VBICitzr); + Ibc = *(ckt->CKTstate0 + here->VBICibc); + Ibep = *(ckt->CKTstate0 + here->VBICibep); + Irci = *(ckt->CKTstate0 + here->VBICirci); + Irbi = *(ckt->CKTstate0 + here->VBICirbi); + Irbp = *(ckt->CKTstate0 + here->VBICirbp); + /* + * check convergence + */ + tol=ckt->CKTreltol*MAX(fabs(ibehat),fabs(Ibe))+ckt->CKTabstol; + if (fabs(ibehat-Ibe) > tol) { + ckt->CKTnoncon++; + ckt->CKTtroubleElt = (GENinstance *) here; + return(OK); /* no reason to continue - we've failed... */ + } else { + tol=ckt->CKTreltol*MAX(fabs(ibexhat),fabs(Ibex))+ckt->CKTabstol; + if (fabs(ibexhat-Ibex) > tol) { + ckt->CKTnoncon++; + ckt->CKTtroubleElt = (GENinstance *) here; + return(OK); /* no reason to continue - we've failed... */ + } else { + tol=ckt->CKTreltol*MAX(fabs(itzfhat),fabs(Itzf))+ckt->CKTabstol; + if (fabs(itzfhat-Itzf) > tol) { + ckt->CKTnoncon++; + ckt->CKTtroubleElt = (GENinstance *) here; + return(OK); /* no reason to continue - we've failed... */ + } else { + tol=ckt->CKTreltol*MAX(fabs(itzrhat),fabs(Itzr))+ckt->CKTabstol; + if (fabs(itzrhat-Itzr) > tol) { + ckt->CKTnoncon++; + ckt->CKTtroubleElt = (GENinstance *) here; + return(OK); /* no reason to continue - we've failed... */ + } else { + tol=ckt->CKTreltol*MAX(fabs(ibchat),fabs(Ibc))+ckt->CKTabstol; + if (fabs(ibchat-Ibc) > tol) { + ckt->CKTnoncon++; + ckt->CKTtroubleElt = (GENinstance *) here; + return(OK); /* no reason to continue - we've failed... */ + } else { + tol=ckt->CKTreltol*MAX(fabs(ibephat),fabs(Ibep))+ckt->CKTabstol; + if (fabs(ibephat-Ibep) > tol) { + ckt->CKTnoncon++; + ckt->CKTtroubleElt = (GENinstance *) here; + return(OK); /* no reason to continue - we've failed... */ + } else { + tol=ckt->CKTreltol*MAX(fabs(ircihat),fabs(Irci))+ckt->CKTabstol; + if (fabs(ircihat-Irci) > tol) { + ckt->CKTnoncon++; + ckt->CKTtroubleElt = (GENinstance *) here; + return(OK); /* no reason to continue - we've failed... */ + } else { + tol=ckt->CKTreltol*MAX(fabs(irbihat),fabs(Irbi))+ckt->CKTabstol; + if (fabs(irbihat-Irbi) > tol) { + ckt->CKTnoncon++; + ckt->CKTtroubleElt = (GENinstance *) here; + return(OK); /* no reason to continue - we've failed... */ + } else { + tol=ckt->CKTreltol*MAX(fabs(irbphat),fabs(Irbp))+ckt->CKTabstol; + if (fabs(irbphat-Irbp) > tol) { + ckt->CKTnoncon++; + ckt->CKTtroubleElt = (GENinstance *) here; + return(OK); /* no reason to continue - we've failed... */ + } + } + } + } + } + } + } + } + } + } + } + return(OK); +} diff --git a/src/spicelib/devices/vbic/vbicdefs.h b/src/spicelib/devices/vbic/vbicdefs.h new file mode 100644 index 000000000..144e5d98a --- /dev/null +++ b/src/spicelib/devices/vbic/vbicdefs.h @@ -0,0 +1,725 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1995 Colin McAndrew Motorola +Spice3 Implementation: 2003 Dietmar Warning DAnalyse GmbH +**********/ + +#ifndef VBIC +#define VBIC + +#include "cktdefs.h" +#include "ifsim.h" +#include "gendefs.h" +#include "complex.h" +#include "noisedef.h" + +/* structures to describe Bipolar Junction Transistors */ + +/* data needed to describe a single instance */ + +typedef struct sVBICinstance { + struct sVBICmodel *VBICmodPtr; /* backpointer to model */ + struct sVBICinstance *VBICnextInstance; /* pointer to next instance of + current model*/ + IFuid VBICname; /* pointer to character string naming this instance */ + int VBICowner; /* number of owner process */ + int VBICstate; /* pointer to start of state vector for vbic */ + + int VBICcollNode; /* number of collector node of vbic */ + int VBICbaseNode; /* number of base node of vbic */ + int VBICemitNode; /* number of emitter node of vbic */ + int VBICcollCXNode; /* number of internal collector node of vbic */ + int VBICcollCINode; /* number of internal collector node of vbic */ + int VBICbaseBXNode; /* number of internal base node of vbic */ + int VBICbaseBINode; /* number of internal base node of vbic */ + int VBICemitEINode; /* number of internal emitter node of vbic */ + int VBICbaseBPNode; /* number of internal base node of vbic */ + + double VBICarea; /* area factor for the vbic */ + double VBICicVBE; /* initial condition voltage B-E*/ + double VBICicVCE; /* initial condition voltage C-E*/ + double VBICtemp; /* instance temperature */ + double VBICdtemp; /* instance delta temperature */ + double VBICm; /* multiply factor for the vbic */ + + double VBICtVcrit; + double VBICttnom; /* temperature adjusted model parameters per instance */ + double VBICtextCollResist; + double VBICtintCollResist; + double VBICtepiSatVoltage; + double VBICtepiDoping; + double VBICtextBaseResist; + double VBICtintBaseResist; + double VBICtemitterResist; + double VBICtsubstrateResist; + double VBICtparBaseResist; + double VBICtsatCur; + double VBICtemissionCoeffF; + double VBICtemissionCoeffR; + double VBICtdepletionCapBE; + double VBICtpotentialBE; + double VBICtdepletionCapBC; + double VBICtextCapBC; + double VBICtpotentialBC; + double VBICtextCapSC; + double VBICtpotentialSC; + double VBICtidealSatCurBE; + double VBICtnidealSatCurBE; + double VBICtidealSatCurBC; + double VBICtnidealSatCurBC; + double VBICtavalanchePar2BC; + double VBICtparasitSatCur; + double VBICtidealParasitSatCurBE; + double VBICtnidealParasitSatCurBE; + double VBICtidealParasitSatCurBC; + double VBICtnidealParasitSatCurBC; + double VBICtrollOffF; + double VBICtsepISRR; + double VBICtvbbe; + double VBICtnbbe; + + double *VBICcollCollPtr; /* pointer to sparse matrix at + * (collector,collector) */ + double *VBICbaseBasePtr; /* pointer to sparse matrix at + * (base,base) */ + double *VBICemitEmitPtr; /* pointer to sparse matrix at + * (emitter,emitter) */ + double *VBICcollCXCollCXPtr; /* pointer to sparse matrix at + * (collector prime,collector prime) */ + double *VBICcollCICollCIPtr; /* pointer to sparse matrix at + * (collector prime,collector prime) */ + double *VBICbaseBXBaseBXPtr; /* pointer to sparse matrix at + * (base prime,base prime) */ + double *VBICbaseBIBaseBIPtr; /* pointer to sparse matrix at + * (collector prime,collector prime) */ + double *VBICbaseBPBaseBPPtr; /* pointer to sparse matrix at + * (collector prime,collector prime) */ + double *VBICemitEIEmitEIPtr; /* pointer to sparse matrix at + * (emitter prime,emitter prime) */ + + double *VBICbaseEmitPtr; /* pointer to sparse matrix at + * (base,emit) */ + double *VBICemitBasePtr; /* pointer to sparse matrix at + * (emit,base) */ + double *VBICbaseCollPtr; /* pointer to sparse matrix at + * (base,coll) */ + double *VBICcollBasePtr; /* pointer to sparse matrix at + * (coll,base) */ + double *VBICcollCollCXPtr; /* pointer to sparse matrix at + * (collector,collector prime) */ + double *VBICbaseBaseBXPtr; /* pointer to sparse matrix at + * (base,base prime) */ + double *VBICemitEmitEIPtr; /* pointer to sparse matrix at + * (emitter,emitter prime) */ + double *VBICcollCXCollCIPtr; /* pointer to sparse matrix at + * (collector prime,base prime) */ + double *VBICcollCXBaseBXPtr; /* pointer to sparse matrix at + * (collector prime,collector prime) */ + double *VBICcollCXBaseBIPtr; /* pointer to sparse matrix at + * (collector prime,collector prime) */ + double *VBICcollCXBaseBPPtr; /* pointer to sparse matrix at + * (collector prime,base prime) */ + double *VBICcollCIBaseBIPtr; /* pointer to sparse matrix at + * (collector prime,base) */ + double *VBICcollCIEmitEIPtr; /* pointer to sparse matrix at + * (collector prime,emitter prime) */ + double *VBICbaseBXBaseBIPtr; /* pointer to sparse matrix at + * (base primt,emitter prime) */ + double *VBICbaseBXEmitEIPtr; /* pointer to sparse matrix at + * (base primt,emitter prime) */ + double *VBICbaseBXBaseBPPtr; /* pointer to sparse matrix at + * (base primt,emitter prime) */ + double *VBICbaseBIEmitEIPtr; /* pointer to sparse matrix at + * (base primt,emitter prime) */ + + double *VBICcollCXCollPtr; /* pointer to sparse matrix at + * (collector prime,collector) */ + double *VBICbaseBXBasePtr; /* pointer to sparse matrix at + * (base prime,base ) */ + double *VBICemitEIEmitPtr; /* pointer to sparse matrix at + * (emitter prime,emitter) */ + double *VBICcollCICollCXPtr; /* pointer to sparse matrix at + * (collector prime,base prime) */ + double *VBICbaseBICollCXPtr; /* pointer to sparse matrix at + * (base prime,collector prime) */ + double *VBICbaseBPCollCXPtr; /* pointer to sparse matrix at + * (base primt,emitter prime) */ + double *VBICbaseBXCollCIPtr; /* pointer to sparse matrix at + * (base,collector prime) */ + double *VBICbaseBICollCIPtr; /* pointer to sparse matrix at + * (base,collector prime) */ + double *VBICemitEICollCIPtr; /* pointer to sparse matrix at + * (emitter prime,collector prime) */ + double *VBICbaseBPCollCIPtr; /* pointer to sparse matrix at + * (base primt,emitter prime) */ + double *VBICbaseBIBaseBXPtr; /* pointer to sparse matrix at + * (base primt,emitter prime) */ + double *VBICemitEIBaseBXPtr; /* pointer to sparse matrix at + * (emitter prime,base prime) */ + double *VBICbaseBPBaseBXPtr; /* pointer to sparse matrix at + * (base primt,emitter prime) */ + double *VBICemitEIBaseBIPtr; /* pointer to sparse matrix at + * (emitter prime,base prime) */ + double *VBICbaseBPBaseBIPtr; /* pointer to sparse matrix at + * (base primt,emitter prime) */ + + unsigned VBICareaGiven :1; /* flag to indicate area was specified */ + unsigned VBICoff :1; /* 'off' flag for vbic */ + unsigned VBICicVBEGiven :1; /* flag to indicate VBE init. cond. given */ + unsigned VBICicVCEGiven :1; /* flag to indicate VCE init. cond. given */ + unsigned VBICtempGiven :1; /* temperature given for vbic instance*/ + unsigned VBICdtempGiven :1; /* delta temperature given for vbic instance*/ + unsigned VBICmGiven :1; /* flag to indicate multiplier was specified */ + unsigned VBICsenPertFlag :1; /* indictes whether the the parameter of + the particular instance is to be perturbed */ + + int VBICsenParmNo; /* parameter # for sensitivity use; + set equal to 0 if not a design parameter */ + double VBICcapbe; + double VBICcapbex; + double VBICcapbc; + double VBICcapbcx; + double VBICcapbep; + double *VBICsens; + +#define VBICsenGpi VBICsens /* stores the perturbed values of gpi */ +#define VBICsenGmu VBICsens+5 /* stores the perturbed values of gmu */ +#define VBICsenGm VBICsens+10 /* stores the perturbed values of gm */ +#define VBICsenGo VBICsens+15 /* stores the perturbed values of go */ +#define VBICsenGx VBICsens+20 /* stores the perturbed values of gx */ +#define VBICsenCpi VBICsens+25 /* stores the perturbed values of cpi */ +#define VBICsenCmu VBICsens+30 /* stores the perturbed values of cmu */ +#define VBICsenCbx VBICsens+35 /* stores the perturbed values of cbx */ +#define VBICsenCmcb VBICsens+40 /* stores the perturbed values of cmcb */ +#define VBICsenCsub VBICsens+45 /* stores the perturbed values of csub */ + + +/* indices to array of VBIC noise sources */ + +#define VBICRCNOIZ 0 +#define VBICRCINOIZ 1 +#define VBICRBNOIZ 2 +#define VBICRBINOIZ 3 +#define VBICRENOIZ 4 +#define VBICRBPNOIZ 5 +#define VBICICNOIZ 6 +#define VBICIBNOIZ 7 +#define VBICIBEPNOIZ 8 +#define VBICFLBENOIZ 9 +#define VBICFLBEPNOIZ 10 +#define VBICTOTNOIZ 11 + +#define VBICNSRCS 12 /* the number of VBIC noise sources */ + +#ifndef NONOISE + double VBICnVar[NSTATVARS][VBICNSRCS]; +#else /*NONOISE*/ + double **VBICnVar; +#endif /*NONOISE*/ +/* the above to avoid allocating memory when it is not needed */ + +} VBICinstance ; + +/* entries in the state vector for vbic: */ + +#define VBICvbei VBICstate +#define VBICvbex VBICstate+1 +#define VBICvbci VBICstate+2 +#define VBICvbcx VBICstate+3 +#define VBICvbep VBICstate+4 +#define VBICvrci VBICstate+6 +#define VBICvrbi VBICstate+7 +#define VBICvrbp VBICstate+8 + +#define VBICibe VBICstate+9 +#define VBICibe_Vbei VBICstate+10 + +#define VBICibex VBICstate+11 +#define VBICibex_Vbex VBICstate+12 + +#define VBICitzf VBICstate+13 +#define VBICitzf_Vbei VBICstate+14 +#define VBICitzf_Vbci VBICstate+15 + +#define VBICitzr VBICstate+16 +#define VBICitzr_Vbci VBICstate+17 +#define VBICitzr_Vbei VBICstate+18 + +#define VBICibc VBICstate+19 +#define VBICibc_Vbci VBICstate+20 +#define VBICibc_Vbei VBICstate+21 + +#define VBICibep VBICstate+22 +#define VBICibep_Vbep VBICstate+23 + +#define VBICirci VBICstate+24 +#define VBICirci_Vrci VBICstate+25 +#define VBICirci_Vbci VBICstate+26 +#define VBICirci_Vbcx VBICstate+27 + +#define VBICirbi VBICstate+28 +#define VBICirbi_Vrbi VBICstate+29 +#define VBICirbi_Vbei VBICstate+30 +#define VBICirbi_Vbci VBICstate+31 + +#define VBICirbp VBICstate+32 +#define VBICirbp_Vrbp VBICstate+33 +#define VBICirbp_Vbep VBICstate+34 +#define VBICirbp_Vbci VBICstate+35 + + +#define VBICqbe VBICstate+36 +#define VBICcqbe VBICstate+37 +#define VBICcqbeci VBICstate+38 + +#define VBICqbex VBICstate+39 +#define VBICcqbex VBICstate+40 + +#define VBICqbc VBICstate+41 +#define VBICcqbc VBICstate+42 + +#define VBICqbcx VBICstate+43 +#define VBICcqbcx VBICstate+44 + +#define VBICqbep VBICstate+45 +#define VBICcqbep VBICstate+46 +#define VBICcqbepci VBICstate+47 + +#define VBICqbeo VBICstate+48 +#define VBICcqbeo VBICstate+49 +#define VBICgqbeo VBICstate+50 + +#define VBICqbco VBICstate+51 +#define VBICcqbco VBICstate+52 +#define VBICgqbco VBICstate+53 + +#define VBICnumStates 54 + +#define VBICsensxpbe VBICstate+54 /* charge sensitivities and their + derivatives. +55 for the derivatives - + pointer to the beginning of the array */ +#define VBICsensxpbex VBICstate+56 +#define VBICsensxpbc VBICstate+58 +#define VBICsensxpbcx VBICstate+60 +#define VBICsensxpbep VBICstate+62 + +#define VBICnumSenStates 10 + + +/* per model data */ +typedef struct sVBICmodel { /* model structure for a vbic */ + int VBICmodType; /* type index of this device type */ + struct sVBICmodel *VBICnextModel; /* pointer to next possible model in + linked list */ + VBICinstance * VBICinstances; /* pointer to list of instances that have + this model */ + IFuid VBICmodName; /* pointer to character string naming + this model */ + int VBICtype; + + double VBICtnom; + double VBICextCollResist; + double VBICintCollResist; + double VBICepiSatVoltage; + double VBICepiDoping; + double VBIChighCurFac; + double VBICextBaseResist; + double VBICintBaseResist; + double VBICemitterResist; + double VBICsubstrateResist; + double VBICparBaseResist; + double VBICsatCur; + double VBICemissionCoeffF; + double VBICemissionCoeffR; + double VBICdeplCapLimitF; + double VBICextOverlapCapBE; + double VBICdepletionCapBE; + double VBICpotentialBE; + double VBICjunctionExpBE; + double VBICsmoothCapBE; + double VBICextOverlapCapBC; + double VBICdepletionCapBC; + double VBICepiCharge; + double VBICextCapBC; + double VBICpotentialBC; + double VBICjunctionExpBC; + double VBICsmoothCapBC; + double VBICextCapSC; + double VBICpotentialSC; + double VBICjunctionExpSC; + double VBICsmoothCapSC; + double VBICidealSatCurBE; + double VBICportionIBEI; + double VBICidealEmissCoeffBE; + double VBICnidealSatCurBE; + double VBICnidealEmissCoeffBE; + double VBICidealSatCurBC; + double VBICidealEmissCoeffBC; + double VBICnidealSatCurBC; + double VBICnidealEmissCoeffBC; + double VBICavalanchePar1BC; + double VBICavalanchePar2BC; + double VBICparasitSatCur; + double VBICportionICCP; + double VBICparasitFwdEmissCoeff; + double VBICidealParasitSatCurBE; + double VBICnidealParasitSatCurBE; + double VBICidealParasitSatCurBC; + double VBICidealParasitEmissCoeffBC; + double VBICnidealParasitSatCurBC; + double VBICnidealParasitEmissCoeffBC; + double VBICearlyVoltF; + double VBICearlyVoltR; + double VBICrollOffF; + double VBICrollOffR; + double VBICparRollOff; + double VBICtransitTimeF; + double VBICvarTransitTimeF; + double VBICtransitTimeBiasCoeffF; + double VBICtransitTimeFVBC; + double VBICtransitTimeHighCurrentF; + double VBICtransitTimeR; + double VBICdelayTimeF; + double VBICfNcoef; + double VBICfNexpA; + double VBICfNexpB; + double VBICtempExpRE; + double VBICtempExpRBI; + double VBICtempExpRCI; + double VBICtempExpRS; + double VBICtempExpVO; + double VBICactivEnergyEA; + double VBICactivEnergyEAIE; + double VBICactivEnergyEAIC; + double VBICactivEnergyEAIS; + double VBICactivEnergyEANE; + double VBICactivEnergyEANC; + double VBICactivEnergyEANS; + double VBICtempExpIS; + double VBICtempExpII; + double VBICtempExpIN; + double VBICtempExpNF; + double VBICtempExpAVC; + double VBICthermalResist; + double VBICthermalCapacitance; + double VBICpunchThroughVoltageBC; + double VBICdeplCapCoeff1; + double VBICfixedCapacitanceCS; + double VBICsgpQBselector; + double VBIChighCurrentBetaRolloff; + double VBICtempExpIKF; + double VBICtempExpRCX; + double VBICtempExpRBX; + double VBICtempExpRBP; + double VBICsepISRR; + double VBICtempExpXISR; + double VBICdear; + double VBICeap; + double VBICvbbe; + double VBICnbbe; + double VBICibbe; + double VBICtvbbe1; + double VBICtvbbe2; + double VBICtnbbe; + double VBICebbe; + double VBIClocTempDiff; + double VBICrevVersion; + double VBICrefVersion; + + double VBICcollectorConduct; /* collector conductance */ + double VBICbaseConduct; /* base conductance */ + double VBICemitterConduct; /* emitter conductance */ + + unsigned VBICtnomGiven : 1; + unsigned VBICextCollResistGiven : 1; + unsigned VBICintCollResistGiven : 1; + unsigned VBICepiSatVoltageGiven : 1; + unsigned VBICepiDopingGiven : 1; + unsigned VBIChighCurFacGiven : 1; + unsigned VBICextBaseResistGiven : 1; + unsigned VBICintBaseResistGiven : 1; + unsigned VBICemitterResistGiven : 1; + unsigned VBICsubstrateResistGiven : 1; + unsigned VBICparBaseResistGiven : 1; + unsigned VBICsatCurGiven : 1; + unsigned VBICemissionCoeffFGiven : 1; + unsigned VBICemissionCoeffRGiven : 1; + unsigned VBICdeplCapLimitFGiven : 1; + unsigned VBICextOverlapCapBEGiven : 1; + unsigned VBICdepletionCapBEGiven : 1; + unsigned VBICpotentialBEGiven : 1; + unsigned VBICjunctionExpBEGiven : 1; + unsigned VBICsmoothCapBEGiven : 1; + unsigned VBICextOverlapCapBCGiven : 1; + unsigned VBICdepletionCapBCGiven : 1; + unsigned VBICepiChargeGiven : 1; + unsigned VBICextCapBCGiven : 1; + unsigned VBICpotentialBCGiven : 1; + unsigned VBICjunctionExpBCGiven : 1; + unsigned VBICsmoothCapBCGiven : 1; + unsigned VBICextCapSCGiven : 1; + unsigned VBICpotentialSCGiven : 1; + unsigned VBICjunctionExpSCGiven : 1; + unsigned VBICsmoothCapSCGiven : 1; + unsigned VBICidealSatCurBEGiven : 1; + unsigned VBICportionIBEIGiven : 1; + unsigned VBICidealEmissCoeffBEGiven : 1; + unsigned VBICnidealSatCurBEGiven : 1; + unsigned VBICnidealEmissCoeffBEGiven : 1; + unsigned VBICidealSatCurBCGiven : 1; + unsigned VBICidealEmissCoeffBCGiven : 1; + unsigned VBICnidealSatCurBCGiven : 1; + unsigned VBICnidealEmissCoeffBCGiven : 1; + unsigned VBICavalanchePar1BCGiven : 1; + unsigned VBICavalanchePar2BCGiven : 1; + unsigned VBICparasitSatCurGiven : 1; + unsigned VBICportionICCPGiven : 1; + unsigned VBICparasitFwdEmissCoeffGiven : 1; + unsigned VBICidealParasitSatCurBEGiven : 1; + unsigned VBICnidealParasitSatCurBEGiven : 1; + unsigned VBICidealParasitSatCurBCGiven : 1; + unsigned VBICidealParasitEmissCoeffBCGiven : 1; + unsigned VBICnidealParasitSatCurBCGiven : 1; + unsigned VBICnidealParasitEmissCoeffBCGiven : 1; + unsigned VBICearlyVoltFGiven : 1; + unsigned VBICearlyVoltRGiven : 1; + unsigned VBICrollOffFGiven : 1; + unsigned VBICrollOffRGiven : 1; + unsigned VBICparRollOffGiven : 1; + unsigned VBICtransitTimeFGiven : 1; + unsigned VBICvarTransitTimeFGiven : 1; + unsigned VBICtransitTimeBiasCoeffFGiven : 1; + unsigned VBICtransitTimeFVBCGiven : 1; + unsigned VBICtransitTimeHighCurrentFGiven : 1; + unsigned VBICtransitTimeRGiven : 1; + unsigned VBICdelayTimeFGiven : 1; + unsigned VBICfNcoefGiven : 1; + unsigned VBICfNexpAGiven : 1; + unsigned VBICfNexpBGiven : 1; + unsigned VBICtempExpREGiven : 1; + unsigned VBICtempExpRBIGiven : 1; + unsigned VBICtempExpRCIGiven : 1; + unsigned VBICtempExpRSGiven : 1; + unsigned VBICtempExpVOGiven : 1; + unsigned VBICactivEnergyEAGiven : 1; + unsigned VBICactivEnergyEAIEGiven : 1; + unsigned VBICactivEnergyEAICGiven : 1; + unsigned VBICactivEnergyEAISGiven : 1; + unsigned VBICactivEnergyEANEGiven : 1; + unsigned VBICactivEnergyEANCGiven : 1; + unsigned VBICactivEnergyEANSGiven : 1; + unsigned VBICtempExpISGiven : 1; + unsigned VBICtempExpIIGiven : 1; + unsigned VBICtempExpINGiven : 1; + unsigned VBICtempExpNFGiven : 1; + unsigned VBICtempExpAVCGiven : 1; + unsigned VBICthermalResistGiven : 1; + unsigned VBICthermalCapacitanceGiven : 1; + unsigned VBICpunchThroughVoltageBCGiven : 1; + unsigned VBICdeplCapCoeff1Given : 1; + unsigned VBICfixedCapacitanceCSGiven : 1; + unsigned VBICsgpQBselectorGiven : 1; + unsigned VBIChighCurrentBetaRolloffGiven : 1; + unsigned VBICtempExpIKFGiven : 1; + unsigned VBICtempExpRCXGiven : 1; + unsigned VBICtempExpRBXGiven : 1; + unsigned VBICtempExpRBPGiven : 1; + unsigned VBICsepISRRGiven : 1; + unsigned VBICtempExpXISRGiven : 1; + unsigned VBICdearGiven : 1; + unsigned VBICeapGiven : 1; + unsigned VBICvbbeGiven : 1; + unsigned VBICnbbeGiven : 1; + unsigned VBICibbeGiven : 1; + unsigned VBICtvbbe1Given : 1; + unsigned VBICtvbbe2Given : 1; + unsigned VBICtnbbeGiven : 1; + unsigned VBICebbeGiven : 1; + unsigned VBIClocTempDiffGiven : 1; + unsigned VBICrevVersionGiven : 1; + unsigned VBICrefVersionGiven : 1; +} VBICmodel; + +#ifndef NPN +#define NPN 1 +#define PNP -1 +#endif /*NPN*/ + +/* device parameters */ +#define VBIC_AREA 1 +#define VBIC_OFF 2 +#define VBIC_IC 3 +#define VBIC_IC_VBE 4 +#define VBIC_IC_VCE 5 +#define VBIC_TEMP 6 +#define VBIC_DTEMP 7 +#define VBIC_M 8 + +/* model parameters */ +#define VBIC_MOD_NPN 101 +#define VBIC_MOD_PNP 102 +#define VBIC_MOD_TNOM 103 +#define VBIC_MOD_RCX 104 +#define VBIC_MOD_RCI 105 +#define VBIC_MOD_VO 106 +#define VBIC_MOD_GAMM 107 +#define VBIC_MOD_HRCF 108 +#define VBIC_MOD_RBX 109 +#define VBIC_MOD_RBI 110 +#define VBIC_MOD_RE 111 +#define VBIC_MOD_RS 112 +#define VBIC_MOD_RBP 113 +#define VBIC_MOD_IS 114 +#define VBIC_MOD_NF 115 +#define VBIC_MOD_NR 116 +#define VBIC_MOD_FC 117 +#define VBIC_MOD_CBEO 118 +#define VBIC_MOD_CJE 119 +#define VBIC_MOD_PE 120 +#define VBIC_MOD_ME 121 +#define VBIC_MOD_AJE 122 +#define VBIC_MOD_CBCO 123 +#define VBIC_MOD_CJC 124 +#define VBIC_MOD_QCO 125 +#define VBIC_MOD_CJEP 126 +#define VBIC_MOD_PC 127 +#define VBIC_MOD_MC 128 +#define VBIC_MOD_AJC 129 +#define VBIC_MOD_CJCP 130 +#define VBIC_MOD_PS 131 +#define VBIC_MOD_MS 132 +#define VBIC_MOD_AJS 133 +#define VBIC_MOD_IBEI 134 +#define VBIC_MOD_WBE 135 +#define VBIC_MOD_NEI 136 +#define VBIC_MOD_IBEN 137 +#define VBIC_MOD_NEN 138 +#define VBIC_MOD_IBCI 139 +#define VBIC_MOD_NCI 140 +#define VBIC_MOD_IBCN 141 +#define VBIC_MOD_NCN 142 +#define VBIC_MOD_AVC1 143 +#define VBIC_MOD_AVC2 144 +#define VBIC_MOD_ISP 145 +#define VBIC_MOD_WSP 146 +#define VBIC_MOD_NFP 147 +#define VBIC_MOD_IBEIP 148 +#define VBIC_MOD_IBENP 149 +#define VBIC_MOD_IBCIP 150 +#define VBIC_MOD_NCIP 151 +#define VBIC_MOD_IBCNP 152 +#define VBIC_MOD_NCNP 153 +#define VBIC_MOD_VEF 154 +#define VBIC_MOD_VER 155 +#define VBIC_MOD_IKF 156 +#define VBIC_MOD_IKR 157 +#define VBIC_MOD_IKP 158 +#define VBIC_MOD_TF 159 +#define VBIC_MOD_QTF 160 +#define VBIC_MOD_XTF 161 +#define VBIC_MOD_VTF 162 +#define VBIC_MOD_ITF 163 +#define VBIC_MOD_TR 164 +#define VBIC_MOD_TD 165 +#define VBIC_MOD_KFN 166 +#define VBIC_MOD_AFN 167 +#define VBIC_MOD_BFN 168 +#define VBIC_MOD_XRE 169 +#define VBIC_MOD_XRBI 170 +#define VBIC_MOD_XRCI 171 +#define VBIC_MOD_XRS 172 +#define VBIC_MOD_XVO 173 +#define VBIC_MOD_EA 174 +#define VBIC_MOD_EAIE 175 +#define VBIC_MOD_EAIC 176 +#define VBIC_MOD_EAIS 177 +#define VBIC_MOD_EANE 178 +#define VBIC_MOD_EANC 179 +#define VBIC_MOD_EANS 180 +#define VBIC_MOD_XIS 181 +#define VBIC_MOD_XII 182 +#define VBIC_MOD_XIN 183 +#define VBIC_MOD_TNF 184 +#define VBIC_MOD_TAVC 185 +#define VBIC_MOD_RTH 186 +#define VBIC_MOD_CTH 187 +#define VBIC_MOD_VRT 188 +#define VBIC_MOD_ART 189 +#define VBIC_MOD_CCSO 190 +#define VBIC_MOD_QBM 191 +#define VBIC_MOD_NKF 192 +#define VBIC_MOD_XIKF 193 +#define VBIC_MOD_XRCX 194 +#define VBIC_MOD_XRBX 195 +#define VBIC_MOD_XRBP 196 +#define VBIC_MOD_ISRR 197 +#define VBIC_MOD_XISR 198 +#define VBIC_MOD_DEAR 199 +#define VBIC_MOD_EAP 200 +#define VBIC_MOD_VBBE 201 +#define VBIC_MOD_NBBE 202 +#define VBIC_MOD_IBBE 203 +#define VBIC_MOD_TVBBE1 204 +#define VBIC_MOD_TVBBE2 205 +#define VBIC_MOD_TNBBE 206 +#define VBIC_MOD_EBBE 207 +#define VBIC_MOD_DTEMP 208 +#define VBIC_MOD_VERS 209 +#define VBIC_MOD_VREF 210 + + +/* device questions */ +#define VBIC_QUEST_FT 211 +#define VBIC_QUEST_COLLNODE 212 +#define VBIC_QUEST_BASENODE 213 +#define VBIC_QUEST_EMITNODE 214 +#define VBIC_QUEST_COLLCXNODE 216 +#define VBIC_QUEST_COLLCINODE 217 +#define VBIC_QUEST_BASEBXNODE 218 +#define VBIC_QUEST_BASEBINODE 219 +#define VBIC_QUEST_BASEBPNODE 220 +#define VBIC_QUEST_EMITEINODE 221 +#define VBIC_QUEST_VBE 223 +#define VBIC_QUEST_VBC 224 +#define VBIC_QUEST_CC 225 +#define VBIC_QUEST_CB 226 +#define VBIC_QUEST_CE 227 +#define VBIC_QUEST_GM 228 +#define VBIC_QUEST_GO 229 +#define VBIC_QUEST_GPI 230 +#define VBIC_QUEST_GMU 231 +#define VBIC_QUEST_GX 232 +#define VBIC_QUEST_QBE 233 +#define VBIC_QUEST_CQBE 234 +#define VBIC_QUEST_QBC 235 +#define VBIC_QUEST_CQBC 236 +#define VBIC_QUEST_QSUB 237 +#define VBIC_QUEST_CQSUB 238 +#define VBIC_QUEST_QBX 239 +#define VBIC_QUEST_CQBX 240 +#define VBIC_QUEST_CEXBC 241 +#define VBIC_QUEST_GEQCB 242 +#define VBIC_QUEST_GCSUB 243 +#define VBIC_QUEST_GDSUB 244 +#define VBIC_QUEST_GEQBX 245 +#define VBIC_QUEST_CBE 246 +#define VBIC_QUEST_CBEX 247 +#define VBIC_QUEST_CBC 248 +#define VBIC_QUEST_CBCX 249 +#define VBIC_QUEST_SENS_REAL 250 +#define VBIC_QUEST_SENS_IMAG 251 +#define VBIC_QUEST_SENS_MAG 252 +#define VBIC_QUEST_SENS_PH 253 +#define VBIC_QUEST_SENS_CPLX 254 +#define VBIC_QUEST_SENS_DC 255 +#define VBIC_QUEST_POWER 256 + +/* model questions */ +#define VBIC_MOD_COLLCONDUCT 301 +#define VBIC_MOD_BASECONDUCT 302 +#define VBIC_MOD_EMITTERCONDUCT 303 +#define VBIC_MOD_TYPE 304 + +#include "vbicext.h" +#endif /*VBIC*/ diff --git a/src/spicelib/devices/vbic/vbicdel.c b/src/spicelib/devices/vbic/vbicdel.c new file mode 100644 index 000000000..461d3a7ef --- /dev/null +++ b/src/spicelib/devices/vbic/vbicdel.c @@ -0,0 +1,40 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1995 Colin McAndrew Motorola +Spice3 Implementation: 2003 Dietmar Warning DAnalyse GmbH +**********/ + +/* + * This routine deletes a VBIC instance from the circuit and frees + * the storage it was using. + */ + +#include "ngspice.h" +#include "vbicdefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +VBICdelete(GENmodel *inModel, IFuid name, GENinstance **kill) +{ + VBICmodel *model = (VBICmodel*)inModel; + VBICinstance **fast = (VBICinstance**)kill; + + VBICinstance **prev = NULL; + VBICinstance *here; + + for( ; model ; model = model->VBICnextModel) { + prev = &(model->VBICinstances); + for(here = *prev; here ; here = *prev) { + if(here->VBICname == name || (fast && here==*fast) ) { + *prev= here->VBICnextInstance; + FREE(here); + return(OK); + } + prev = &(here->VBICnextInstance); + } + } + return(E_NODEV); +} diff --git a/src/spicelib/devices/vbic/vbicdest.c b/src/spicelib/devices/vbic/vbicdest.c new file mode 100644 index 000000000..ae8ecfb0a --- /dev/null +++ b/src/spicelib/devices/vbic/vbicdest.c @@ -0,0 +1,46 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1995 Colin McAndrew Motorola +Spice3 Implementation: 2003 Dietmar Warning DAnalyse GmbH +**********/ + +/* + * This routine deletes all VBICs from the circuit and frees + * all storage they were using. + */ + +#include "ngspice.h" +#include "vbicdefs.h" +#include "suffix.h" + + +void +VBICdestroy(GENmodel **inModel) +{ + + VBICmodel **model = (VBICmodel**)inModel; + VBICinstance *here; + VBICinstance *prev = NULL; + VBICmodel *mod = *model; + VBICmodel *oldmod = NULL; + + for( ; mod ; mod = mod->VBICnextModel) { + if(oldmod) FREE(oldmod); + oldmod = mod; + prev = (VBICinstance *)NULL; + for(here = mod->VBICinstances ; here ; here = here->VBICnextInstance) { + if(prev){ + if(prev->VBICsens) FREE(prev->VBICsens); + FREE(prev); + } + prev = here; + } + if(prev){ + if(prev->VBICsens) FREE(prev->VBICsens); + FREE(prev); + } + } + if(oldmod) FREE(oldmod); + *model = NULL; +} diff --git a/src/spicelib/devices/vbic/vbicext.h b/src/spicelib/devices/vbic/vbicext.h new file mode 100644 index 000000000..96e0d11bc --- /dev/null +++ b/src/spicelib/devices/vbic/vbicext.h @@ -0,0 +1,29 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1995 Colin McAndrew Motorola +Spice3 Implementation: 2003 Dietmar Warning DAnalyse GmbH +**********/ +#ifndef __VBICEXT_H +#define __VBICEXT_H + + +extern int VBICacLoad(GENmodel *,CKTcircuit*); +extern int VBICask(CKTcircuit *,GENinstance*,int,IFvalue*,IFvalue*); +extern int VBICconvTest(GENmodel*,CKTcircuit*); +extern int VBICdelete(GENmodel*,IFuid,GENinstance**); +extern void VBICdestroy(GENmodel**); +extern int VBICgetic(GENmodel*,CKTcircuit*); +extern int VBICload(GENmodel*,CKTcircuit*); +extern int VBICmAsk(CKTcircuit*,GENmodel*,int,IFvalue*); +extern int VBICmDelete(GENmodel**,IFuid,GENmodel*); +extern int VBICmParam(int,IFvalue*,GENmodel*); +extern int VBICparam(int,IFvalue*,GENinstance*,IFvalue*); +extern int VBICpzLoad(GENmodel*, CKTcircuit*, SPcomplex*); +extern int VBICsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); +extern int VBICunsetup(GENmodel*,CKTcircuit*); +extern int VBICtemp(GENmodel*,CKTcircuit*); +extern int VBICtrunc(GENmodel*,CKTcircuit*,double*); +extern int VBICnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); + +#endif diff --git a/src/spicelib/devices/vbic/vbicgetic.c b/src/spicelib/devices/vbic/vbicgetic.c new file mode 100644 index 000000000..2c1cb28cb --- /dev/null +++ b/src/spicelib/devices/vbic/vbicgetic.c @@ -0,0 +1,49 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1995 Colin McAndrew Motorola +Spice3 Implementation: 2003 Dietmar Warning DAnalyse GmbH +**********/ + +/* + * This routine gets the device initial conditions for the VBICs + * from the RHS vector + */ + +#include "ngspice.h" +#include "cktdefs.h" +#include "vbicdefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +VBICgetic(GENmodel *inModel, CKTcircuit *ckt) +{ + + VBICmodel *model = (VBICmodel*)inModel; + VBICinstance *here; + /* + * grab initial conditions out of rhs array. User specified, so use + * external nodes to get values + */ + + for( ; model ; model = model->VBICnextModel) { + for(here = model->VBICinstances; here ; here = here->VBICnextInstance) { + + if (here->VBICowner != ARCHme) continue; + + if(!here->VBICicVBEGiven) { + here->VBICicVBE = + *(ckt->CKTrhs + here->VBICbaseNode) - + *(ckt->CKTrhs + here->VBICemitNode); + } + if(!here->VBICicVCEGiven) { + here->VBICicVCE = + *(ckt->CKTrhs + here->VBICcollNode) - + *(ckt->CKTrhs + here->VBICemitNode); + } + } + } + return(OK); +} diff --git a/src/spicelib/devices/vbic/vbicinit.c b/src/spicelib/devices/vbic/vbicinit.c new file mode 100644 index 000000000..11401a19c --- /dev/null +++ b/src/spicelib/devices/vbic/vbicinit.c @@ -0,0 +1,81 @@ +#include "config.h" + +#include "devdefs.h" + +#include "vbicitf.h" +#include "vbicext.h" +#include "vbicinit.h" + + +SPICEdev VBICinfo = { + { + "VBIC", + "Vertical Bipolar Inter-Company Model (3-terminal)", + + &VBICnSize, + &VBICnSize, + VBICnames, + + &VBICpTSize, + VBICpTable, + + &VBICmPTSize, + VBICmPTable, + +#ifdef XSPICE +/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ + + 0, /* This is a SPICE device, it has no MIF info data */ + NULL, /* This is a SPICE device, it has no MIF info data */ +/*--------------------------- End of SDB fix -------------------------*/ +#endif + + DEV_DEFAULT + }, + + VBICparam, /* DEVparam */ + VBICmParam, /* DEVmodParam */ + VBICload, /* DEVload */ + VBICsetup, /* DEVsetup */ + VBICunsetup, /* DEVunsetup */ + VBICsetup, /* DEVpzSetup */ + VBICtemp, /* DEVtemperature */ + VBICtrunc, /* DEVtrunc */ + NULL, /* DEVfindBranch */ + VBICacLoad, /* DEVacLoad */ + NULL, /* DEVaccept */ + VBICdestroy, /* DEVdestroy */ + VBICmDelete, /* DEVmodDelete */ + VBICdelete, /* DEVdelete */ + VBICgetic, /* DEVsetic */ + VBICask, /* DEVask */ + VBICmAsk, /* DEVmodAsk */ + VBICpzLoad, /* DEVpzLoad */ + VBICconvTest, /* DEVconvTest */ + NULL, /* DEVsenSetup */ + NULL, /* DEVsenLoad */ + NULL, /* DEVsenUpdate */ + NULL, /* DEVsenAcLoad */ + NULL, /* DEVsenPrint */ + NULL, /* DEVsenTrunc */ + NULL, /* DEVdisto */ + VBICnoise, /* DEVnoise */ + + &VBICiSize, /* DEVinstSize */ + &VBICmSize /* DEVmodSize */ + +}; + + +SPICEdev * +get_vbic_info(void) +{ + return &VBICinfo; +} diff --git a/src/spicelib/devices/vbic/vbicinit.h b/src/spicelib/devices/vbic/vbicinit.h new file mode 100644 index 000000000..02d412e23 --- /dev/null +++ b/src/spicelib/devices/vbic/vbicinit.h @@ -0,0 +1,13 @@ +#ifndef _VBICINIT_H +#define _VBICINIT_H + +extern IFparm VBICpTable[ ]; +extern IFparm VBICmPTable[ ]; +extern char *VBICnames[ ]; +extern int VBICpTSize; +extern int VBICmPTSize; +extern int VBICnSize; +extern int VBICiSize; +extern int VBICmSize; + +#endif diff --git a/src/spicelib/devices/vbic/vbicitf.h b/src/spicelib/devices/vbic/vbicitf.h new file mode 100644 index 000000000..c088c07a2 --- /dev/null +++ b/src/spicelib/devices/vbic/vbicitf.h @@ -0,0 +1,12 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1995 Colin McAndrew Motorola +Spice3 Implementation: 2003 Dietmar Warning DAnalyse GmbH +**********/ +#ifndef DEV_VBIC +#define DEV_VBIC + +extern SPICEdev *get_vbic_info(void); + +#endif diff --git a/src/spicelib/devices/vbic/vbicload.c b/src/spicelib/devices/vbic/vbicload.c new file mode 100644 index 000000000..6e0a55ede --- /dev/null +++ b/src/spicelib/devices/vbic/vbicload.c @@ -0,0 +1,2134 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1995 Colin McAndrew Motorola +Spice3 Implementation: 2003 Dietmar Warning DAnalyse GmbH +**********/ + +/* + * This is the function called each iteration to evaluate the + * VBICs in the circuit and load them into the matrix as appropriate + */ + +#include "ngspice.h" +#include "cktdefs.h" +#include "vbicdefs.h" +#include "const.h" +#include "trandefs.h" +#include "sperror.h" +#include "devdefs.h" +#include "suffix.h" + +int +VBICload(GENmodel *inModel, CKTcircuit *ckt) + /* actually load the current resistance value into the + * sparse matrix previously provided + */ +{ + VBICmodel *model = (VBICmodel*)inModel; + VBICinstance *here; + double p[108] + ,Vbei,Vbex,Vbci,Vbep,Vrcx,Vbcx + ,Vrci,Vrbx,Vrbi,Vre,Vrbp,Vbe,Vbc + ,Ibe,Ibe_Vbei,Ibex,Ibex_Vbex,Itzf,Itzf_Vbei,Itzf_Vbci + ,Itzr,Itzr_Vbci,Itzr_Vbei,Ibc,Ibc_Vbci,Ibc_Vbei,Ibep + ,Ibep_Vbep,Ircx,Ircx_Vrcx,Irci,Irci_Vrci,Irci_Vbci,Irci_Vbcx + ,Irbx,Irbx_Vrbx,Irbi,Irbi_Vrbi,Irbi_Vbei,Irbi_Vbci,Ire + ,Ire_Vre,Irbp,Irbp_Vrbp,Irbp_Vbep,Irbp_Vbci,Qbe,Qbe_Vbei + ,Qbe_Vbci,Qbex,Qbex_Vbex,Qbc,Qbc_Vbci,Qbcx,Qbcx_Vbcx + ,Qbep,Qbep_Vbep,Qbep_Vbci,Qbeo,Qbeo_Vbe,Qbco,Qbco_Vbc,SCALE; + int iret; + int vbic_3T_it_cf_fj(double * + ,double *,double *,double *,double *,double *,double * + ,double *,double *,double *,double *,double *,double *, double * + ,double *,double *,double *,double *,double *,double *, double * + ,double *,double *,double *,double *,double *,double *, double * + ,double *,double *,double *,double *,double *,double *, double * + ,double *,double *,double *,double *,double *,double *, double * + ,double *,double *,double *,double *,double *,double *, double * + ,double *,double *,double *,double *,double *,double *, double * + ,double *,double *,double *,double *,double *,double *, double *, double *); + double vce, xfact; + double vt; + double delvbei; + double delvbex; + double delvbci; + double delvbcx; + double delvbep; + double delvrci; + double delvrbi; + double delvrbp; + double ibehat; + double ibexhat; + double itzfhat; + double itzrhat; + double ibchat; + double ibephat; + double ircihat; + double irbihat; + double irbphat; + double ceq, geq, rhs_current; + int icheck; + int ichk1, ichk2, ichk3, ichk4; + int error; + int SenCond=0; + double gqbeo, cqbeo, gqbco, cqbco, gbcx, cbcx; + + /* loop through all the models */ + for( ; model != NULL; model = model->VBICnextModel ) { + + /* loop through all the instances of the model */ + for (here = model->VBICinstances; here != NULL ; + here=here->VBICnextInstance) { + + if (here->VBICowner != ARCHme) continue; + + vt = here->VBICtemp * CONSTKoverQ; + + if(ckt->CKTsenInfo){ +#ifdef SENSDEBUG + printf("VBICload\n"); +#endif /* SENSDEBUG */ + if((ckt->CKTsenInfo->SENstatus == PERTURBATION)&& + (here->VBICsenPertFlag == OFF)) continue; + SenCond = here->VBICsenPertFlag; + } + + gbcx = 0.0; + cbcx = 0.0; + gqbeo = 0.0; + cqbeo = 0.0; + gqbco = 0.0; + cqbco = 0.0; + /* + * dc model paramters + */ + p[0] = here->VBICttnom; + p[1] = here->VBICtextCollResist; + p[2] = here->VBICtintCollResist; + p[3] = here->VBICtepiSatVoltage; + p[4] = here->VBICtepiDoping; + p[5] = model->VBIChighCurFac; + p[6] = here->VBICtextBaseResist; + p[7] = here->VBICtintBaseResist; + p[8] = here->VBICtemitterResist; + p[9] = here->VBICtsubstrateResist; + p[10] = here->VBICtparBaseResist; + p[11] = here->VBICtsatCur; + p[12] = here->VBICtemissionCoeffF; + p[13] = here->VBICtemissionCoeffR; + p[14] = model->VBICdeplCapLimitF; + p[15] = model->VBICextOverlapCapBE; + p[16] = here->VBICtdepletionCapBE; + p[17] = here->VBICtpotentialBE; + p[18] = model->VBICjunctionExpBE; + p[19] = model->VBICsmoothCapBE; + p[20] = model->VBICextOverlapCapBC; + p[21] = here->VBICtdepletionCapBC; + p[22] = model->VBICepiCharge; + p[23] = here->VBICtextCapBC; + p[24] = here->VBICtpotentialBC; + p[25] = model->VBICjunctionExpBC; + p[26] = model->VBICsmoothCapBC; + p[27] = here->VBICtextCapSC; + p[28] = here->VBICtpotentialSC; + p[29] = model->VBICjunctionExpSC; + p[30] = model->VBICsmoothCapSC; + p[31] = here->VBICtidealSatCurBE; + p[32] = model->VBICportionIBEI; + p[33] = model->VBICidealEmissCoeffBE; + p[34] = here->VBICtnidealSatCurBE; + p[35] = model->VBICnidealEmissCoeffBE; + p[36] = here->VBICtidealSatCurBC; + p[37] = model->VBICidealEmissCoeffBC; + p[38] = here->VBICtnidealSatCurBC; + p[39] = model->VBICnidealEmissCoeffBC; + p[40] = model->VBICavalanchePar1BC; + p[41] = here->VBICtavalanchePar2BC; + p[42] = here->VBICtparasitSatCur; + p[43] = model->VBICportionICCP; + p[44] = model->VBICparasitFwdEmissCoeff; + p[45] = here->VBICtidealParasitSatCurBE; + p[46] = here->VBICtnidealParasitSatCurBE; + p[47] = here->VBICtidealParasitSatCurBC; + p[48] = model->VBICidealParasitEmissCoeffBC; + p[49] = here->VBICtnidealParasitSatCurBC; + p[50] = model->VBICnidealParasitEmissCoeffBC; + p[51] = model->VBICearlyVoltF; + p[52] = model->VBICearlyVoltR; + p[53] = here->VBICtrollOffF; + p[54] = model->VBICrollOffR; + p[55] = model->VBICparRollOff; + p[56] = model->VBICtransitTimeF; + p[57] = model->VBICvarTransitTimeF; + p[58] = model->VBICtransitTimeBiasCoeffF; + p[59] = model->VBICtransitTimeFVBC; + p[60] = model->VBICtransitTimeHighCurrentF; + p[61] = model->VBICtransitTimeR; + p[62] = model->VBICdelayTimeF; + p[63] = model->VBICfNcoef; + p[64] = model->VBICfNexpA; + p[65] = model->VBICfNexpB; + p[66] = model->VBICtempExpRE; + p[67] = model->VBICtempExpRBI; + p[68] = model->VBICtempExpRCI; + p[69] = model->VBICtempExpRS; + p[70] = model->VBICtempExpVO; + p[71] = model->VBICactivEnergyEA; + p[72] = model->VBICactivEnergyEAIE; + p[73] = model->VBICactivEnergyEAIC; + p[74] = model->VBICactivEnergyEAIS; + p[75] = model->VBICactivEnergyEANE; + p[76] = model->VBICactivEnergyEANC; + p[77] = model->VBICactivEnergyEANS; + p[78] = model->VBICtempExpIS; + p[79] = model->VBICtempExpII; + p[80] = model->VBICtempExpIN; + p[81] = model->VBICtempExpNF; + p[82] = model->VBICtempExpAVC; + p[83] = model->VBICthermalResist; + p[84] = model->VBICthermalCapacitance; + p[85] = model->VBICpunchThroughVoltageBC; + p[86] = model->VBICdeplCapCoeff1; + p[87] = model->VBICfixedCapacitanceCS; + p[88] = model->VBICsgpQBselector; + p[89] = model->VBIChighCurrentBetaRolloff; + p[90] = model->VBICtempExpIKF; + p[91] = model->VBICtempExpRCX; + p[92] = model->VBICtempExpRBX; + p[93] = model->VBICtempExpRBP; + p[94] = here->VBICtsepISRR; + p[95] = model->VBICtempExpXISR; + p[96] = model->VBICdear; + p[97] = model->VBICeap; + p[98] = here->VBICtvbbe; + p[99] = here->VBICtnbbe; + p[100] = model->VBICibbe; + p[101] = model->VBICtvbbe1; + p[102] = model->VBICtvbbe2; + p[103] = model->VBICtnbbe; + p[104] = model->VBICebbe; + p[105] = model->VBIClocTempDiff; + p[106] = model->VBICrevVersion; + p[107] = model->VBICrefVersion; + + SCALE = here->VBICarea * here->VBICm; + + if(SenCond){ +#ifdef SENSDEBUG + printf("VBICsenPertFlag = ON \n"); +#endif /* SENSDEBUG */ + + if((ckt->CKTsenInfo->SENmode == TRANSEN)&& + (ckt->CKTmode & MODEINITTRAN)) { + Vbe = model->VBICtype*( + *(ckt->CKTrhsOp+here->VBICbaseNode)- + *(ckt->CKTrhsOp+here->VBICemitNode)); + Vbc = model->VBICtype*( + *(ckt->CKTrhsOp+here->VBICbaseNode)- + *(ckt->CKTrhsOp+here->VBICcollNode)); + Vbei = *(ckt->CKTstate1 + here->VBICvbei); + Vbex = *(ckt->CKTstate1 + here->VBICvbex); + Vbci = *(ckt->CKTstate1 + here->VBICvbci); + Vbcx = *(ckt->CKTstate1 + here->VBICvbcx); + Vbep = *(ckt->CKTstate1 + here->VBICvbep); + Vrci = *(ckt->CKTstate1 + here->VBICvrci); + Vrbi = *(ckt->CKTstate1 + here->VBICvrbi); + Vrbp = *(ckt->CKTstate1 + here->VBICvrbp); + Vrcx = model->VBICtype*( + *(ckt->CKTrhsOp+here->VBICcollNode)- + *(ckt->CKTrhsOp+here->VBICcollCXNode)); + Vrbx = model->VBICtype*( + *(ckt->CKTrhsOp+here->VBICbaseNode)- + *(ckt->CKTrhsOp+here->VBICbaseBXNode)); + Vre = model->VBICtype*( + *(ckt->CKTrhsOp+here->VBICemitNode)- + *(ckt->CKTrhsOp+here->VBICemitEINode)); + } + else{ + Vbei = *(ckt->CKTstate0 + here->VBICvbei); + Vbex = *(ckt->CKTstate0 + here->VBICvbex); + Vbci = *(ckt->CKTstate0 + here->VBICvbci); + Vbcx = *(ckt->CKTstate0 + here->VBICvbcx); + Vbep = *(ckt->CKTstate0 + here->VBICvbep); + Vrci = *(ckt->CKTstate0 + here->VBICvrci); + Vrbi = *(ckt->CKTstate0 + here->VBICvrbi); + Vrbp = *(ckt->CKTstate0 + here->VBICvrbp); + if((ckt->CKTsenInfo->SENmode == DCSEN)|| + (ckt->CKTsenInfo->SENmode == TRANSEN)){ + Vbe = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseNode)- + *(ckt->CKTrhsOld+here->VBICemitNode)); + Vbc = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseNode)- + *(ckt->CKTrhsOld+here->VBICcollNode)); + Vrcx = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICcollNode)- + *(ckt->CKTrhsOld+here->VBICcollCXNode)); + Vrbx = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseNode)- + *(ckt->CKTrhsOld+here->VBICbaseBXNode)); + Vre = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICemitNode)- + *(ckt->CKTrhsOld+here->VBICemitEINode)); + } + if(ckt->CKTsenInfo->SENmode == ACSEN){ + Vbe = model->VBICtype*( + *(ckt->CKTrhsOp+here->VBICbaseNode)- + *(ckt->CKTrhsOp+here->VBICemitNode)); + Vbc = model->VBICtype*( + *(ckt->CKTrhsOp+here->VBICbaseNode)- + *(ckt->CKTrhsOp+here->VBICcollNode)); + Vrcx = model->VBICtype*( + *(ckt->CKTrhsOp+here->VBICcollNode)- + *(ckt->CKTrhsOp+here->VBICcollCXNode)); + Vrbx = model->VBICtype*( + *(ckt->CKTrhsOp+here->VBICbaseNode)- + *(ckt->CKTrhsOp+here->VBICbaseBXNode)); + Vre = model->VBICtype*( + *(ckt->CKTrhsOp+here->VBICemitNode)- + *(ckt->CKTrhsOp+here->VBICemitEINode)); + } + } + goto next1; + } + + /* + * initialization + */ + icheck=1; + if(ckt->CKTmode & MODEINITSMSIG) { + Vbe = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseNode)- + *(ckt->CKTrhsOld+here->VBICemitNode)); + Vbc = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseNode)- + *(ckt->CKTrhsOld+here->VBICcollNode)); + Vbei = *(ckt->CKTstate0 + here->VBICvbei); + Vbex = *(ckt->CKTstate0 + here->VBICvbex); + Vbci = *(ckt->CKTstate0 + here->VBICvbci); + Vbcx = *(ckt->CKTstate0 + here->VBICvbcx); + Vbep = *(ckt->CKTstate0 + here->VBICvbep); + Vrci = *(ckt->CKTstate0 + here->VBICvrci); + Vrbi = *(ckt->CKTstate0 + here->VBICvrbi); + Vrbp = *(ckt->CKTstate0 + here->VBICvrbp); + Vrcx = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICcollNode)- + *(ckt->CKTrhsOld+here->VBICcollCXNode)); + Vrbx = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseNode)- + *(ckt->CKTrhsOld+here->VBICbaseBXNode)); + Vre = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICemitNode)- + *(ckt->CKTrhsOld+here->VBICemitEINode)); + } else if(ckt->CKTmode & MODEINITTRAN) { + Vbe = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseNode)- + *(ckt->CKTrhsOld+here->VBICemitNode)); + Vbc = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseNode)- + *(ckt->CKTrhsOld+here->VBICcollNode)); + Vbei = *(ckt->CKTstate1 + here->VBICvbei); + Vbex = *(ckt->CKTstate1 + here->VBICvbex); + Vbci = *(ckt->CKTstate1 + here->VBICvbci); + Vbcx = *(ckt->CKTstate1 + here->VBICvbcx); + Vbep = *(ckt->CKTstate1 + here->VBICvbep); + Vrci = *(ckt->CKTstate1 + here->VBICvrci); + Vrbi = *(ckt->CKTstate1 + here->VBICvrbi); + Vrbp = *(ckt->CKTstate1 + here->VBICvrbp); + Vrcx = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICcollNode)- + *(ckt->CKTrhsOld+here->VBICcollCXNode)); + Vrbx = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseNode)- + *(ckt->CKTrhsOld+here->VBICbaseBXNode)); + Vre = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICemitNode)- + *(ckt->CKTrhsOld+here->VBICemitEINode)); + if( (ckt->CKTmode & MODETRAN) && (ckt->CKTmode & MODEUIC) ) { + Vbc = model->VBICtype * (here->VBICicVBE-here->VBICicVCE); + } + } else if((ckt->CKTmode & MODEINITJCT) && + (ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)){ + Vbe=model->VBICtype*here->VBICicVBE; + Vbei=Vbex=Vbe; + vce=model->VBICtype*here->VBICicVCE; + Vbc=Vbe-vce; + Vbci=Vbcx=Vbc; + Vbep=0.0; + Vrci=Vrbi=Vrbp=0.0; + Vrcx=Vrbx=Vre=0.0; + } else if((ckt->CKTmode & MODEINITJCT) && (here->VBICoff==0)) { + Vbe=Vbei=Vbex=model->VBICtype*here->VBICtVcrit; + Vbc=Vbci=Vbcx=Vbep=0.0; + Vrci=Vrbi=Vrbp=0.0; + Vrcx=Vrbx=Vre=0.0; + } else if((ckt->CKTmode & MODEINITJCT) || + ( (ckt->CKTmode & MODEINITFIX) && (here->VBICoff!=0))) { + Vbe=0.0; + Vbei=Vbex=Vbe; + Vbc=0.0; + Vbci=Vbcx=Vbc; + Vbep=0.0; + Vrci=Vrbi=Vrbp=0.0; + Vrcx=Vrbx=Vre=0.0; + } else { +#ifndef PREDICTOR + if(ckt->CKTmode & MODEINITPRED) { + xfact = ckt->CKTdelta/ckt->CKTdeltaOld[1]; + Vbei = (1+xfact) * *(ckt->CKTstate1 + here->VBICvbei)- + xfact * *(ckt->CKTstate2 + here->VBICvbei); + Vbex = (1+xfact) * *(ckt->CKTstate1 + here->VBICvbex)- + xfact * *(ckt->CKTstate2 + here->VBICvbex); + Vbci = (1+xfact) * *(ckt->CKTstate1 + here->VBICvbci)- + xfact * *(ckt->CKTstate2 + here->VBICvbci); + Vbcx = (1+xfact) * *(ckt->CKTstate1 + here->VBICvbcx)- + xfact * *(ckt->CKTstate2 + here->VBICvbcx); + Vbep = (1+xfact) * *(ckt->CKTstate1 + here->VBICvbep)- + xfact * *(ckt->CKTstate2 + here->VBICvbep); + Vrci = (1+xfact) * *(ckt->CKTstate1 + here->VBICvrci)- + xfact * *(ckt->CKTstate2 + here->VBICvrci); + Vrbi = (1+xfact) * *(ckt->CKTstate1 + here->VBICvrbi)- + xfact * *(ckt->CKTstate2 + here->VBICvrbi); + Vrbp = (1+xfact) * *(ckt->CKTstate1 + here->VBICvrbp)- + xfact * *(ckt->CKTstate2 + here->VBICvrbp); + *(ckt->CKTstate0 + here->VBICvbei) = + *(ckt->CKTstate1 + here->VBICvbei); + *(ckt->CKTstate0 + here->VBICvbex) = + *(ckt->CKTstate1 + here->VBICvbex); + *(ckt->CKTstate0 + here->VBICvbci) = + *(ckt->CKTstate1 + here->VBICvbci); + *(ckt->CKTstate0 + here->VBICvbcx) = + *(ckt->CKTstate1 + here->VBICvbcx); + *(ckt->CKTstate0 + here->VBICvbep) = + *(ckt->CKTstate1 + here->VBICvbep); + *(ckt->CKTstate0 + here->VBICvrci) = + *(ckt->CKTstate1 + here->VBICvrci); + *(ckt->CKTstate0 + here->VBICvrbi) = + *(ckt->CKTstate1 + here->VBICvrbi); + *(ckt->CKTstate0 + here->VBICvrbp) = + *(ckt->CKTstate1 + here->VBICvrbp); + *(ckt->CKTstate0 + here->VBICibe) = + *(ckt->CKTstate1 + here->VBICibe); + *(ckt->CKTstate0 + here->VBICibe_Vbei) = + *(ckt->CKTstate1 + here->VBICibe_Vbei); + *(ckt->CKTstate0 + here->VBICibex) = + *(ckt->CKTstate1 + here->VBICibex); + *(ckt->CKTstate0 + here->VBICibex_Vbex) = + *(ckt->CKTstate1 + here->VBICibex_Vbex); + *(ckt->CKTstate0 + here->VBICitzf) = + *(ckt->CKTstate1 + here->VBICitzf); + *(ckt->CKTstate0 + here->VBICitzf_Vbei) = + *(ckt->CKTstate1 + here->VBICitzf_Vbei); + *(ckt->CKTstate0 + here->VBICitzf_Vbci) = + *(ckt->CKTstate1 + here->VBICitzf_Vbci); + *(ckt->CKTstate0 + here->VBICitzr) = + *(ckt->CKTstate1 + here->VBICitzr); + *(ckt->CKTstate0 + here->VBICitzr_Vbei) = + *(ckt->CKTstate1 + here->VBICitzf_Vbei); + *(ckt->CKTstate0 + here->VBICitzr_Vbci) = + *(ckt->CKTstate1 + here->VBICitzr_Vbci); + *(ckt->CKTstate0 + here->VBICibc) = + *(ckt->CKTstate1 + here->VBICibc); + *(ckt->CKTstate0 + here->VBICibc_Vbci) = + *(ckt->CKTstate1 + here->VBICibc_Vbci); + *(ckt->CKTstate0 + here->VBICibc_Vbei) = + *(ckt->CKTstate1 + here->VBICibc_Vbei); + *(ckt->CKTstate0 + here->VBICibep) = + *(ckt->CKTstate1 + here->VBICibep); + *(ckt->CKTstate0 + here->VBICibep_Vbep) = + *(ckt->CKTstate1 + here->VBICibep_Vbep); + *(ckt->CKTstate0 + here->VBICirci) = + *(ckt->CKTstate1 + here->VBICirci); + *(ckt->CKTstate0 + here->VBICirci_Vrci) = + *(ckt->CKTstate1 + here->VBICirci_Vrci); + *(ckt->CKTstate0 + here->VBICirci_Vbci) = + *(ckt->CKTstate1 + here->VBICirci_Vbci); + *(ckt->CKTstate0 + here->VBICirci_Vbcx) = + *(ckt->CKTstate1 + here->VBICirci_Vbcx); + *(ckt->CKTstate0 + here->VBICirbi) = + *(ckt->CKTstate1 + here->VBICirbi); + *(ckt->CKTstate0 + here->VBICirbi_Vrbi) = + *(ckt->CKTstate1 + here->VBICirbi_Vrbi); + *(ckt->CKTstate0 + here->VBICirbi_Vbei) = + *(ckt->CKTstate1 + here->VBICirbi_Vbei); + *(ckt->CKTstate0 + here->VBICirbi_Vbci) = + *(ckt->CKTstate1 + here->VBICirbi_Vbci); + *(ckt->CKTstate0 + here->VBICirbp) = + *(ckt->CKTstate1 + here->VBICirbp); + *(ckt->CKTstate0 + here->VBICirbp_Vrbp) = + *(ckt->CKTstate1 + here->VBICirbp_Vrbp); + *(ckt->CKTstate0 + here->VBICirbp_Vbep) = + *(ckt->CKTstate1 + here->VBICirbp_Vbep); + *(ckt->CKTstate0 + here->VBICirbp_Vbci) = + *(ckt->CKTstate1 + here->VBICirbp_Vbci); + } else { +#endif /* PREDICTOR */ + /* + * compute new nonlinear branch voltages + */ + Vbei = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseBINode)- + *(ckt->CKTrhsOld+here->VBICemitEINode)); + Vbex = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseBXNode)- + *(ckt->CKTrhsOld+here->VBICemitEINode)); + Vbci = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseBINode)- + *(ckt->CKTrhsOld+here->VBICcollCINode)); + Vbcx = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseBINode)- + *(ckt->CKTrhsOld+here->VBICcollCXNode)); + Vbep = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseBXNode)- + *(ckt->CKTrhsOld+here->VBICbaseBPNode)); + Vrci = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICcollCXNode)- + *(ckt->CKTrhsOld+here->VBICcollCINode)); + Vrbi = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseBXNode)- + *(ckt->CKTrhsOld+here->VBICbaseBINode)); + Vrbp = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseBPNode)- + *(ckt->CKTrhsOld+here->VBICcollCXNode)); +#ifndef PREDICTOR + } +#endif /* PREDICTOR */ + delvbei = Vbei - *(ckt->CKTstate0 + here->VBICvbei); + delvbex = Vbex - *(ckt->CKTstate0 + here->VBICvbex); + delvbci = Vbci - *(ckt->CKTstate0 + here->VBICvbci); + delvbcx = Vbcx - *(ckt->CKTstate0 + here->VBICvbcx); + delvbep = Vbep - *(ckt->CKTstate0 + here->VBICvbep); + delvrci = Vrci - *(ckt->CKTstate0 + here->VBICvrci); + delvrbi = Vrbi - *(ckt->CKTstate0 + here->VBICvrbi); + delvrbp = Vrbp - *(ckt->CKTstate0 + here->VBICvrbp); + Vbe = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseNode)- + *(ckt->CKTrhsOld+here->VBICemitNode)); + Vbc = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseNode)- + *(ckt->CKTrhsOld+here->VBICcollNode)); + Vrcx = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICcollNode)- + *(ckt->CKTrhsOld+here->VBICcollCXNode)); + Vrbx = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICbaseNode)- + *(ckt->CKTrhsOld+here->VBICbaseBXNode)); + Vre = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICemitNode)- + *(ckt->CKTrhsOld+here->VBICemitEINode)); + + ibehat = *(ckt->CKTstate0 + here->VBICibe) + + *(ckt->CKTstate0 + here->VBICibe_Vbei)*delvbei; + ibexhat = *(ckt->CKTstate0 + here->VBICibex) + + *(ckt->CKTstate0 + here->VBICibex_Vbex)*delvbex; + itzfhat = *(ckt->CKTstate0 + here->VBICitzf) + + *(ckt->CKTstate0 + here->VBICitzf_Vbei)*delvbei + *(ckt->CKTstate0 + here->VBICitzf_Vbci)*delvbci; + itzrhat = *(ckt->CKTstate0 + here->VBICitzr) + + *(ckt->CKTstate0 + here->VBICitzr_Vbei)*delvbei + *(ckt->CKTstate0 + here->VBICitzr_Vbci)*delvbci; + ibchat = *(ckt->CKTstate0 + here->VBICibc) + + *(ckt->CKTstate0 + here->VBICibc_Vbei)*delvbei + *(ckt->CKTstate0 + here->VBICibc_Vbci)*delvbci; + ibephat = *(ckt->CKTstate0 + here->VBICibep) + + *(ckt->CKTstate0 + here->VBICibep_Vbep)*delvbep; + ircihat = *(ckt->CKTstate0 + here->VBICirci) + *(ckt->CKTstate0 + here->VBICirci_Vrci)*delvrci + + *(ckt->CKTstate0 + here->VBICirci_Vbcx)*delvbcx + *(ckt->CKTstate0 + here->VBICirci_Vbci)*delvbci; + irbihat = *(ckt->CKTstate0 + here->VBICirbi) + *(ckt->CKTstate0 + here->VBICirbi_Vrbi)*delvrbi + + *(ckt->CKTstate0 + here->VBICirbi_Vbei)*delvbei + *(ckt->CKTstate0 + here->VBICirbi_Vbci)*delvbci; + irbphat = *(ckt->CKTstate0 + here->VBICirbp) + *(ckt->CKTstate0 + here->VBICirbp_Vrbp)*delvrbp + + *(ckt->CKTstate0 + here->VBICirbp_Vbep)*delvbep + *(ckt->CKTstate0 + here->VBICirbp_Vbci)*delvbci; + /* + * bypass if solution has not changed + */ + /* the following collections of if's would be just one + * if the average compiler could handle it, but many + * find the expression too complicated, thus the split. + */ + if( (ckt->CKTbypass) && + (!(ckt->CKTmode & MODEINITPRED)) && + (fabs(delvbei) < (ckt->CKTreltol*MAX(fabs(Vbei), + fabs(*(ckt->CKTstate0 + here->VBICvbei)))+ + ckt->CKTvoltTol)) ) + if( (fabs(delvbex) < ckt->CKTreltol*MAX(fabs(Vbex), + fabs(*(ckt->CKTstate0 + here->VBICvbex)))+ + ckt->CKTvoltTol) ) + if( (fabs(delvbci) < ckt->CKTreltol*MAX(fabs(Vbci), + fabs(*(ckt->CKTstate0 + here->VBICvbci)))+ + ckt->CKTvoltTol) ) + if( (fabs(delvbcx) < ckt->CKTreltol*MAX(fabs(Vbcx), + fabs(*(ckt->CKTstate0 + here->VBICvbcx)))+ + ckt->CKTvoltTol) ) + if( (fabs(delvbep) < ckt->CKTreltol*MAX(fabs(Vbep), + fabs(*(ckt->CKTstate0 + here->VBICvbep)))+ + ckt->CKTvoltTol) ) + if( (fabs(delvrci) < ckt->CKTreltol*MAX(fabs(Vrci), + fabs(*(ckt->CKTstate0 + here->VBICvrci)))+ + ckt->CKTvoltTol) ) + if( (fabs(delvrbi) < ckt->CKTreltol*MAX(fabs(Vrbi), + fabs(*(ckt->CKTstate0 + here->VBICvrbi)))+ + ckt->CKTvoltTol) ) + if( (fabs(delvrbp) < ckt->CKTreltol*MAX(fabs(Vrbp), + fabs(*(ckt->CKTstate0 + here->VBICvrbp)))+ + ckt->CKTvoltTol) ) + if( (fabs(ibehat-*(ckt->CKTstate0 + here->VBICibe)) < + ckt->CKTreltol* MAX(fabs(ibehat), + fabs(*(ckt->CKTstate0 + here->VBICibe)))+ + ckt->CKTabstol) ) + if( (fabs(ibexhat-*(ckt->CKTstate0 + here->VBICibex)) < + ckt->CKTreltol* MAX(fabs(ibexhat), + fabs(*(ckt->CKTstate0 + here->VBICibex)))+ + ckt->CKTabstol) ) + if( (fabs(itzfhat-*(ckt->CKTstate0 + here->VBICitzf)) < + ckt->CKTreltol* MAX(fabs(itzfhat), + fabs(*(ckt->CKTstate0 + here->VBICitzf)))+ + ckt->CKTabstol) ) + if( (fabs(itzrhat-*(ckt->CKTstate0 + here->VBICitzr)) < + ckt->CKTreltol* MAX(fabs(itzrhat), + fabs(*(ckt->CKTstate0 + here->VBICitzr)))+ + ckt->CKTabstol) ) + if( (fabs(ibchat-*(ckt->CKTstate0 + here->VBICibc)) < + ckt->CKTreltol* MAX(fabs(ibchat), + fabs(*(ckt->CKTstate0 + here->VBICibc)))+ + ckt->CKTabstol) ) + if( (fabs(ibephat-*(ckt->CKTstate0 + here->VBICibep)) < + ckt->CKTreltol* MAX(fabs(ibephat), + fabs(*(ckt->CKTstate0 + here->VBICibep)))+ + ckt->CKTabstol) ) + if( (fabs(ircihat-*(ckt->CKTstate0 + here->VBICirci)) < + ckt->CKTreltol* MAX(fabs(ircihat), + fabs(*(ckt->CKTstate0 + here->VBICirci)))+ + ckt->CKTabstol) ) + if( (fabs(irbihat-*(ckt->CKTstate0 + here->VBICirbi)) < + ckt->CKTreltol* MAX(fabs(irbihat), + fabs(*(ckt->CKTstate0 + here->VBICirbi)))+ + ckt->CKTabstol) ) + if( (fabs(irbphat-*(ckt->CKTstate0 + here->VBICirbp)) < + ckt->CKTreltol* MAX(fabs(irbphat), + fabs(*(ckt->CKTstate0 + here->VBICirbp)))+ + ckt->CKTabstol) ) { + /* + * bypassing.... + */ + Vbei = *(ckt->CKTstate0 + here->VBICvbei); + Vbex = *(ckt->CKTstate0 + here->VBICvbex); + Vbci = *(ckt->CKTstate0 + here->VBICvbci); + Vbcx = *(ckt->CKTstate0 + here->VBICvbcx); + Vbep = *(ckt->CKTstate0 + here->VBICvbep); + Vrci = *(ckt->CKTstate0 + here->VBICvrci); + Vrbi = *(ckt->CKTstate0 + here->VBICvrbi); + Vrbp = *(ckt->CKTstate0 + here->VBICvrbp); + Ibe = *(ckt->CKTstate0 + here->VBICibe); + Ibe_Vbei = *(ckt->CKTstate0 + here->VBICibe_Vbei); + Ibex = *(ckt->CKTstate0 + here->VBICibex); + Ibex_Vbex = *(ckt->CKTstate0 + here->VBICibex_Vbex); + Itzf = *(ckt->CKTstate0 + here->VBICitzf); + Itzf_Vbei = *(ckt->CKTstate0 + here->VBICitzf_Vbei); + Itzf_Vbci = *(ckt->CKTstate0 + here->VBICitzf_Vbci); + Itzr = *(ckt->CKTstate0 + here->VBICitzr); + Itzr_Vbci = *(ckt->CKTstate0 + here->VBICitzr_Vbci); + Itzr_Vbei = *(ckt->CKTstate0 + here->VBICitzr_Vbei); + Ibc = *(ckt->CKTstate0 + here->VBICibc); + Ibc_Vbci = *(ckt->CKTstate0 + here->VBICibc_Vbci); + Ibc_Vbei = *(ckt->CKTstate0 + here->VBICibc_Vbei); + Ibep = *(ckt->CKTstate0 + here->VBICibep); + Ibep_Vbep = *(ckt->CKTstate0 + here->VBICibep_Vbep); + Irci = *(ckt->CKTstate0 + here->VBICirci); + Irci_Vrci = *(ckt->CKTstate0 + here->VBICirci_Vrci); + Irci_Vbci = *(ckt->CKTstate0 + here->VBICirci_Vbci); + Irci_Vbcx = *(ckt->CKTstate0 + here->VBICirci_Vbcx); + Irbi = *(ckt->CKTstate0 + here->VBICirbi); + Irbi_Vrbi = *(ckt->CKTstate0 + here->VBICirbi_Vrbi); + Irbi_Vbei = *(ckt->CKTstate0 + here->VBICirbi_Vbei); + Irbi_Vbci = *(ckt->CKTstate0 + here->VBICirbi_Vbci); + Irbp = *(ckt->CKTstate0 + here->VBICirbp); + Irbp_Vrbp = *(ckt->CKTstate0 + here->VBICirbp_Vrbp); + Irbp_Vbep = *(ckt->CKTstate0 + here->VBICirbp_Vbep); + Irbp_Vbci = *(ckt->CKTstate0 + here->VBICirbp_Vbci); + gqbeo = *(ckt->CKTstate0 + here->VBICgqbeo); + gqbco = *(ckt->CKTstate0 + here->VBICgqbco); + goto load; + } + /* + * limit nonlinear branch voltages + */ + ichk1 = 1; + Vbei = DEVpnjlim(Vbei,*(ckt->CKTstate0 + here->VBICvbei),vt, + here->VBICtVcrit,&icheck); + Vbex = DEVpnjlim(Vbex,*(ckt->CKTstate0 + here->VBICvbex),vt, + here->VBICtVcrit,&ichk1); + Vbci = DEVpnjlim(Vbci,*(ckt->CKTstate0 + here->VBICvbci),vt, + here->VBICtVcrit,&ichk2); + Vbcx = DEVpnjlim(Vbcx,*(ckt->CKTstate0 + here->VBICvbcx),vt, + here->VBICtVcrit,&ichk3); + Vbep = DEVpnjlim(Vbep,*(ckt->CKTstate0 + here->VBICvbep),vt, + here->VBICtVcrit,&ichk4); + if ((ichk1 == 1) || (ichk2 == 1) || (ichk3 == 1) || (ichk4 == 1)) icheck=1; + } + /* + * determine dc current and derivitives + */ +next1: + iret = vbic_3T_it_cf_fj(p + ,&Vbei,&Vbex,&Vbci,&Vbep,&Vrcx,&Vbcx + ,&Vrci,&Vrbx,&Vrbi,&Vre,&Vrbp,&Vbe,&Vbc + ,&Ibe,&Ibe_Vbei,&Ibex,&Ibex_Vbex,&Itzf,&Itzf_Vbei,&Itzf_Vbci + ,&Itzr,&Itzr_Vbci,&Itzr_Vbei,&Ibc,&Ibc_Vbci,&Ibc_Vbei,&Ibep + ,&Ibep_Vbep,&Ircx,&Ircx_Vrcx,&Irci,&Irci_Vrci,&Irci_Vbci,&Irci_Vbcx + ,&Irbx,&Irbx_Vrbx,&Irbi,&Irbi_Vrbi,&Irbi_Vbei,&Irbi_Vbci,&Ire + ,&Ire_Vre,&Irbp,&Irbp_Vrbp,&Irbp_Vbep,&Irbp_Vbci,&Qbe,&Qbe_Vbei + ,&Qbe_Vbci,&Qbex,&Qbex_Vbex,&Qbc,&Qbc_Vbci,&Qbcx,&Qbcx_Vbcx + ,&Qbep,&Qbep_Vbep,&Qbep_Vbci,&Qbeo,&Qbeo_Vbe,&Qbco,&Qbco_Vbc,&SCALE); + + Ibe += ckt->CKTgmin*Vbei; + Ibe_Vbei += ckt->CKTgmin; + Ibex += ckt->CKTgmin*Vbex; + Ibex_Vbex += ckt->CKTgmin; + Ibc += ckt->CKTgmin*Vbci; + Ibc_Vbci += ckt->CKTgmin; + Ibep += ckt->CKTgmin*Vbep; + Ibep_Vbep += ckt->CKTgmin; + Irci += ckt->CKTgmin*Vrci; + Irci_Vrci += ckt->CKTgmin; + Irci_Vbci += ckt->CKTgmin; + Irci_Vbcx += ckt->CKTgmin; + + if( (ckt->CKTmode & (MODETRAN | MODEAC)) || + ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) || + (ckt->CKTmode & MODEINITSMSIG)) { + + *(ckt->CKTstate0 + here->VBICqbe) = Qbe; + *(ckt->CKTstate0 + here->VBICqbex) = Qbex; + *(ckt->CKTstate0 + here->VBICqbc) = Qbc; + *(ckt->CKTstate0 + here->VBICqbcx) = Qbcx; + *(ckt->CKTstate0 + here->VBICqbep) = Qbep; + *(ckt->CKTstate0 + here->VBICqbeo) = Qbeo; + *(ckt->CKTstate0 + here->VBICqbco) = Qbco; + + here->VBICcapbe = Qbe_Vbei; + here->VBICcapbex = Qbex_Vbex; + here->VBICcapbc = Qbc_Vbci; + here->VBICcapbcx = Qbcx_Vbcx; + here->VBICcapbep = Qbep_Vbep; + + /* + * store small-signal parameters + */ + if ( (!(ckt->CKTmode & MODETRANOP))|| + (!(ckt->CKTmode & MODEUIC)) ) { + if(ckt->CKTmode & MODEINITSMSIG) { + *(ckt->CKTstate0 + here->VBICcqbe) = Qbe_Vbei; + *(ckt->CKTstate0 + here->VBICcqbeci) = Qbe_Vbci; + *(ckt->CKTstate0 + here->VBICcqbex) = Qbex_Vbex; + *(ckt->CKTstate0 + here->VBICcqbc) = Qbc_Vbci; + *(ckt->CKTstate0 + here->VBICcqbcx) = Qbcx_Vbcx; + *(ckt->CKTstate0 + here->VBICcqbep) = Qbep_Vbep; + *(ckt->CKTstate0 + here->VBICcqbepci) = Qbep_Vbci; + *(ckt->CKTstate0 + here->VBICcqbeo) = Qbeo_Vbe; + *(ckt->CKTstate0 + here->VBICcqbco) = Qbco_Vbc; + if(SenCond) { + *(ckt->CKTstate0 + here->VBICibe) = Ibe; + *(ckt->CKTstate0 + here->VBICibe_Vbei) = Ibe_Vbei; + *(ckt->CKTstate0 + here->VBICibex) = Ibex; + *(ckt->CKTstate0 + here->VBICibex_Vbex) = Ibex_Vbex; + *(ckt->CKTstate0 + here->VBICitzf) = Itzf; + *(ckt->CKTstate0 + here->VBICitzf_Vbei) = Itzf_Vbei; + *(ckt->CKTstate0 + here->VBICitzf_Vbci) = Itzf_Vbci; + *(ckt->CKTstate0 + here->VBICitzr) = Itzr; + *(ckt->CKTstate0 + here->VBICitzr_Vbci) = Itzr_Vbci; + *(ckt->CKTstate0 + here->VBICitzr_Vbei) = Itzr_Vbei; + *(ckt->CKTstate0 + here->VBICibc) = Ibc; + *(ckt->CKTstate0 + here->VBICibc_Vbci) = Ibc_Vbci; + *(ckt->CKTstate0 + here->VBICibc_Vbei) = Ibc_Vbei; + *(ckt->CKTstate0 + here->VBICibep) = Ibep; + *(ckt->CKTstate0 + here->VBICibep_Vbep) = Ibep_Vbep; + *(ckt->CKTstate0 + here->VBICirci) = Irci; + *(ckt->CKTstate0 + here->VBICirci_Vrci) = Irci_Vrci; + *(ckt->CKTstate0 + here->VBICirci_Vbci) = Irci_Vbci; + *(ckt->CKTstate0 + here->VBICirci_Vbcx) = Irci_Vbcx; + *(ckt->CKTstate0 + here->VBICirbi) = Irbi; + *(ckt->CKTstate0 + here->VBICirbi_Vrbi) = Irbi_Vrbi; + *(ckt->CKTstate0 + here->VBICirbi_Vbei) = Irbi_Vbei; + *(ckt->CKTstate0 + here->VBICirbi_Vbci) = Irbi_Vbci; + *(ckt->CKTstate0 + here->VBICirbp) = Irbp; + *(ckt->CKTstate0 + here->VBICirbp_Vrbp) = Irbp_Vrbp; + *(ckt->CKTstate0 + here->VBICirbp_Vbep) = Irbp_Vbep; + *(ckt->CKTstate0 + here->VBICirbp_Vbci) = Irbp_Vbci; + *(ckt->CKTstate0 + here->VBICgqbeo) = gqbeo; + *(ckt->CKTstate0 + here->VBICgqbco) = gqbco; + } +#ifdef SENSDEBUG + printf("storing small signal parameters for op\n"); + printf("Cbe = %.7e, Cbex = %.7e\n", Qbe_Vbei, Qbex_Vbex); + printf("Cbc = %.7e, Cbcx = %.7e\n", Qbc_Vbci, Qbcx_Vbcx); + printf("gpi = %.7e\n", Ibe_Vbei); + printf("gmu = %.7e, gm = %.7e\n", Ibc_Vbci, Itzf_Vbei); + printf("go = %.7e, gx = %.7e\n", Itzf_Vbci, Irbi_Vrbi); + printf("geqcb = %.7e, geqbx = %.7e\n", geqcb, geqbx); + printf("cc = %.7e, cb = %.7e\n", Ibe+Itzf, Ibe); +#endif /* SENSDEBUG */ + continue; /* go to 1000 */ + } + /* + * transient analysis + */ + if(SenCond && ckt->CKTsenInfo->SENmode == TRANSEN) { + *(ckt->CKTstate0 + here->VBICibe) = Ibe; + *(ckt->CKTstate0 + here->VBICibex) = Ibex; + *(ckt->CKTstate0 + here->VBICitzf) = Itzf; + *(ckt->CKTstate0 + here->VBICitzr) = Itzr; + *(ckt->CKTstate0 + here->VBICibc) = Ibc; + *(ckt->CKTstate0 + here->VBICibep) = Ibep; + *(ckt->CKTstate0 + here->VBICirci) = Irci; + *(ckt->CKTstate0 + here->VBICirbi) = Irbi; + *(ckt->CKTstate0 + here->VBICirbp) = Irbp; + continue; + } + + if(ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->VBICqbe) = + *(ckt->CKTstate0 + here->VBICqbe) ; + *(ckt->CKTstate1 + here->VBICqbex) = + *(ckt->CKTstate0 + here->VBICqbex) ; + *(ckt->CKTstate1 + here->VBICqbc) = + *(ckt->CKTstate0 + here->VBICqbc) ; + *(ckt->CKTstate1 + here->VBICqbcx) = + *(ckt->CKTstate0 + here->VBICqbcx) ; + *(ckt->CKTstate1 + here->VBICqbep) = + *(ckt->CKTstate0 + here->VBICqbep) ; + *(ckt->CKTstate1 + here->VBICqbeo) = + *(ckt->CKTstate0 + here->VBICqbeo) ; + *(ckt->CKTstate1 + here->VBICqbco) = + *(ckt->CKTstate0 + here->VBICqbco) ; + } + error = NIintegrate(ckt,&geq,&ceq,Qbe_Vbei,here->VBICqbe); + if(error) return(error); + Ibe_Vbei = Ibe_Vbei + geq; + Ibe = Ibe + *(ckt->CKTstate0 + here->VBICcqbe); + + error = NIintegrate(ckt,&geq,&ceq,Qbex_Vbex,here->VBICqbex); + if(error) return(error); + Ibex_Vbex = Ibex_Vbex + geq; + Ibex = Ibex + *(ckt->CKTstate0 + here->VBICcqbex); + + error = NIintegrate(ckt,&geq,&ceq,Qbc_Vbci,here->VBICqbc); + if(error) return(error); + Ibc_Vbci = Ibc_Vbci + geq; + Ibc = Ibc + *(ckt->CKTstate0 + here->VBICcqbc); + + error = NIintegrate(ckt,&geq,&ceq,Qbcx_Vbcx,here->VBICqbcx); + if(error) return(error); + gbcx = geq; + cbcx = *(ckt->CKTstate0 + here->VBICcqbcx); + + error = NIintegrate(ckt,&geq,&ceq,Qbep_Vbep,here->VBICqbep); + if(error) return(error); + Ibep_Vbep = Ibep_Vbep + geq; + Ibep = Ibep + *(ckt->CKTstate0 + here->VBICcqbep); + + if(ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->VBICcqbe) = + *(ckt->CKTstate0 + here->VBICcqbe); + *(ckt->CKTstate1 + here->VBICcqbex) = + *(ckt->CKTstate0 + here->VBICcqbex); + *(ckt->CKTstate1 + here->VBICcqbc) = + *(ckt->CKTstate0 + here->VBICcqbc); + *(ckt->CKTstate1 + here->VBICcqbcx) = + *(ckt->CKTstate0 + here->VBICcqbcx); + *(ckt->CKTstate1 + here->VBICcqbep) = + *(ckt->CKTstate0 + here->VBICcqbep); + } + } + } + + if(SenCond) goto next2; + + /* + * check convergence + */ + if ( (!(ckt->CKTmode & MODEINITFIX))||(!(here->VBICoff))) { + if (icheck == 1) { + ckt->CKTnoncon++; + ckt->CKTtroubleElt = (GENinstance *) here; + } + } + + /* + * charge storage for outer b-e and b-c junctions + */ + if(ckt->CKTmode & (MODETRAN | MODEAC)) { + error = NIintegrate(ckt,&gqbeo,&cqbeo,Qbeo_Vbe,here->VBICqbeo); + if(error) return(error); + error = NIintegrate(ckt,&gqbco,&cqbco,Qbco_Vbc,here->VBICqbco); + if(error) return(error); + if(ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->VBICcqbeo) = + *(ckt->CKTstate0 + here->VBICcqbeo); + *(ckt->CKTstate1 + here->VBICcqbco) = + *(ckt->CKTstate0 + here->VBICcqbco); + } + } +next2: + *(ckt->CKTstate0 + here->VBICvbei) = Vbei; + *(ckt->CKTstate0 + here->VBICvbex) = Vbex; + *(ckt->CKTstate0 + here->VBICvbci) = Vbci; + *(ckt->CKTstate0 + here->VBICvbcx) = Vbcx; + *(ckt->CKTstate0 + here->VBICvbep) = Vbep; + *(ckt->CKTstate0 + here->VBICvrci) = Vrci; + *(ckt->CKTstate0 + here->VBICvrbi) = Vrbi; + *(ckt->CKTstate0 + here->VBICvrbp) = Vrbp; + *(ckt->CKTstate0 + here->VBICibe) = Ibe; + *(ckt->CKTstate0 + here->VBICibe_Vbei) = Ibe_Vbei; + *(ckt->CKTstate0 + here->VBICibex) = Ibex; + *(ckt->CKTstate0 + here->VBICibex_Vbex) = Ibex_Vbex; + *(ckt->CKTstate0 + here->VBICitzf) = Itzf; + *(ckt->CKTstate0 + here->VBICitzf_Vbei) = Itzf_Vbei; + *(ckt->CKTstate0 + here->VBICitzf_Vbci) = Itzf_Vbci; + *(ckt->CKTstate0 + here->VBICitzr) = Itzr; + *(ckt->CKTstate0 + here->VBICitzr_Vbci) = Itzr_Vbci; + *(ckt->CKTstate0 + here->VBICitzr_Vbei) = Itzr_Vbei; + *(ckt->CKTstate0 + here->VBICibc) = Ibc; + *(ckt->CKTstate0 + here->VBICibc_Vbci) = Ibc_Vbci; + *(ckt->CKTstate0 + here->VBICibc_Vbei) = Ibc_Vbei; + *(ckt->CKTstate0 + here->VBICibep) = Ibep; + *(ckt->CKTstate0 + here->VBICibep_Vbep) = Ibep_Vbep; + *(ckt->CKTstate0 + here->VBICirci) = Irci; + *(ckt->CKTstate0 + here->VBICirci_Vrci) = Irci_Vrci; + *(ckt->CKTstate0 + here->VBICirci_Vbci) = Irci_Vbci; + *(ckt->CKTstate0 + here->VBICirci_Vbcx) = Irci_Vbcx; + *(ckt->CKTstate0 + here->VBICirbi) = Irbi; + *(ckt->CKTstate0 + here->VBICirbi_Vrbi) = Irbi_Vrbi; + *(ckt->CKTstate0 + here->VBICirbi_Vbei) = Irbi_Vbei; + *(ckt->CKTstate0 + here->VBICirbi_Vbci) = Irbi_Vbci; + *(ckt->CKTstate0 + here->VBICirbp) = Irbp; + *(ckt->CKTstate0 + here->VBICirbp_Vrbp) = Irbp_Vrbp; + *(ckt->CKTstate0 + here->VBICirbp_Vbep) = Irbp_Vbep; + *(ckt->CKTstate0 + here->VBICirbp_Vbci) = Irbp_Vbci; + *(ckt->CKTstate0 + here->VBICgqbeo) = gqbeo; + *(ckt->CKTstate0 + here->VBICgqbco) = gqbco; + + /* Do not load the Jacobian and the rhs if + perturbation is being carried out */ + if(SenCond) continue; +load: + /* + * load current excitation vector and matrix + */ + rhs_current = model->VBICtype * (*(ckt->CKTstate0 + here->VBICcqbeo) - + Vbe * gqbeo); + *(ckt->CKTrhs + here->VBICbaseNode) += -rhs_current; + *(ckt->CKTrhs + here->VBICemitNode) += rhs_current; + *(here->VBICbaseBasePtr) += gqbeo; + *(here->VBICemitEmitPtr) += gqbeo; + *(here->VBICbaseEmitPtr) += -gqbeo; + *(here->VBICemitBasePtr) += -gqbeo; + + rhs_current = model->VBICtype * (*(ckt->CKTstate0 + here->VBICcqbco) - + Vbc * gqbco); + *(ckt->CKTrhs + here->VBICbaseNode) += -rhs_current; + *(ckt->CKTrhs + here->VBICcollNode) += rhs_current; + *(here->VBICbaseBasePtr) += gqbco; + *(here->VBICcollCollPtr) += gqbco; + *(here->VBICbaseCollPtr) += -gqbco; + *(here->VBICcollBasePtr) += -gqbco; + + *(ckt->CKTrhs + here->VBICbaseBINode) += -cbcx; + *(ckt->CKTrhs + here->VBICcollCXNode) += cbcx; + *(here->VBICbaseBIBaseBIPtr) += gbcx; + *(here->VBICcollCXCollCXPtr) += gbcx; + *(here->VBICbaseBICollCXPtr) += -gbcx; + *(here->VBICcollCXBaseBIPtr) += -gbcx; + +/* +c KCL at internal nodes +c +c Stamp element: Ibe +*/ + rhs_current = model->VBICtype * (Ibe - Ibe_Vbei*Vbei); + *(ckt->CKTrhs + here->VBICbaseBINode) += -rhs_current; + *(here->VBICbaseBIBaseBIPtr) += Ibe_Vbei; + *(here->VBICbaseBIEmitEIPtr) += -Ibe_Vbei; + *(ckt->CKTrhs + here->VBICemitEINode) += rhs_current; + *(here->VBICemitEIBaseBIPtr) += -Ibe_Vbei; + *(here->VBICemitEIEmitEIPtr) += Ibe_Vbei; +/* +c Stamp element: Ibex +*/ + rhs_current = model->VBICtype * (Ibex - Ibex_Vbex*Vbex); + *(ckt->CKTrhs + here->VBICbaseBXNode) += -rhs_current; + *(here->VBICbaseBXBaseBXPtr) += Ibex_Vbex; + *(here->VBICbaseBXEmitEIPtr) += -Ibex_Vbex; + *(ckt->CKTrhs + here->VBICemitEINode) += rhs_current; + *(here->VBICemitEIBaseBXPtr) += -Ibex_Vbex; + *(here->VBICemitEIEmitEIPtr) += Ibex_Vbex; + +/* +c Stamp element: Itzf +*/ + rhs_current = model->VBICtype * (Itzf - Itzf_Vbei*Vbei - Itzf_Vbci*Vbci); + *(ckt->CKTrhs + here->VBICcollCINode) += -rhs_current; + *(here->VBICcollCIBaseBIPtr) += Itzf_Vbei; + *(here->VBICcollCIEmitEIPtr) += -Itzf_Vbei; + *(here->VBICcollCIBaseBIPtr) += Itzf_Vbci; + *(here->VBICcollCICollCIPtr) += -Itzf_Vbci; + *(ckt->CKTrhs + here->VBICemitEINode) += rhs_current; + *(here->VBICemitEIBaseBIPtr) += -Itzf_Vbei; + *(here->VBICemitEIEmitEIPtr) += Itzf_Vbei; + *(here->VBICemitEIBaseBIPtr) += -Itzf_Vbci; + *(here->VBICemitEICollCIPtr) += Itzf_Vbci; +/* +c Stamp element: Itzr +*/ + rhs_current = model->VBICtype * (Itzr - Itzr_Vbci*Vbci - Itzr_Vbei*Vbei); + *(ckt->CKTrhs + here->VBICemitEINode) += -rhs_current; + *(here->VBICemitEIBaseBIPtr) += Itzr_Vbci; + *(here->VBICemitEICollCIPtr) += -Itzr_Vbci; + *(here->VBICemitEIBaseBIPtr) += Itzr_Vbei; + *(here->VBICemitEIEmitEIPtr) += -Itzr_Vbei; + *(ckt->CKTrhs + here->VBICcollCINode) += rhs_current; + *(here->VBICcollCIBaseBIPtr) += -Itzr_Vbci; + *(here->VBICcollCICollCIPtr) += Itzr_Vbci; + *(here->VBICcollCIBaseBIPtr) += -Itzr_Vbei; + *(here->VBICcollCIEmitEIPtr) += Itzr_Vbei; +/* +c Stamp element: Ibc +*/ + rhs_current = model->VBICtype * (Ibc - Ibc_Vbci*Vbci - Ibc_Vbei*Vbei); + *(ckt->CKTrhs + here->VBICbaseBINode) += -rhs_current; + *(here->VBICbaseBIBaseBIPtr) += Ibc_Vbci; + *(here->VBICbaseBICollCIPtr) += -Ibc_Vbci; + *(here->VBICbaseBIBaseBIPtr) += Ibc_Vbei; + *(here->VBICbaseBIEmitEIPtr) += -Ibc_Vbei; + *(ckt->CKTrhs + here->VBICcollCINode) += rhs_current; + *(here->VBICcollCIBaseBIPtr) += -Ibc_Vbci; + *(here->VBICcollCICollCIPtr) += Ibc_Vbci; + *(here->VBICcollCIBaseBIPtr) += -Ibc_Vbei; + *(here->VBICcollCIEmitEIPtr) += Ibc_Vbei; +/* +c Stamp element: Ibep +*/ + rhs_current = model->VBICtype * (Ibep - Ibep_Vbep*Vbep); + *(ckt->CKTrhs + here->VBICbaseBXNode) += -rhs_current; + *(here->VBICbaseBXBaseBXPtr) += Ibep_Vbep; + *(here->VBICbaseBXBaseBPPtr) += -Ibep_Vbep; + *(ckt->CKTrhs + here->VBICbaseBPNode) += rhs_current; + *(here->VBICbaseBPBaseBXPtr) += -Ibep_Vbep; + *(here->VBICbaseBPBaseBPPtr) += Ibep_Vbep; +/* +c Stamp element: Ircx +*/ + *(here->VBICcollCollPtr) += Ircx_Vrcx; + *(here->VBICcollCXCollCXPtr) += Ircx_Vrcx; + *(here->VBICcollCXCollPtr) += -Ircx_Vrcx; + *(here->VBICcollCollCXPtr) += -Ircx_Vrcx; +/* +c Stamp element: Irci +*/ + rhs_current = model->VBICtype * (Irci - Irci_Vrci*Vrci - Irci_Vbci*Vbci - Irci_Vbcx*Vbcx); + *(ckt->CKTrhs + here->VBICcollCXNode) += -rhs_current; + *(here->VBICcollCXCollCXPtr) += Irci_Vrci; + *(here->VBICcollCXCollCIPtr) += -Irci_Vrci; + *(here->VBICcollCXBaseBIPtr) += Irci_Vbci; + *(here->VBICcollCXCollCIPtr) += -Irci_Vbci; + *(here->VBICcollCXBaseBIPtr) += Irci_Vbcx; + *(here->VBICcollCXCollCXPtr) += -Irci_Vbcx; + *(ckt->CKTrhs + here->VBICcollCINode) += rhs_current; + *(here->VBICcollCICollCXPtr) += -Irci_Vrci; + *(here->VBICcollCICollCIPtr) += Irci_Vrci; + *(here->VBICcollCIBaseBIPtr) += -Irci_Vbci; + *(here->VBICcollCICollCIPtr) += Irci_Vbci; + *(here->VBICcollCIBaseBIPtr) += -Irci_Vbcx; + *(here->VBICcollCICollCXPtr) += Irci_Vbcx; +/* +c Stamp element: Irbx +*/ + *(here->VBICbaseBasePtr) += Irbx_Vrbx; + *(here->VBICbaseBXBaseBXPtr) += Irbx_Vrbx; + *(here->VBICbaseBXBasePtr) += -Irbx_Vrbx; + *(here->VBICbaseBaseBXPtr) += -Irbx_Vrbx; +/* +c Stamp element: Irbi +*/ + rhs_current = model->VBICtype * (Irbi - Irbi_Vrbi*Vrbi - Irbi_Vbei*Vbei - Irbi_Vbci*Vbci); + *(ckt->CKTrhs + here->VBICbaseBXNode) += -rhs_current; + *(here->VBICbaseBXBaseBXPtr) += Irbi_Vrbi; + *(here->VBICbaseBXBaseBIPtr) += -Irbi_Vrbi; + *(here->VBICbaseBXBaseBIPtr) += Irbi_Vbei; + *(here->VBICbaseBXEmitEIPtr) += -Irbi_Vbei; + *(here->VBICbaseBXBaseBIPtr) += Irbi_Vbci; + *(here->VBICbaseBXCollCIPtr) += -Irbi_Vbci; + *(ckt->CKTrhs + here->VBICbaseBINode) += rhs_current; + *(here->VBICbaseBIBaseBXPtr) += -Irbi_Vrbi; + *(here->VBICbaseBIBaseBIPtr) += Irbi_Vrbi; + *(here->VBICbaseBIBaseBIPtr) += -Irbi_Vbei; + *(here->VBICbaseBIEmitEIPtr) += Irbi_Vbei; + *(here->VBICbaseBIBaseBIPtr) += -Irbi_Vbci; + *(here->VBICbaseBICollCIPtr) += Irbi_Vbci; +/* +c Stamp element: Ire +*/ + *(here->VBICemitEmitPtr) += Ire_Vre; + *(here->VBICemitEIEmitEIPtr) += Ire_Vre; + *(here->VBICemitEIEmitPtr) += -Ire_Vre; + *(here->VBICemitEmitEIPtr) += -Ire_Vre; +/* +c Stamp element: Irbp +*/ + rhs_current = model->VBICtype * (Irbp - Irbp_Vrbp*Vrbp - Irbp_Vbep*Vbep - Irbp_Vbci*Vbci); + *(ckt->CKTrhs + here->VBICbaseBPNode) += -rhs_current; + *(here->VBICbaseBPBaseBPPtr) += Irbp_Vrbp; + *(here->VBICbaseBPCollCXPtr) += -Irbp_Vrbp; + *(here->VBICbaseBPBaseBXPtr) += Irbp_Vbep; + *(here->VBICbaseBPBaseBPPtr) += -Irbp_Vbep; + *(here->VBICbaseBPBaseBIPtr) += Irbp_Vbci; + *(here->VBICbaseBPCollCIPtr) += -Irbp_Vbci; + *(ckt->CKTrhs + here->VBICcollCXNode) += rhs_current; + *(here->VBICcollCXBaseBPPtr) += -Irbp_Vrbp; + *(here->VBICcollCXCollCXPtr) += Irbp_Vrbp; + *(here->VBICcollCXBaseBXPtr) += -Irbp_Vbep; + *(here->VBICcollCXBaseBPPtr) += Irbp_Vbep; + *(here->VBICcollCXBaseBIPtr) += -Irbp_Vbci; + *(here->VBICcollCXCollCIPtr) += Irbp_Vbci; + + } + + } + return(OK); +} + +int vbic_3T_it_cf_fj(p + ,Vbei,Vbex,Vbci,Vbep,Vrcx,Vbcx + ,Vrci,Vrbx,Vrbi,Vre,Vrbp,Vbe,Vbc + ,Ibe,Ibe_Vbei,Ibex,Ibex_Vbex,Itzf,Itzf_Vbei,Itzf_Vbci + ,Itzr,Itzr_Vbci,Itzr_Vbei,Ibc,Ibc_Vbci,Ibc_Vbei,Ibep + ,Ibep_Vbep,Ircx,Ircx_Vrcx,Irci,Irci_Vrci,Irci_Vbci,Irci_Vbcx + ,Irbx,Irbx_Vrbx,Irbi,Irbi_Vrbi,Irbi_Vbei,Irbi_Vbci,Ire + ,Ire_Vre,Irbp,Irbp_Vrbp,Irbp_Vbep,Irbp_Vbci,Qbe,Qbe_Vbei + ,Qbe_Vbci,Qbex,Qbex_Vbex,Qbc,Qbc_Vbci,Qbcx,Qbcx_Vbcx + ,Qbep,Qbep_Vbep,Qbep_Vbci,Qbeo,Qbeo_Vbe,Qbco,Qbco_Vbc,SCALE) +double *p + ,*Vbei,*Vbex,*Vbci,*Vbep,*Vrcx,*Vbcx + ,*Vrci,*Vrbx,*Vrbi,*Vre,*Vrbp,*Vbe,*Vbc + ,*Ibe,*Ibe_Vbei,*Ibex,*Ibex_Vbex,*Itzf,*Itzf_Vbei,*Itzf_Vbci + ,*Itzr,*Itzr_Vbci,*Itzr_Vbei,*Ibc,*Ibc_Vbci,*Ibc_Vbei,*Ibep + ,*Ibep_Vbep,*Ircx,*Ircx_Vrcx,*Irci,*Irci_Vrci,*Irci_Vbci,*Irci_Vbcx + ,*Irbx,*Irbx_Vrbx,*Irbi,*Irbi_Vrbi,*Irbi_Vbei,*Irbi_Vbci,*Ire + ,*Ire_Vre,*Irbp,*Irbp_Vrbp,*Irbp_Vbep,*Irbp_Vbci,*Qbe,*Qbe_Vbei + ,*Qbe_Vbci,*Qbex,*Qbex_Vbex,*Qbc,*Qbc_Vbci,*Qbcx,*Qbcx_Vbcx + ,*Qbep,*Qbep_Vbep,*Qbep_Vbci,*Qbeo,*Qbeo_Vbe,*Qbco,*Qbco_Vbc,*SCALE; +{ +double Vtv,IVEF,IVER,IIKF,IIKR,IIKP,IVO; +double IHRCF,IVTF,IITF,slTF,dv0,dvh,dvh_Vbei; +double xvar1,xvar2,pwq,qlo,qlo_Vbei,qhi,qhi_dvh; +double qhi_Vbei,xvar1_Vbei,xvar3,xvar3_xvar1,xvar3_Vbei,qlo_xvar3,qdbe; +double qdbe_qlo,qdbe_Vbei,qdbe_qhi,mv0,vl0,q0,dv; +double dv_Vbei,mv,mv_dv,mv_Vbei,vl,vl_dv,vl_Vbei; +double vl_mv,xvar1_vl,qdbe_vl,dvh_Vbex,qlo_Vbex,qhi_Vbex,xvar1_Vbex; +double xvar3_Vbex,qdbex,qdbex_qlo,qdbex_Vbex,qdbex_qhi,dv_Vbex,mv_Vbex; +double vl_Vbex,qdbex_vl,dvh_Vbci,qlo_Vbci,qhi_Vbci,xvar1_Vbci,xvar3_Vbci; +double qdbc,qdbc_qlo,qdbc_Vbci,qdbc_qhi,vn0,vnl0,qlo0; +double vn,vn_Vbci,vnl,vnl_vn,vnl_Vbci,vl_vnl,vl_Vbci; +double sel,sel_vnl,sel_Vbci,crt,cmx,cl,cl_sel; +double cl_Vbci,ql,ql_Vbci,ql_vl,ql_cl,qdbc_ql,dv_Vbci; +double mv_Vbci,qdbc_vl,dvh_Vbep,qlo_Vbep,qhi_Vbep,xvar1_Vbep,xvar3_Vbep; +double qdbep,qdbep_qlo,qdbep_Vbep,qdbep_qhi,vn_Vbep,vnl_Vbep,vl_Vbep; +double sel_Vbep,cl_Vbep,ql_Vbep,qdbep_ql,dv_Vbep,mv_Vbep,qdbep_vl; +double argi,argi_Vbei,expi,expi_argi,expi_Vbei,Ifi,Ifi_expi; +double Ifi_Vbei,argi_Vbci,expi_Vbci,Iri,Iri_expi,Iri_Vbci,q1z; +double q1z_qdbe,q1z_Vbei,q1z_qdbc,q1z_Vbci,q1,q1_q1z,q1_Vbei; +double q1_Vbci,q2,q2_Ifi,q2_Vbei,q2_Iri,q2_Vbci,xvar3_q1; +double xvar1_xvar3,xvar1_q2,xvar4,xvar4_xvar1,xvar4_Vbei,xvar4_Vbci,qb; +double qb_q1,qb_Vbei,qb_Vbci,qb_xvar4,xvar2_xvar1,xvar2_Vbei,xvar2_Vbci; +double qb_xvar2,Itzr_Iri,Itzr_qb,Itzf_Ifi,Itzf_qb,argi_Vbep,expi_Vbep; +double argx,argx_Vbci,expx,expx_argx,expx_Vbci,Ifp,Ifp_expi; +double Ifp_Vbep,Ifp_expx,Ifp_Vbci,q2p,q2p_Ifp,q2p_Vbep,q2p_Vbci; +double qbp,qbp_q2p,qbp_Vbep,qbp_Vbci,argn,argn_Vbei,expn; +double expn_argn,expn_Vbei,argx_Vbei,expx_Vbei,Ibe_expi,Ibe_expn,Ibe_expx; +double argi_Vbex,expi_Vbex,argn_Vbex,expn_Vbex,argx_Vbex,expx_Vbex,Ibex_expi; +double Ibex_expn,Ibex_expx,argn_Vbci,expn_Vbci,Ibcj,Ibcj_expi,Ibcj_Vbci; +double Ibcj_expn,argn_Vbep,expn_Vbep,Ibep_expi,Ibep_expn,xvar3_vl,avalf; +double avalf_vl,avalf_Vbci,avalf_xvar4,Igc,Igc_Itzf,Igc_Vbei,Igc_Vbci; +double Igc_Itzr,Igc_Ibcj,Igc_avalf,Ibc_Ibcj,Ibc_Igc,argx_Vbcx,expx_Vbcx; +double Kbci,Kbci_expi,Kbci_Vbci,Kbcx,Kbcx_expx,Kbcx_Vbcx,rKp1; +double rKp1_Kbci,rKp1_Vbci,rKp1_Kbcx,rKp1_Vbcx,xvar1_rKp1,xvar1_Vbcx,Iohm; +double Iohm_Vrci,Iohm_Kbci,Iohm_Vbci,Iohm_Kbcx,Iohm_Vbcx,Iohm_xvar1,derf; +double derf_Iohm,derf_Vrci,derf_Vbci,derf_Vbcx,Irci_Iohm,Irci_derf,Irbi_qb; +double Irbp_qbp,sgIf,rIf,rIf_Ifi,rIf_Vbei,mIf,mIf_rIf; +double mIf_Vbei,tff,tff_q1,tff_Vbei,tff_Vbci,tff_xvar2,tff_mIf; +double Qbe_qdbe,Qbe_tff,Qbe_Ifi,Qbe_qb,Qbex_qdbex,Qbc_qdbc,Qbc_Iri; +double Qbc_Kbci,Qbcx_Kbcx,Qbep_qdbep,Qbep_Ifp; + +/* Function and derivative code */ + + Vtv=1.380662e-23*(2.731500e+02+p[0])/1.602189e-19; + if(p[51]>0.0){ + IVEF=1.0/p[51]; + }else{ + IVEF=0.0; + } + if(p[52]>0.0){ + IVER=1.0/p[52]; + }else{ + IVER=0.0; + } + if(p[53]>0.0){ + IIKF=1.0/p[53]; + }else{ + IIKF=0.0; + } + if(p[54]>0.0){ + IIKR=1.0/p[54]; + }else{ + IIKR=0.0; + } + if(p[55]>0.0){ + IIKP=1.0/p[55]; + }else{ + IIKP=0.0; + } + if(p[3]>0.0){ + IVO=1.0/p[3]; + }else{ + IVO=0.0; + } + if(p[5]>0.0){ + IHRCF=1.0/p[5]; + }else{ + IHRCF=0.0; + } + if(p[59]>0.0){ + IVTF=1.0/p[59]; + }else{ + IVTF=0.0; + } + if(p[60]>0.0){ + IITF=1.0/p[60]; + }else{ + IITF=0.0; + } + if(p[60]>0.0){ + slTF=0.0; + }else{ + slTF=1.0; + } + dv0=-p[17]*p[14]; + if(p[19]<=0.0){ + dvh=(*Vbei)+dv0; + dvh_Vbei=1.0; + if(dvh>0.0){ + xvar1=(1.0-p[14]); + xvar2=(-1.0-p[18]); + pwq=pow(xvar1,xvar2); + qlo=p[17]*(1.0-pwq*(1.0-p[14])*(1.0-p[14]))/(1.0-p[18]); + qlo_Vbei=0.0; + qhi=dvh*(1.0-p[14]+0.5*p[18]*dvh/p[17])*pwq; + qhi_dvh=(0.5*dvh*p[18]/p[17]-p[14]+1.0)*pwq+0.5*dvh*p[18]*pwq/p[17]; + qhi_Vbei=qhi_dvh*dvh_Vbei; + }else{ + xvar1=(1.0-(*Vbei)/p[17]); + xvar1_Vbei=-1.0/p[17]; + xvar2=(1.0-p[18]); + xvar3=pow(xvar1,xvar2); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vbei=xvar3_xvar1*xvar1_Vbei; + qlo=p[17]*(1.0-xvar3)/(1.0-p[18]); + qlo_xvar3=-p[17]/(1.0-p[18]); + qlo_Vbei=qlo_xvar3*xvar3_Vbei; + qhi=0.0; + qhi_Vbei=0.0; + } + qdbe=qlo+qhi; + qdbe_qlo=1.0; + qdbe_qhi=1.0; + qdbe_Vbei=qdbe_qlo*qlo_Vbei; + qdbe_Vbei=qdbe_Vbei+qdbe_qhi*qhi_Vbei; + }else{ + mv0=sqrt(dv0*dv0+4.0*p[19]*p[19]); + vl0=-0.5*(dv0+mv0); + xvar1=(1.0-vl0/p[17]); + xvar2=(1.0-p[18]); + xvar3=pow(xvar1,xvar2); + q0=-p[17]*xvar3/(1.0-p[18]); + dv=(*Vbei)+dv0; + dv_Vbei=1.0; + mv=sqrt(dv*dv+4.0*p[19]*p[19]); + mv_dv=dv/sqrt((dv*dv)+4.0*(p[19]*p[19])); + mv_Vbei=mv_dv*dv_Vbei; + vl=0.5*(dv-mv)-dv0; + vl_dv=0.5; + vl_mv=-0.5; + vl_Vbei=vl_dv*dv_Vbei; + vl_Vbei=vl_Vbei+vl_mv*mv_Vbei; + xvar1=(1.0-vl/p[17]); + xvar1_vl=-1.0/p[17]; + xvar1_Vbei=xvar1_vl*vl_Vbei; + xvar2=(1.0-p[18]); + xvar3=pow(xvar1,xvar2); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vbei=xvar3_xvar1*xvar1_Vbei; + qlo=-p[17]*xvar3/(1.0-p[18]); + qlo_xvar3=-p[17]/(1.0-p[18]); + qlo_Vbei=qlo_xvar3*xvar3_Vbei; + xvar1=(1.0-p[14]); + xvar2=(-p[18]); + xvar3=pow(xvar1,xvar2); + qdbe=qlo+xvar3*((*Vbei)-vl+vl0)-q0; + qdbe_qlo=1.0; + qdbe_Vbei=xvar3; + qdbe_vl=-xvar3; + qdbe_Vbei=qdbe_Vbei+qdbe_qlo*qlo_Vbei; + qdbe_Vbei=qdbe_Vbei+qdbe_vl*vl_Vbei; + } + dv0=-p[17]*p[14]; + if(p[19]<=0.0){ + dvh=(*Vbex)+dv0; + dvh_Vbex=1.0; + if(dvh>0.0){ + xvar1=(1.0-p[14]); + xvar2=(-1.0-p[18]); + pwq=pow(xvar1,xvar2); + qlo=p[17]*(1.0-pwq*(1.0-p[14])*(1.0-p[14]))/(1.0-p[18]); + qlo_Vbex=0.0; + qhi=dvh*(1.0-p[14]+0.5*p[18]*dvh/p[17])*pwq; + qhi_dvh=(0.5*dvh*p[18]/p[17]-p[14]+1.0)*pwq+0.5*dvh*p[18]*pwq/p[17]; + qhi_Vbex=qhi_dvh*dvh_Vbex; + }else{ + xvar1=(1.0-(*Vbex)/p[17]); + xvar1_Vbex=-1.0/p[17]; + xvar2=(1.0-p[18]); + xvar3=pow(xvar1,xvar2); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vbex=xvar3_xvar1*xvar1_Vbex; + qlo=p[17]*(1.0-xvar3)/(1.0-p[18]); + qlo_xvar3=-p[17]/(1.0-p[18]); + qlo_Vbex=qlo_xvar3*xvar3_Vbex; + qhi=0.0; + qhi_Vbex=0.0; + } + qdbex=qlo+qhi; + qdbex_qlo=1.0; + qdbex_qhi=1.0; + qdbex_Vbex=qdbex_qlo*qlo_Vbex; + qdbex_Vbex=qdbex_Vbex+qdbex_qhi*qhi_Vbex; + }else{ + mv0=sqrt(dv0*dv0+4.0*p[19]*p[19]); + vl0=-0.5*(dv0+mv0); + xvar1=(1.0-vl0/p[17]); + xvar2=(1.0-p[18]); + xvar3=pow(xvar1,xvar2); + q0=-p[17]*xvar3/(1.0-p[18]); + dv=(*Vbex)+dv0; + dv_Vbex=1.0; + mv=sqrt(dv*dv+4.0*p[19]*p[19]); + mv_dv=dv/sqrt((dv*dv)+4.0*(p[19]*p[19])); + mv_Vbex=mv_dv*dv_Vbex; + vl=0.5*(dv-mv)-dv0; + vl_dv=0.5; + vl_mv=-0.5; + vl_Vbex=vl_dv*dv_Vbex; + vl_Vbex=vl_Vbex+vl_mv*mv_Vbex; + xvar1=(1.0-vl/p[17]); + xvar1_vl=-1.0/p[17]; + xvar1_Vbex=xvar1_vl*vl_Vbex; + xvar2=(1.0-p[18]); + xvar3=pow(xvar1,xvar2); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vbex=xvar3_xvar1*xvar1_Vbex; + qlo=-p[17]*xvar3/(1.0-p[18]); + qlo_xvar3=-p[17]/(1.0-p[18]); + qlo_Vbex=qlo_xvar3*xvar3_Vbex; + xvar1=(1.0-p[14]); + xvar2=(-p[18]); + xvar3=pow(xvar1,xvar2); + qdbex=qlo+xvar3*((*Vbex)-vl+vl0)-q0; + qdbex_qlo=1.0; + qdbex_Vbex=xvar3; + qdbex_vl=-xvar3; + qdbex_Vbex=qdbex_Vbex+qdbex_qlo*qlo_Vbex; + qdbex_Vbex=qdbex_Vbex+qdbex_vl*vl_Vbex; + } + dv0=-p[24]*p[14]; + if(p[26]<=0.0){ + dvh=(*Vbci)+dv0; + dvh_Vbci=1.0; + if(dvh>0.0){ + xvar1=(1.0-p[14]); + xvar2=(-1.0-p[25]); + pwq=pow(xvar1,xvar2); + qlo=p[24]*(1.0-pwq*(1.0-p[14])*(1.0-p[14]))/(1.0-p[25]); + qlo_Vbci=0.0; + qhi=dvh*(1.0-p[14]+0.5*p[25]*dvh/p[24])*pwq; + qhi_dvh=(0.5*dvh*p[25]/p[24]-p[14]+1.0)*pwq+0.5*dvh*p[25]*pwq/p[24]; + qhi_Vbci=qhi_dvh*dvh_Vbci; + }else{ + if((p[85]>0.0)&&((*Vbci)<-p[85])){ + xvar1=(1.0+p[85]/p[24]); + xvar2=(1.0-p[25]); + xvar3=pow(xvar1,xvar2); + qlo=p[24]*(1.0-xvar3*(1.0-((1.0-p[25])*((*Vbci)+p[85]))/(p[24]+p[85])))/(1.0-p[25]); + qlo_Vbci=p[24]*xvar3/(p[85]+p[24]); + }else{ + xvar1=(1.0-(*Vbci)/p[24]); + xvar1_Vbci=-1.0/p[24]; + xvar2=(1.0-p[25]); + xvar3=pow(xvar1,xvar2); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vbci=xvar3_xvar1*xvar1_Vbci; + qlo=p[24]*(1.0-xvar3)/(1.0-p[25]); + qlo_xvar3=-p[24]/(1.0-p[25]); + qlo_Vbci=qlo_xvar3*xvar3_Vbci; + } + qhi=0.0; + qhi_Vbci=0.0; + } + qdbc=qlo+qhi; + qdbc_qlo=1.0; + qdbc_qhi=1.0; + qdbc_Vbci=qdbc_qlo*qlo_Vbci; + qdbc_Vbci=qdbc_Vbci+qdbc_qhi*qhi_Vbci; + }else{ + if((p[85]>0.0)&&(p[86]>0.0)){ + vn0=(p[85]+dv0)/(p[85]-dv0); + vnl0=2.0*vn0/(sqrt((vn0-1.0)*(vn0-1.0)+4.0*p[26]*p[26])+sqrt((vn0+1.0)*(vn0+1.0)+4.0*p[86]*p[86])); + vl0=0.5*(vnl0*(p[85]-dv0)-p[85]-dv0); + xvar1=(1.0-vl0/p[24]); + xvar2=(1.0-p[25]); + xvar3=pow(xvar1,xvar2); + qlo0=p[24]*(1.0-xvar3)/(1.0-p[25]); + vn=(2.0*(*Vbci)+p[85]+dv0)/(p[85]-dv0); + vn_Vbci=2.0/(p[85]-dv0); + vnl=2.0*vn/(sqrt((vn-1.0)*(vn-1.0)+4.0*p[26]*p[26])+sqrt((vn+1.0)*(vn+1.0)+4.0*p[86]*p[86])); + vnl_vn=2.0/(sqrt(((vn+1.0)*(vn+1.0))+4.0*(p[86]*p[86]))+sqrt(((vn-1.0)*(vn-1.0))+4.0*(p[26]*p[26])))-2.0*vn*((vn+1.0)/sqrt(((vn+1.0)*(vn+1.0))+4.0*(p[86]*p[86]))+(vn-1.0)/sqrt(((vn-1.0)*(vn-1.0))+4.0*(p[26]*p[26])))/((sqrt(((vn+1.0)*(vn+1.0))+4.0*(p[86]*p[86]))+sqrt(((vn-1.0)*(vn-1.0))+4.0*(p[26]*p[26])))*(sqrt(((vn+1.0)*(vn+1.0))+4.0*(p[86]*p[86]))+sqrt(((vn-1.0)*(vn-1.0))+4.0*(p[26]*p[26])))); + vnl_Vbci=vnl_vn*vn_Vbci; + vl=0.5*(vnl*(p[85]-dv0)-p[85]-dv0); + vl_vnl=0.5*(p[85]-dv0); + vl_Vbci=vl_vnl*vnl_Vbci; + xvar1=(1.0-vl/p[24]); + xvar1_vl=-1.0/p[24]; + xvar1_Vbci=xvar1_vl*vl_Vbci; + xvar2=(1.0-p[25]); + xvar3=pow(xvar1,xvar2); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vbci=xvar3_xvar1*xvar1_Vbci; + qlo=p[24]*(1.0-xvar3)/(1.0-p[25]); + qlo_xvar3=-p[24]/(1.0-p[25]); + qlo_Vbci=qlo_xvar3*xvar3_Vbci; + sel=0.5*(vnl+1.0); + sel_vnl=0.5; + sel_Vbci=sel_vnl*vnl_Vbci; + xvar1=(1.0+p[85]/p[24]); + xvar2=(-p[25]); + crt=pow(xvar1,xvar2); + xvar1=(1.0+dv0/p[24]); + xvar2=(-p[25]); + cmx=pow(xvar1,xvar2); + cl=(1.0-sel)*crt+sel*cmx; + cl_sel=cmx-crt; + cl_Vbci=cl_sel*sel_Vbci; + ql=((*Vbci)-vl+vl0)*cl; + ql_Vbci=cl; + ql_vl=-cl; + ql_cl=vl0-vl+(*Vbci); + ql_Vbci=ql_Vbci+ql_vl*vl_Vbci; + ql_Vbci=ql_Vbci+ql_cl*cl_Vbci; + qdbc=ql+qlo-qlo0; + qdbc_ql=1.0; + qdbc_qlo=1.0; + qdbc_Vbci=qdbc_ql*ql_Vbci; + qdbc_Vbci=qdbc_Vbci+qdbc_qlo*qlo_Vbci; + }else{ + mv0=sqrt(dv0*dv0+4.0*p[26]*p[26]); + vl0=-0.5*(dv0+mv0); + xvar1=(1.0-vl0/p[24]); + xvar2=(1.0-p[25]); + xvar3=pow(xvar1,xvar2); + q0=-p[24]*xvar3/(1.0-p[25]); + dv=(*Vbci)+dv0; + dv_Vbci=1.0; + mv=sqrt(dv*dv+4.0*p[26]*p[26]); + mv_dv=dv/sqrt((dv*dv)+4.0*(p[26]*p[26])); + mv_Vbci=mv_dv*dv_Vbci; + vl=0.5*(dv-mv)-dv0; + vl_dv=0.5; + vl_mv=-0.5; + vl_Vbci=vl_dv*dv_Vbci; + vl_Vbci=vl_Vbci+vl_mv*mv_Vbci; + xvar1=(1.0-vl/p[24]); + xvar1_vl=-1.0/p[24]; + xvar1_Vbci=xvar1_vl*vl_Vbci; + xvar2=(1.0-p[25]); + xvar3=pow(xvar1,xvar2); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vbci=xvar3_xvar1*xvar1_Vbci; + qlo=-p[24]*xvar3/(1.0-p[25]); + qlo_xvar3=-p[24]/(1.0-p[25]); + qlo_Vbci=qlo_xvar3*xvar3_Vbci; + xvar1=(1.0-p[14]); + xvar2=(-p[25]); + xvar3=pow(xvar1,xvar2); + qdbc=qlo+xvar3*((*Vbci)-vl+vl0)-q0; + qdbc_qlo=1.0; + qdbc_Vbci=xvar3; + qdbc_vl=-xvar3; + qdbc_Vbci=qdbc_Vbci+qdbc_qlo*qlo_Vbci; + qdbc_Vbci=qdbc_Vbci+qdbc_vl*vl_Vbci; + } + } + dv0=-p[24]*p[14]; + if(p[26]<=0.0){ + dvh=(*Vbep)+dv0; + dvh_Vbep=1.0; + if(dvh>0.0){ + xvar1=(1.0-p[14]); + xvar2=(-1.0-p[25]); + pwq=pow(xvar1,xvar2); + qlo=p[24]*(1.0-pwq*(1.0-p[14])*(1.0-p[14]))/(1.0-p[25]); + qlo_Vbep=0.0; + qhi=dvh*(1.0-p[14]+0.5*p[25]*dvh/p[24])*pwq; + qhi_dvh=(0.5*dvh*p[25]/p[24]-p[14]+1.0)*pwq+0.5*dvh*p[25]*pwq/p[24]; + qhi_Vbep=qhi_dvh*dvh_Vbep; + }else{ + if((p[85]>0.0)&&((*Vbep)<-p[85])){ + xvar1=(1.0+p[85]/p[24]); + xvar2=(1.0-p[25]); + xvar3=pow(xvar1,xvar2); + qlo=p[24]*(1.0-xvar3*(1.0-((1.0-p[25])*((*Vbep)+p[85]))/(p[24]+p[85])))/(1.0-p[25]); + qlo_Vbep=p[24]*xvar3/(p[85]+p[24]); + }else{ + xvar1=(1.0-(*Vbep)/p[24]); + xvar1_Vbep=-1.0/p[24]; + xvar2=(1.0-p[25]); + xvar3=pow(xvar1,xvar2); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vbep=xvar3_xvar1*xvar1_Vbep; + qlo=p[24]*(1.0-xvar3)/(1.0-p[25]); + qlo_xvar3=-p[24]/(1.0-p[25]); + qlo_Vbep=qlo_xvar3*xvar3_Vbep; + } + qhi=0.0; + qhi_Vbep=0.0; + } + qdbep=qlo+qhi; + qdbep_qlo=1.0; + qdbep_qhi=1.0; + qdbep_Vbep=qdbep_qlo*qlo_Vbep; + qdbep_Vbep=qdbep_Vbep+qdbep_qhi*qhi_Vbep; + }else{ + if((p[85]>0.0)&&(p[86]>0.0)){ + vn0=(p[85]+dv0)/(p[85]-dv0); + vnl0=2.0*vn0/(sqrt((vn0-1.0)*(vn0-1.0)+4.0*p[26]*p[26])+sqrt((vn0+1.0)*(vn0+1.0)+4.0*p[86]*p[86])); + vl0=0.5*(vnl0*(p[85]-dv0)-p[85]-dv0); + xvar1=(1.0-vl0/p[24]); + xvar2=(1.0-p[25]); + xvar3=pow(xvar1,xvar2); + qlo0=p[24]*(1.0-xvar3)/(1.0-p[25]); + vn=(2.0*(*Vbep)+p[85]+dv0)/(p[85]-dv0); + vn_Vbep=2.0/(p[85]-dv0); + vnl=2.0*vn/(sqrt((vn-1.0)*(vn-1.0)+4.0*p[26]*p[26])+sqrt((vn+1.0)*(vn+1.0)+4.0*p[86]*p[86])); + vnl_vn=2.0/(sqrt(((vn+1.0)*(vn+1.0))+4.0*(p[86]*p[86]))+sqrt(((vn-1.0)*(vn-1.0))+4.0*(p[26]*p[26])))-2.0*vn*((vn+1.0)/sqrt(((vn+1.0)*(vn+1.0))+4.0*(p[86]*p[86]))+(vn-1.0)/sqrt(((vn-1.0)*(vn-1.0))+4.0*(p[26]*p[26])))/((sqrt(((vn+1.0)*(vn+1.0))+4.0*(p[86]*p[86]))+sqrt(((vn-1.0)*(vn-1.0))+4.0*(p[26]*p[26])))*(sqrt(((vn+1.0)*(vn+1.0))+4.0*(p[86]*p[86]))+sqrt(((vn-1.0)*(vn-1.0))+4.0*(p[26]*p[26])))); + vnl_Vbep=vnl_vn*vn_Vbep; + vl=0.5*(vnl*(p[85]-dv0)-p[85]-dv0); + vl_vnl=0.5*(p[85]-dv0); + vl_Vbep=vl_vnl*vnl_Vbep; + xvar1=(1.0-vl/p[24]); + xvar1_vl=-1.0/p[24]; + xvar1_Vbep=xvar1_vl*vl_Vbep; + xvar2=(1.0-p[25]); + xvar3=pow(xvar1,xvar2); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vbep=xvar3_xvar1*xvar1_Vbep; + qlo=p[24]*(1.0-xvar3)/(1.0-p[25]); + qlo_xvar3=-p[24]/(1.0-p[25]); + qlo_Vbep=qlo_xvar3*xvar3_Vbep; + sel=0.5*(vnl+1.0); + sel_vnl=0.5; + sel_Vbep=sel_vnl*vnl_Vbep; + xvar1=(1.0+p[85]/p[24]); + xvar2=(-p[25]); + crt=pow(xvar1,xvar2); + xvar1=(1.0+dv0/p[24]); + xvar2=(-p[25]); + cmx=pow(xvar1,xvar2); + cl=(1.0-sel)*crt+sel*cmx; + cl_sel=cmx-crt; + cl_Vbep=cl_sel*sel_Vbep; + ql=((*Vbep)-vl+vl0)*cl; + ql_Vbep=cl; + ql_vl=-cl; + ql_cl=vl0-vl+(*Vbep); + ql_Vbep=ql_Vbep+ql_vl*vl_Vbep; + ql_Vbep=ql_Vbep+ql_cl*cl_Vbep; + qdbep=ql+qlo-qlo0; + qdbep_ql=1.0; + qdbep_qlo=1.0; + qdbep_Vbep=qdbep_ql*ql_Vbep; + qdbep_Vbep=qdbep_Vbep+qdbep_qlo*qlo_Vbep; + }else{ + mv0=sqrt(dv0*dv0+4.0*p[26]*p[26]); + vl0=-0.5*(dv0+mv0); + xvar1=(1.0-vl0/p[24]); + xvar2=(1.0-p[25]); + xvar3=pow(xvar1,xvar2); + q0=-p[24]*xvar3/(1.0-p[25]); + dv=(*Vbep)+dv0; + dv_Vbep=1.0; + mv=sqrt(dv*dv+4.0*p[26]*p[26]); + mv_dv=dv/sqrt((dv*dv)+4.0*(p[26]*p[26])); + mv_Vbep=mv_dv*dv_Vbep; + vl=0.5*(dv-mv)-dv0; + vl_dv=0.5; + vl_mv=-0.5; + vl_Vbep=vl_dv*dv_Vbep; + vl_Vbep=vl_Vbep+vl_mv*mv_Vbep; + xvar1=(1.0-vl/p[24]); + xvar1_vl=-1.0/p[24]; + xvar1_Vbep=xvar1_vl*vl_Vbep; + xvar2=(1.0-p[25]); + xvar3=pow(xvar1,xvar2); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vbep=xvar3_xvar1*xvar1_Vbep; + qlo=-p[24]*xvar3/(1.0-p[25]); + qlo_xvar3=-p[24]/(1.0-p[25]); + qlo_Vbep=qlo_xvar3*xvar3_Vbep; + xvar1=(1.0-p[14]); + xvar2=(-p[25]); + xvar3=pow(xvar1,xvar2); + qdbep=qlo+xvar3*((*Vbep)-vl+vl0)-q0; + qdbep_qlo=1.0; + qdbep_Vbep=xvar3; + qdbep_vl=-xvar3; + qdbep_Vbep=qdbep_Vbep+qdbep_qlo*qlo_Vbep; + qdbep_Vbep=qdbep_Vbep+qdbep_vl*vl_Vbep; + } + } + argi=(*Vbei)/(p[12]*Vtv); + argi_Vbei=1.0/(p[12]*Vtv); + expi=exp(argi); + expi_argi=expi; + expi_Vbei=expi_argi*argi_Vbei; + Ifi=p[11]*(expi-1.0); + Ifi_expi=p[11]; + Ifi_Vbei=Ifi_expi*expi_Vbei; + argi=(*Vbci)/(p[13]*Vtv); + argi_Vbci=1.0/(p[13]*Vtv); + expi=exp(argi); + expi_argi=expi; + expi_Vbci=expi_argi*argi_Vbci; + Iri=p[11]*p[94]*(expi-1.0); + Iri_expi=p[11]*p[94]; + Iri_Vbci=Iri_expi*expi_Vbci; + q1z=1.0+qdbe*IVER+qdbc*IVEF; + q1z_qdbe=IVER; + q1z_qdbc=IVEF; + q1z_Vbei=q1z_qdbe*qdbe_Vbei; + q1z_Vbci=q1z_qdbc*qdbc_Vbci; + q1=0.5*(sqrt((q1z-1.0e-4)*(q1z-1.0e-4)+1.0e-8)+q1z-1.0e-4)+1.0e-4; + q1_q1z=0.5*((q1z-1.0e-4)/sqrt(((q1z-1.0e-4)*(q1z-1.0e-4))+1.0e-8)+1.0); + q1_Vbei=q1_q1z*q1z_Vbei; + q1_Vbci=q1_q1z*q1z_Vbci; + q2=Ifi*IIKF+Iri*IIKR; + q2_Ifi=IIKF; + q2_Iri=IIKR; + q2_Vbei=q2_Ifi*Ifi_Vbei; + q2_Vbci=q2_Iri*Iri_Vbci; + if(p[88]<0.5){ + xvar2=1.0/p[89]; + xvar3=pow(q1,xvar2); + xvar3_q1=xvar3*xvar2/q1; + xvar3_Vbei=xvar3_q1*q1_Vbei; + xvar3_Vbci=xvar3_q1*q1_Vbci; + xvar1=(xvar3+4.0*q2); + xvar1_xvar3=1.0; + xvar1_q2=4.0; + xvar1_Vbei=xvar1_xvar3*xvar3_Vbei; + xvar1_Vbci=xvar1_xvar3*xvar3_Vbci; + xvar1_Vbei=xvar1_Vbei+xvar1_q2*q2_Vbei; + xvar1_Vbci=xvar1_Vbci+xvar1_q2*q2_Vbci; + xvar4=pow(xvar1,p[89]); + xvar4_xvar1=xvar4*p[89]/xvar1; + xvar4_Vbei=xvar4_xvar1*xvar1_Vbei; + xvar4_Vbci=xvar4_xvar1*xvar1_Vbci; + qb=0.5*(q1+xvar4); + qb_q1=0.5; + qb_xvar4=0.5; + qb_Vbei=qb_q1*q1_Vbei; + qb_Vbci=qb_q1*q1_Vbci; + qb_Vbei=qb_Vbei+qb_xvar4*xvar4_Vbei; + qb_Vbci=qb_Vbci+qb_xvar4*xvar4_Vbci; + }else{ + xvar1=(1.0+4.0*q2); + xvar1_q2=4.0; + xvar1_Vbei=xvar1_q2*q2_Vbei; + xvar1_Vbci=xvar1_q2*q2_Vbci; + xvar2=pow(xvar1,p[89]); + xvar2_xvar1=xvar2*p[89]/xvar1; + xvar2_Vbei=xvar2_xvar1*xvar1_Vbei; + xvar2_Vbci=xvar2_xvar1*xvar1_Vbci; + qb=0.5*q1*(1.0+xvar2); + qb_q1=0.5*(xvar2+1.0); + qb_xvar2=0.5*q1; + qb_Vbei=qb_q1*q1_Vbei; + qb_Vbci=qb_q1*q1_Vbci; + qb_Vbei=qb_Vbei+qb_xvar2*xvar2_Vbei; + qb_Vbci=qb_Vbci+qb_xvar2*xvar2_Vbci; + } + (*Itzr)=Iri/qb; + Itzr_Iri=1.0/qb; + Itzr_qb=-Iri/(qb*qb); + *Itzr_Vbci=Itzr_Iri*Iri_Vbci; + *Itzr_Vbei=Itzr_qb*qb_Vbei; + *Itzr_Vbci=(*Itzr_Vbci)+Itzr_qb*qb_Vbci; + (*Itzf)=Ifi/qb; + Itzf_Ifi=1.0/qb; + Itzf_qb=-Ifi/(qb*qb); + *Itzf_Vbei=Itzf_Ifi*Ifi_Vbei; + *Itzf_Vbei=(*Itzf_Vbei)+Itzf_qb*qb_Vbei; + *Itzf_Vbci=Itzf_qb*qb_Vbci; + if(p[42]>0.0){ + argi=(*Vbep)/(p[44]*Vtv); + argi_Vbep=1.0/(p[44]*Vtv); + expi=exp(argi); + expi_argi=expi; + expi_Vbep=expi_argi*argi_Vbep; + argx=(*Vbci)/(p[44]*Vtv); + argx_Vbci=1.0/(p[44]*Vtv); + expx=exp(argx); + expx_argx=expx; + expx_Vbci=expx_argx*argx_Vbci; + Ifp=p[42]*(p[43]*expi+(1.0-p[43])*expx-1.0); + Ifp_expi=p[42]*p[43]; + Ifp_expx=p[42]*(1.0-p[43]); + Ifp_Vbep=Ifp_expi*expi_Vbep; + Ifp_Vbci=Ifp_expx*expx_Vbci; + q2p=Ifp*IIKP; + q2p_Ifp=IIKP; + q2p_Vbep=q2p_Ifp*Ifp_Vbep; + q2p_Vbci=q2p_Ifp*Ifp_Vbci; + qbp=0.5*(1.0+sqrt(1.0+4.0*q2p)); + qbp_q2p=1.0/sqrt(4.0*q2p+1.0); + qbp_Vbep=qbp_q2p*q2p_Vbep; + qbp_Vbci=qbp_q2p*q2p_Vbci; + }else{ + Ifp=0.0; + Ifp_Vbep=0.0; + Ifp_Vbci=0.0; + qbp=1.0; + qbp_Vbep=0.0; + qbp_Vbci=0.0; + } + if(p[32]==1.0){ + argi=(*Vbei)/(p[33]*Vtv); + argi_Vbei=1.0/(p[33]*Vtv); + expi=exp(argi); + expi_argi=expi; + expi_Vbei=expi_argi*argi_Vbei; + argn=(*Vbei)/(p[35]*Vtv); + argn_Vbei=1.0/(p[35]*Vtv); + expn=exp(argn); + expn_argn=expn; + expn_Vbei=expn_argn*argn_Vbei; + if(p[98]>0.0){ + argx=(-p[98]-(*Vbei))/(p[99]*Vtv); + argx_Vbei=-1.0/(p[99]*Vtv); + expx=exp(argx); + expx_argx=expx; + expx_Vbei=expx_argx*argx_Vbei; + (*Ibe)=p[31]*(expi-1.0)+p[34]*(expn-1.0)-p[100]*(expx-p[104]); + Ibe_expi=p[31]; + Ibe_expn=p[34]; + Ibe_expx=-p[100]; + *Ibe_Vbei=Ibe_expi*expi_Vbei; + *Ibe_Vbei=(*Ibe_Vbei)+Ibe_expn*expn_Vbei; + *Ibe_Vbei=(*Ibe_Vbei)+Ibe_expx*expx_Vbei; + }else{ + (*Ibe)=p[31]*(expi-1.0)+p[34]*(expn-1.0); + Ibe_expi=p[31]; + Ibe_expn=p[34]; + *Ibe_Vbei=Ibe_expi*expi_Vbei; + *Ibe_Vbei=(*Ibe_Vbei)+Ibe_expn*expn_Vbei; + } + (*Ibex)=0.0; + *Ibex_Vbex=0.0; + }else if(p[32]==0.0){ + (*Ibe)=0.0; + *Ibe_Vbei=0.0; + argi=(*Vbex)/(p[33]*Vtv); + argi_Vbex=1.0/(p[33]*Vtv); + expi=exp(argi); + expi_argi=expi; + expi_Vbex=expi_argi*argi_Vbex; + argn=(*Vbex)/(p[35]*Vtv); + argn_Vbex=1.0/(p[35]*Vtv); + expn=exp(argn); + expn_argn=expn; + expn_Vbex=expn_argn*argn_Vbex; + if(p[98]>0.0){ + argx=(-p[98]-(*Vbex))/(p[99]*Vtv); + argx_Vbex=-1.0/(p[99]*Vtv); + expx=exp(argx); + expx_argx=expx; + expx_Vbex=expx_argx*argx_Vbex; + (*Ibex)=p[31]*(expi-1.0)+p[34]*(expn-1.0)-p[100]*(expx-p[104]); + Ibex_expi=p[31]; + Ibex_expn=p[34]; + Ibex_expx=-p[100]; + *Ibex_Vbex=Ibex_expi*expi_Vbex; + *Ibex_Vbex=(*Ibex_Vbex)+Ibex_expn*expn_Vbex; + *Ibex_Vbex=(*Ibex_Vbex)+Ibex_expx*expx_Vbex; + }else{ + (*Ibex)=p[31]*(expi-1.0)+p[34]*(expn-1.0); + Ibex_expi=p[31]; + Ibex_expn=p[34]; + *Ibex_Vbex=Ibex_expi*expi_Vbex; + *Ibex_Vbex=(*Ibex_Vbex)+Ibex_expn*expn_Vbex; + } + }else{ + argi=(*Vbei)/(p[33]*Vtv); + argi_Vbei=1.0/(p[33]*Vtv); + expi=exp(argi); + expi_argi=expi; + expi_Vbei=expi_argi*argi_Vbei; + argn=(*Vbei)/(p[35]*Vtv); + argn_Vbei=1.0/(p[35]*Vtv); + expn=exp(argn); + expn_argn=expn; + expn_Vbei=expn_argn*argn_Vbei; + if(p[98]>0.0){ + argx=(-p[98]-(*Vbei))/(p[99]*Vtv); + argx_Vbei=-1.0/(p[99]*Vtv); + expx=exp(argx); + expx_argx=expx; + expx_Vbei=expx_argx*argx_Vbei; + (*Ibe)=p[32]*(p[31]*(expi-1.0)+p[34]*(expn-1.0)-p[100]*(expx-p[104])); + Ibe_expi=p[31]*p[32]; + Ibe_expn=p[34]*p[32]; + Ibe_expx=-p[100]*p[32]; + *Ibe_Vbei=Ibe_expi*expi_Vbei; + *Ibe_Vbei=(*Ibe_Vbei)+Ibe_expn*expn_Vbei; + *Ibe_Vbei=(*Ibe_Vbei)+Ibe_expx*expx_Vbei; + }else{ + (*Ibe)=p[32]*(p[31]*(expi-1.0)+p[34]*(expn-1.0)); + Ibe_expi=p[31]*p[32]; + Ibe_expn=p[34]*p[32]; + *Ibe_Vbei=Ibe_expi*expi_Vbei; + *Ibe_Vbei=(*Ibe_Vbei)+Ibe_expn*expn_Vbei; + } + argi=(*Vbex)/(p[33]*Vtv); + argi_Vbex=1.0/(p[33]*Vtv); + expi=exp(argi); + expi_argi=expi; + expi_Vbex=expi_argi*argi_Vbex; + argn=(*Vbex)/(p[35]*Vtv); + argn_Vbex=1.0/(p[35]*Vtv); + expn=exp(argn); + expn_argn=expn; + expn_Vbex=expn_argn*argn_Vbex; + if(p[98]>0.0){ + argx=(-p[98]-(*Vbex))/(p[99]*Vtv); + argx_Vbex=-1.0/(p[99]*Vtv); + expx=exp(argx); + expx_argx=expx; + expx_Vbex=expx_argx*argx_Vbex; + (*Ibex)=(1.0-p[32])*(p[31]*(expi-1.0)+p[34]*(expn-1.0)-p[100]*(expx-p[104])); + Ibex_expi=p[31]*(1.0-p[32]); + Ibex_expn=p[34]*(1.0-p[32]); + Ibex_expx=-p[100]*(1.0-p[32]); + *Ibex_Vbex=Ibex_expi*expi_Vbex; + *Ibex_Vbex=(*Ibex_Vbex)+Ibex_expn*expn_Vbex; + *Ibex_Vbex=(*Ibex_Vbex)+Ibex_expx*expx_Vbex; + }else{ + (*Ibex)=(1.0-p[32])*(p[31]*(expi-1.0)+p[34]*(expn-1.0)); + Ibex_expi=p[31]*(1.0-p[32]); + Ibex_expn=p[34]*(1.0-p[32]); + *Ibex_Vbex=Ibex_expi*expi_Vbex; + *Ibex_Vbex=(*Ibex_Vbex)+Ibex_expn*expn_Vbex; + } + } + argi=(*Vbci)/(p[37]*Vtv); + argi_Vbci=1.0/(p[37]*Vtv); + expi=exp(argi); + expi_argi=expi; + expi_Vbci=expi_argi*argi_Vbci; + argn=(*Vbci)/(p[39]*Vtv); + argn_Vbci=1.0/(p[39]*Vtv); + expn=exp(argn); + expn_argn=expn; + expn_Vbci=expn_argn*argn_Vbci; + Ibcj=p[36]*(expi-1.0)+p[38]*(expn-1.0); + Ibcj_expi=p[36]; + Ibcj_expn=p[38]; + Ibcj_Vbci=Ibcj_expi*expi_Vbci; + Ibcj_Vbci=Ibcj_Vbci+Ibcj_expn*expn_Vbci; + if((p[45]>0.0)||(p[46]>0.0)){ + argi=(*Vbep)/(p[37]*Vtv); + argi_Vbep=1.0/(p[37]*Vtv); + expi=exp(argi); + expi_argi=expi; + expi_Vbep=expi_argi*argi_Vbep; + argn=(*Vbep)/(p[39]*Vtv); + argn_Vbep=1.0/(p[39]*Vtv); + expn=exp(argn); + expn_argn=expn; + expn_Vbep=expn_argn*argn_Vbep; + (*Ibep)=p[45]*(expi-1.0)+p[46]*(expn-1.0); + Ibep_expi=p[45]; + Ibep_expn=p[46]; + *Ibep_Vbep=Ibep_expi*expi_Vbep; + *Ibep_Vbep=(*Ibep_Vbep)+Ibep_expn*expn_Vbep; + }else{ + (*Ibep)=0.0; + *Ibep_Vbep=0.0; + } + if(p[40]>0.0){ + vl=0.5*(sqrt((p[24]-(*Vbci))*(p[24]-(*Vbci))+0.01)+(p[24]-(*Vbci))); + vl_Vbci=0.5*(-(p[24]-(*Vbci))/sqrt(((p[24]-(*Vbci))*(p[24]-(*Vbci)))+0.01)-1.0); + xvar2=(p[25]-1.0); + xvar3=pow(vl,xvar2); + xvar3_vl=xvar3*xvar2/vl; + xvar3_Vbci=xvar3_vl*vl_Vbci; + xvar1=-p[41]*xvar3; + xvar1_xvar3=-p[41]; + xvar1_Vbci=xvar1_xvar3*xvar3_Vbci; + xvar4=exp(xvar1); + xvar4_xvar1=xvar4; + xvar4_Vbci=xvar4_xvar1*xvar1_Vbci; + avalf=p[40]*vl*xvar4; + avalf_vl=p[40]*xvar4; + avalf_xvar4=p[40]*vl; + avalf_Vbci=avalf_vl*vl_Vbci; + avalf_Vbci=avalf_Vbci+avalf_xvar4*xvar4_Vbci; + Igc=((*Itzf)-(*Itzr)-Ibcj)*avalf; + Igc_Itzf=avalf; + Igc_Itzr=-avalf; + Igc_Ibcj=-avalf; + Igc_avalf=-(*Itzr)+(*Itzf)-Ibcj; + Igc_Vbei=Igc_Itzf*(*Itzf_Vbei); + Igc_Vbci=Igc_Itzf*(*Itzf_Vbci); + Igc_Vbci=Igc_Vbci+Igc_Itzr*(*Itzr_Vbci); + Igc_Vbei=Igc_Vbei+Igc_Itzr*(*Itzr_Vbei); + Igc_Vbci=Igc_Vbci+Igc_Ibcj*Ibcj_Vbci; + Igc_Vbci=Igc_Vbci+Igc_avalf*avalf_Vbci; + }else{ + Igc=0.0; + Igc_Vbei=0.0; + Igc_Vbci=0.0; + } + (*Ibc)=Ibcj-Igc; + Ibc_Ibcj=1.0; + Ibc_Igc=-1.0; + *Ibc_Vbci=Ibc_Ibcj*Ibcj_Vbci; + *Ibc_Vbei=Ibc_Igc*Igc_Vbei; + *Ibc_Vbci=(*Ibc_Vbci)+Ibc_Igc*Igc_Vbci; + if(p[1]>0.0){ + (*Ircx)=(*Vrcx)/p[1]; + *Ircx_Vrcx=1.0/p[1]; + }else{ + (*Ircx)=0.0; + *Ircx_Vrcx=0.0; + } + argi=(*Vbci)/Vtv; + argi_Vbci=1.0/Vtv; + expi=exp(argi); + expi_argi=expi; + expi_Vbci=expi_argi*argi_Vbci; + argx=(*Vbcx)/Vtv; + argx_Vbcx=1.0/Vtv; + expx=exp(argx); + expx_argx=expx; + expx_Vbcx=expx_argx*argx_Vbcx; + Kbci=sqrt(1.0+p[4]*expi); + Kbci_expi=p[4]/(2.0*sqrt(expi*p[4]+1.0)); + Kbci_Vbci=Kbci_expi*expi_Vbci; + Kbcx=sqrt(1.0+p[4]*expx); + Kbcx_expx=p[4]/(2.0*sqrt(expx*p[4]+1.0)); + Kbcx_Vbcx=Kbcx_expx*expx_Vbcx; + if(p[2]>0.0){ + rKp1=(Kbci+1.0)/(Kbcx+1.0); + rKp1_Kbci=1.0/(Kbcx+1.0); + rKp1_Kbcx=-(Kbci+1.0)/((Kbcx+1.0)*(Kbcx+1.0)); + rKp1_Vbci=rKp1_Kbci*Kbci_Vbci; + rKp1_Vbcx=rKp1_Kbcx*Kbcx_Vbcx; + xvar1=log(rKp1); + xvar1_rKp1=1.0/rKp1; + xvar1_Vbci=xvar1_rKp1*rKp1_Vbci; + xvar1_Vbcx=xvar1_rKp1*rKp1_Vbcx; + Iohm=((*Vrci)+Vtv*(Kbci-Kbcx-xvar1))/p[2]; + Iohm_Vrci=1.0/p[2]; + Iohm_Kbci=Vtv/p[2]; + Iohm_Kbcx=-Vtv/p[2]; + Iohm_xvar1=-Vtv/p[2]; + Iohm_Vbci=Iohm_Kbci*Kbci_Vbci; + Iohm_Vbcx=Iohm_Kbcx*Kbcx_Vbcx; + Iohm_Vbci=Iohm_Vbci+Iohm_xvar1*xvar1_Vbci; + Iohm_Vbcx=Iohm_Vbcx+Iohm_xvar1*xvar1_Vbcx; + derf=IVO*p[2]*Iohm/(1.0+0.5*IVO*IHRCF*sqrt((*Vrci)*(*Vrci)+0.01)); + derf_Iohm=IVO*p[2]/(0.5*IHRCF*IVO*sqrt(((*Vrci)*(*Vrci))+0.01)+1.0); + derf_Vrci=-0.5*IHRCF*Iohm*(IVO*IVO)*p[2]*(*Vrci)/(sqrt(((*Vrci)*(*Vrci))+0.01)*((0.5*IHRCF*IVO*sqrt(((*Vrci)*(*Vrci))+0.01)+1.0)*(0.5*IHRCF*IVO*sqrt(((*Vrci)*(*Vrci))+0.01)+1.0))); + derf_Vrci=derf_Vrci+derf_Iohm*Iohm_Vrci; + derf_Vbci=derf_Iohm*Iohm_Vbci; + derf_Vbcx=derf_Iohm*Iohm_Vbcx; + (*Irci)=Iohm/sqrt(1.0+derf*derf); + Irci_Iohm=1.0/sqrt((derf*derf)+1.0); + Irci_derf=-derf*Iohm/pow(((derf*derf)+1.0),(3.0/2.0)); + *Irci_Vrci=Irci_Iohm*Iohm_Vrci; + *Irci_Vbci=Irci_Iohm*Iohm_Vbci; + *Irci_Vbcx=Irci_Iohm*Iohm_Vbcx; + *Irci_Vrci=(*Irci_Vrci)+Irci_derf*derf_Vrci; + *Irci_Vbci=(*Irci_Vbci)+Irci_derf*derf_Vbci; + *Irci_Vbcx=(*Irci_Vbcx)+Irci_derf*derf_Vbcx; + }else{ + (*Irci)=0.0; + *Irci_Vrci=0.0; + *Irci_Vbci=0.0; + *Irci_Vbcx=0.0; + } + if(p[6]>0.0){ + (*Irbx)=(*Vrbx)/p[6]; + *Irbx_Vrbx=1.0/p[6]; + }else{ + (*Irbx)=0.0; + *Irbx_Vrbx=0.0; + } + if(p[7]>0.0){ + (*Irbi)=(*Vrbi)*qb/p[7]; + *Irbi_Vrbi=qb/p[7]; + Irbi_qb=(*Vrbi)/p[7]; + *Irbi_Vbei=Irbi_qb*qb_Vbei; + *Irbi_Vbci=Irbi_qb*qb_Vbci; + }else{ + (*Irbi)=0.0; + *Irbi_Vrbi=0.0; + *Irbi_Vbei=0.0; + *Irbi_Vbci=0.0; + } + if(p[8]>0.0){ + (*Ire)=(*Vre)/p[8]; + *Ire_Vre=1.0/p[8]; + }else{ + (*Ire)=0.0; + *Ire_Vre=0.0; + } + if(p[10]>0.0){ + (*Irbp)=(*Vrbp)*qbp/p[10]; + *Irbp_Vrbp=qbp/p[10]; + Irbp_qbp=(*Vrbp)/p[10]; + *Irbp_Vbep=Irbp_qbp*qbp_Vbep; + *Irbp_Vbci=Irbp_qbp*qbp_Vbci; + }else{ + (*Irbp)=0.0; + *Irbp_Vrbp=0.0; + *Irbp_Vbep=0.0; + *Irbp_Vbci=0.0; + } + if(Ifi>0.0){ + sgIf=1.0; + }else{ + sgIf=0.0; + } + rIf=Ifi*sgIf*IITF; + rIf_Ifi=IITF*sgIf; + rIf_Vbei=rIf_Ifi*Ifi_Vbei; + mIf=rIf/(rIf+1.0); + mIf_rIf=1.0/(rIf+1.0)-rIf/((rIf+1.0)*(rIf+1.0)); + mIf_Vbei=mIf_rIf*rIf_Vbei; + xvar1=(*Vbci)*IVTF/1.44; + xvar1_Vbci=0.6944444*IVTF; + xvar2=exp(xvar1); + xvar2_xvar1=xvar2; + xvar2_Vbci=xvar2_xvar1*xvar1_Vbci; + tff=p[56]*(1.0+p[57]*q1)*(1.0+p[58]*xvar2*(slTF+mIf*mIf)*sgIf); + tff_q1=p[57]*p[56]*(sgIf*(slTF+(mIf*mIf))*p[58]*xvar2+1.0); + tff_xvar2=(q1*p[57]+1.0)*sgIf*(slTF+(mIf*mIf))*p[56]*p[58]; + tff_mIf=2.0*mIf*(q1*p[57]+1.0)*sgIf*p[56]*p[58]*xvar2; + tff_Vbei=tff_q1*q1_Vbei; + tff_Vbci=tff_q1*q1_Vbci; + tff_Vbci=tff_Vbci+tff_xvar2*xvar2_Vbci; + tff_Vbei=tff_Vbei+tff_mIf*mIf_Vbei; + (*Qbe)=p[16]*qdbe*p[32]+tff*Ifi/qb; + Qbe_qdbe=p[16]*p[32]; + Qbe_tff=Ifi/qb; + Qbe_Ifi=tff/qb; + Qbe_qb=-Ifi*tff/(qb*qb); + *Qbe_Vbei=Qbe_qdbe*qdbe_Vbei; + *Qbe_Vbei=(*Qbe_Vbei)+Qbe_tff*tff_Vbei; + *Qbe_Vbci=Qbe_tff*tff_Vbci; + *Qbe_Vbei=(*Qbe_Vbei)+Qbe_Ifi*Ifi_Vbei; + *Qbe_Vbei=(*Qbe_Vbei)+Qbe_qb*qb_Vbei; + *Qbe_Vbci=(*Qbe_Vbci)+Qbe_qb*qb_Vbci; + (*Qbex)=p[16]*qdbex*(1.0-p[32]); + Qbex_qdbex=p[16]*(1.0-p[32]); + *Qbex_Vbex=Qbex_qdbex*qdbex_Vbex; + (*Qbc)=p[21]*qdbc+p[61]*Iri+p[22]*Kbci; + Qbc_qdbc=p[21]; + Qbc_Iri=p[61]; + Qbc_Kbci=p[22]; + *Qbc_Vbci=Qbc_qdbc*qdbc_Vbci; + *Qbc_Vbci=(*Qbc_Vbci)+Qbc_Iri*Iri_Vbci; + *Qbc_Vbci=(*Qbc_Vbci)+Qbc_Kbci*Kbci_Vbci; + (*Qbcx)=p[22]*Kbcx; + Qbcx_Kbcx=p[22]; + *Qbcx_Vbcx=Qbcx_Kbcx*Kbcx_Vbcx; + (*Qbep)=p[23]*qdbep+p[61]*Ifp; + Qbep_qdbep=p[23]; + Qbep_Ifp=p[61]; + *Qbep_Vbep=Qbep_qdbep*qdbep_Vbep; + *Qbep_Vbep=(*Qbep_Vbep)+Qbep_Ifp*Ifp_Vbep; + *Qbep_Vbci=Qbep_Ifp*Ifp_Vbci; + (*Qbeo)=(*Vbe)*p[15]; + *Qbeo_Vbe=p[15]; + (*Qbco)=(*Vbc)*p[20]; + *Qbco_Vbc=p[20]; + +/* Scale outputs */ + + if((*SCALE)!=1.0){ + *Ibe=(*SCALE)*(*Ibe); + *Ibe_Vbei=(*SCALE)*(*Ibe_Vbei); + *Ibex=(*SCALE)*(*Ibex); + *Ibex_Vbex=(*SCALE)*(*Ibex_Vbex); + *Itzf=(*SCALE)*(*Itzf); + *Itzf_Vbei=(*SCALE)*(*Itzf_Vbei); + *Itzf_Vbci=(*SCALE)*(*Itzf_Vbci); + *Itzr=(*SCALE)*(*Itzr); + *Itzr_Vbci=(*SCALE)*(*Itzr_Vbci); + *Itzr_Vbei=(*SCALE)*(*Itzr_Vbei); + *Ibc=(*SCALE)*(*Ibc); + *Ibc_Vbci=(*SCALE)*(*Ibc_Vbci); + *Ibc_Vbei=(*SCALE)*(*Ibc_Vbei); + *Ibep=(*SCALE)*(*Ibep); + *Ibep_Vbep=(*SCALE)*(*Ibep_Vbep); + *Ircx=(*SCALE)*(*Ircx); + *Ircx_Vrcx=(*SCALE)*(*Ircx_Vrcx); + *Irci=(*SCALE)*(*Irci); + *Irci_Vrci=(*SCALE)*(*Irci_Vrci); + *Irci_Vbci=(*SCALE)*(*Irci_Vbci); + *Irci_Vbcx=(*SCALE)*(*Irci_Vbcx); + *Irbx=(*SCALE)*(*Irbx); + *Irbx_Vrbx=(*SCALE)*(*Irbx_Vrbx); + *Irbi=(*SCALE)*(*Irbi); + *Irbi_Vrbi=(*SCALE)*(*Irbi_Vrbi); + *Irbi_Vbei=(*SCALE)*(*Irbi_Vbei); + *Irbi_Vbci=(*SCALE)*(*Irbi_Vbci); + *Ire=(*SCALE)*(*Ire); + *Ire_Vre=(*SCALE)*(*Ire_Vre); + *Irbp=(*SCALE)*(*Irbp); + *Irbp_Vrbp=(*SCALE)*(*Irbp_Vrbp); + *Irbp_Vbep=(*SCALE)*(*Irbp_Vbep); + *Irbp_Vbci=(*SCALE)*(*Irbp_Vbci); + *Qbe=(*SCALE)*(*Qbe); + *Qbe_Vbei=(*SCALE)*(*Qbe_Vbei); + *Qbe_Vbci=(*SCALE)*(*Qbe_Vbci); + *Qbex=(*SCALE)*(*Qbex); + *Qbex_Vbex=(*SCALE)*(*Qbex_Vbex); + *Qbc=(*SCALE)*(*Qbc); + *Qbc_Vbci=(*SCALE)*(*Qbc_Vbci); + *Qbcx=(*SCALE)*(*Qbcx); + *Qbcx_Vbcx=(*SCALE)*(*Qbcx_Vbcx); + *Qbep=(*SCALE)*(*Qbep); + *Qbep_Vbep=(*SCALE)*(*Qbep_Vbep); + *Qbep_Vbci=(*SCALE)*(*Qbep_Vbci); + *Qbeo=(*SCALE)*(*Qbeo); + *Qbeo_Vbe=(*SCALE)*(*Qbeo_Vbe); + *Qbco=(*SCALE)*(*Qbco); + *Qbco_Vbc=(*SCALE)*(*Qbco_Vbc); + } + return(0); +} diff --git a/src/spicelib/devices/vbic/vbicmask.c b/src/spicelib/devices/vbic/vbicmask.c new file mode 100644 index 000000000..889f8fd1f --- /dev/null +++ b/src/spicelib/devices/vbic/vbicmask.c @@ -0,0 +1,360 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Mathew Lew and Thomas L. Quarles +Model Author: 1995 Colin McAndrew Motorola +Spice3 Implementation: 2003 Dietmar Warning DAnalyse GmbH +**********/ + +#include "ngspice.h" +#include "const.h" +#include "ifsim.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "vbicdefs.h" +#include "sperror.h" +#include "suffix.h" + + +/*ARGSUSED*/ +int +VBICmAsk(CKTcircuit *ckt, GENmodel *instPtr, int which, IFvalue *value) +{ + VBICmodel *here = (VBICmodel*)instPtr; + + switch(which) { + case VBIC_MOD_TNOM: + value->rValue = here->VBICtnom-CONSTCtoK; + return(OK); + case VBIC_MOD_RCX: + value->rValue = here->VBICextCollResist; + return(OK); + case VBIC_MOD_RCI: + value->rValue = here->VBICintCollResist; + return(OK); + case VBIC_MOD_VO: + value->rValue = here->VBICepiSatVoltage; + return(OK); + case VBIC_MOD_GAMM: + value->rValue = here->VBICepiDoping; + return(OK); + case VBIC_MOD_HRCF: + value->rValue = here->VBIChighCurFac; + return(OK); + case VBIC_MOD_RBX: + value->rValue = here->VBICextBaseResist; + return(OK); + case VBIC_MOD_RBI: + value->rValue = here->VBICintBaseResist; + return(OK); + case VBIC_MOD_RE: + value->rValue = here->VBICemitterResist; + return(OK); + case VBIC_MOD_RS: + value->rValue = here->VBICsubstrateResist; + return(OK); + case VBIC_MOD_RBP: + value->rValue = here->VBICparBaseResist; + return(OK); + case VBIC_MOD_IS: + value->rValue = here->VBICsatCur; + return(OK); + case VBIC_MOD_NF: + value->rValue = here->VBICemissionCoeffF; + return(OK); + case VBIC_MOD_NR: + value->rValue = here->VBICemissionCoeffR; + return(OK); + case VBIC_MOD_FC: + value->rValue = here->VBICdeplCapLimitF; + return(OK); + case VBIC_MOD_CBEO: + value->rValue = here->VBICextOverlapCapBE; + return(OK); + case VBIC_MOD_CJE: + value->rValue = here->VBICdepletionCapBE; + return(OK); + case VBIC_MOD_PE: + value->rValue = here->VBICpotentialBE; + return(OK); + case VBIC_MOD_ME: + value->rValue = here->VBICjunctionExpBE; + return(OK); + case VBIC_MOD_AJE: + value->rValue = here->VBICsmoothCapBE; + return(OK); + case VBIC_MOD_CBCO: + value->rValue = here->VBICextOverlapCapBC; + return(OK); + case VBIC_MOD_CJC: + value->rValue = here->VBICdepletionCapBC; + return(OK); + case VBIC_MOD_QCO: + value->rValue = here->VBICepiCharge; + return(OK); + case VBIC_MOD_CJEP: + value->rValue = here->VBICextCapBC; + return(OK); + case VBIC_MOD_PC: + value->rValue = here->VBICpotentialBC; + return(OK); + case VBIC_MOD_MC: + value->rValue = here->VBICjunctionExpBC; + return(OK); + case VBIC_MOD_AJC: + value->rValue = here->VBICsmoothCapBC; + return(OK); + case VBIC_MOD_CJCP: + value->rValue = here->VBICextCapSC; + return(OK); + case VBIC_MOD_PS: + value->rValue = here->VBICpotentialSC; + return(OK); + case VBIC_MOD_MS: + value->rValue = here->VBICjunctionExpSC; + return(OK); + case VBIC_MOD_AJS: + value->rValue = here->VBICsmoothCapSC; + return(OK); + case VBIC_MOD_IBEI: + value->rValue = here->VBICidealSatCurBE; + return(OK); + case VBIC_MOD_WBE: + value->rValue = here->VBICportionIBEI; + return(OK); + case VBIC_MOD_NEI: + value->rValue = here->VBICidealEmissCoeffBE; + return(OK); + case VBIC_MOD_IBEN: + value->rValue = here->VBICnidealSatCurBE; + return(OK); + case VBIC_MOD_NEN: + value->rValue = here->VBICnidealEmissCoeffBE; + return(OK); + case VBIC_MOD_IBCI: + value->rValue = here->VBICidealSatCurBC; + return(OK); + case VBIC_MOD_NCI: + value->rValue = here->VBICidealEmissCoeffBC; + return(OK); + case VBIC_MOD_IBCN: + value->rValue = here->VBICnidealSatCurBC; + return(OK); + case VBIC_MOD_NCN: + value->rValue = here->VBICnidealEmissCoeffBC; + return(OK); + case VBIC_MOD_AVC1: + value->rValue = here->VBICavalanchePar1BC; + return(OK); + case VBIC_MOD_AVC2: + value->rValue = here->VBICavalanchePar2BC; + return(OK); + case VBIC_MOD_ISP: + value->rValue = here->VBICparasitSatCur; + return(OK); + case VBIC_MOD_WSP: + value->rValue = here->VBICportionICCP; + return(OK); + case VBIC_MOD_NFP: + value->rValue = here->VBICparasitFwdEmissCoeff; + return(OK); + case VBIC_MOD_IBEIP: + value->rValue = here->VBICidealParasitSatCurBE; + return(OK); + case VBIC_MOD_IBENP: + value->rValue = here->VBICnidealParasitSatCurBE; + return(OK); + case VBIC_MOD_IBCIP: + value->rValue = here->VBICidealParasitSatCurBC; + return(OK); + case VBIC_MOD_NCIP: + value->rValue = here->VBICidealParasitEmissCoeffBC; + return(OK); + case VBIC_MOD_IBCNP: + value->rValue = here->VBICnidealParasitSatCurBC; + return(OK); + case VBIC_MOD_NCNP: + value->rValue = here->VBICnidealParasitEmissCoeffBC; + return(OK); + case VBIC_MOD_VEF: + value->rValue = here->VBICearlyVoltF; + return(OK); + case VBIC_MOD_VER: + value->rValue = here->VBICearlyVoltR; + return(OK); + case VBIC_MOD_IKF: + value->rValue = here->VBICrollOffF; + return(OK); + case VBIC_MOD_IKR: + value->rValue = here->VBICrollOffR; + return(OK); + case VBIC_MOD_IKP: + value->rValue = here->VBICparRollOff; + return(OK); + case VBIC_MOD_TF: + value->rValue = here->VBICtransitTimeF; + return(OK); + case VBIC_MOD_QTF: + value->rValue = here->VBICvarTransitTimeF; + return(OK); + case VBIC_MOD_XTF: + value->rValue = here->VBICtransitTimeBiasCoeffF; + return(OK); + case VBIC_MOD_VTF: + value->rValue = here->VBICtransitTimeFVBC; + return(OK); + case VBIC_MOD_ITF: + value->rValue = here->VBICtransitTimeHighCurrentF; + return(OK); + case VBIC_MOD_TR: + value->rValue = here->VBICtransitTimeR; + return(OK); + case VBIC_MOD_TD: + value->rValue = here->VBICdelayTimeF; + return(OK); + case VBIC_MOD_KFN: + value->rValue = here->VBICfNcoef; + return(OK); + case VBIC_MOD_AFN: + value->rValue = here->VBICfNexpA; + return(OK); + case VBIC_MOD_BFN: + value->rValue = here->VBICfNexpB; + return(OK); + case VBIC_MOD_XRE: + value->rValue = here->VBICtempExpRE; + return(OK); + case VBIC_MOD_XRBI: + value->rValue = here->VBICtempExpRBI; + return(OK); + case VBIC_MOD_XRCI: + value->rValue = here->VBICtempExpRCI; + return(OK); + case VBIC_MOD_XRS: + value->rValue = here->VBICtempExpRS; + return(OK); + case VBIC_MOD_XVO: + value->rValue = here->VBICtempExpVO; + return(OK); + case VBIC_MOD_EA: + value->rValue = here->VBICactivEnergyEA; + return(OK); + case VBIC_MOD_EAIE: + value->rValue = here->VBICactivEnergyEAIE; + return(OK); + case VBIC_MOD_EAIC: + value->rValue = here->VBICactivEnergyEAIC; + return(OK); + case VBIC_MOD_EAIS: + value->rValue = here->VBICactivEnergyEAIS; + return(OK); + case VBIC_MOD_EANE: + value->rValue = here->VBICactivEnergyEANE; + return(OK); + case VBIC_MOD_EANC: + value->rValue = here->VBICactivEnergyEANC; + return(OK); + case VBIC_MOD_EANS: + value->rValue = here->VBICactivEnergyEANS; + return(OK); + case VBIC_MOD_XIS: + value->rValue = here->VBICtempExpIS; + return(OK); + case VBIC_MOD_XII: + value->rValue = here->VBICtempExpII; + return(OK); + case VBIC_MOD_XIN: + value->rValue = here->VBICtempExpIN; + return(OK); + case VBIC_MOD_TNF: + value->rValue = here->VBICtempExpNF; + return(OK); + case VBIC_MOD_TAVC: + value->rValue = here->VBICtempExpAVC; + return(OK); + case VBIC_MOD_RTH: + value->rValue = here->VBICthermalResist; + return(OK); + case VBIC_MOD_CTH: + value->rValue = here->VBICthermalCapacitance; + return(OK); + case VBIC_MOD_VRT: + value->rValue = here->VBICpunchThroughVoltageBC; + return(OK); + case VBIC_MOD_ART: + value->rValue = here->VBICdeplCapCoeff1; + return(OK); + case VBIC_MOD_CCSO: + value->rValue = here->VBICfixedCapacitanceCS; + return(OK); + case VBIC_MOD_QBM: + value->rValue = here->VBICsgpQBselector; + return(OK); + case VBIC_MOD_NKF: + value->rValue = here->VBIChighCurrentBetaRolloff; + return(OK); + case VBIC_MOD_XIKF: + value->rValue = here->VBICtempExpIKF; + return(OK); + case VBIC_MOD_XRCX: + value->rValue = here->VBICtempExpRCX; + return(OK); + case VBIC_MOD_XRBX: + value->rValue = here->VBICtempExpRBX; + return(OK); + case VBIC_MOD_XRBP: + value->rValue = here->VBICtempExpRBP; + return(OK); + case VBIC_MOD_ISRR: + value->rValue = here->VBICsepISRR; + return(OK); + case VBIC_MOD_XISR: + value->rValue = here->VBICtempExpXISR; + return(OK); + case VBIC_MOD_DEAR: + value->rValue = here->VBICdear; + return(OK); + case VBIC_MOD_EAP: + value->rValue = here->VBICeap; + return(OK); + case VBIC_MOD_VBBE: + value->rValue = here->VBICvbbe; + return(OK); + case VBIC_MOD_NBBE: + value->rValue = here->VBICnbbe; + return(OK); + case VBIC_MOD_IBBE: + value->rValue = here->VBICibbe; + return(OK); + case VBIC_MOD_TVBBE1: + value->rValue = here->VBICtvbbe1; + return(OK); + case VBIC_MOD_TVBBE2: + value->rValue = here->VBICtvbbe2; + return(OK); + case VBIC_MOD_TNBBE: + value->rValue = here->VBICtnbbe; + return(OK); + case VBIC_MOD_EBBE: + value->rValue = here->VBICebbe; + return(OK); + case VBIC_MOD_DTEMP: + value->rValue = here->VBIClocTempDiff; + return(OK); + case VBIC_MOD_VERS: + value->rValue = here->VBICrevVersion; + return(OK); + case VBIC_MOD_VREF: + value->rValue = here->VBICrefVersion; + return(OK); + case VBIC_MOD_TYPE: + if (here->VBICtype == NPN) + value->sValue = "npn"; + else + value->sValue = "pnp"; + return(OK); + default: + return(E_BADPARM); + } + /* NOTREACHED */ +} + diff --git a/src/spicelib/devices/vbic/vbicmdel.c b/src/spicelib/devices/vbic/vbicmdel.c new file mode 100644 index 000000000..31e9677c7 --- /dev/null +++ b/src/spicelib/devices/vbic/vbicmdel.c @@ -0,0 +1,41 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1995 Colin McAndrew Motorola +Spice3 Implementation: 2003 Dietmar Warning DAnalyse GmbH +**********/ + +/* + * This routine deletes a VBIC model from the circuit and frees + * the storage it was using. + * returns an error if the model has instances + */ + +#include "ngspice.h" +#include "vbicdefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +VBICmDelete(GENmodel **inModels, IFuid modname, GENmodel *kill) +{ + VBICmodel **model = (VBICmodel**)inModels; + VBICmodel *modfast = (VBICmodel*)kill; + + VBICmodel **oldmod; + oldmod = model; + for( ; *model ; model = &((*model)->VBICnextModel)) { + if( (*model)->VBICmodName == modname || + (modfast && *model == modfast) ) goto delgot; + oldmod = model; + } + return(E_NOMOD); + +delgot: + if( (*model)->VBICinstances ) return(E_NOTEMPTY); + *oldmod = (*model)->VBICnextModel; /* cut deleted device out of list */ + FREE(*model); + return(OK); + +} diff --git a/src/spicelib/devices/vbic/vbicmpar.c b/src/spicelib/devices/vbic/vbicmpar.c new file mode 100644 index 000000000..914c0350d --- /dev/null +++ b/src/spicelib/devices/vbic/vbicmpar.c @@ -0,0 +1,477 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1995 Colin McAndrew Motorola +Spice3 Implementation: 2003 Dietmar Warning DAnalyse GmbH +**********/ + +/* + * This routine sets model parameters for + * VBICs in the circuit. + */ + +#include "ngspice.h" +#include "const.h" +#include "ifsim.h" +#include "vbicdefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +VBICmParam(int param, IFvalue *value, GENmodel *inModel) +{ + VBICmodel *mods = (VBICmodel*)inModel; + + switch(param) { + case VBIC_MOD_NPN: + if(value->iValue) { + mods->VBICtype = NPN; + } + break; + case VBIC_MOD_PNP: + if(value->iValue) { + mods->VBICtype = PNP; + } + break; + + case VBIC_MOD_TNOM: + mods->VBICtnom = value->rValue; + mods->VBICtnomGiven = TRUE; + break; + case VBIC_MOD_RCX: + mods->VBICextCollResist = value->rValue; + mods->VBICextCollResistGiven = TRUE; + break; + case VBIC_MOD_RCI: + mods->VBICintCollResist = value->rValue; + if (mods->VBICintCollResist < 0.1) mods->VBICintCollResist = 0.1; + mods->VBICintCollResistGiven = TRUE; + break; + case VBIC_MOD_VO: + mods->VBICepiSatVoltage = value->rValue; + mods->VBICepiSatVoltageGiven = TRUE; + break; + case VBIC_MOD_GAMM: + mods->VBICepiDoping = value->rValue; + mods->VBICepiDopingGiven = TRUE; + break; + case VBIC_MOD_HRCF: + mods->VBIChighCurFac = value->rValue; + mods->VBIChighCurFacGiven = TRUE; + break; + case VBIC_MOD_RBX: + mods->VBICextBaseResist = value->rValue; + mods->VBICextBaseResistGiven = TRUE; + break; + case VBIC_MOD_RBI: + mods->VBICintBaseResist = value->rValue; + if (mods->VBICintBaseResist < 0.1) mods->VBICintBaseResist = 0.1; + mods->VBICintBaseResistGiven = TRUE; + break; + case VBIC_MOD_RE: + mods->VBICemitterResist = value->rValue; + mods->VBICemitterResistGiven = TRUE; + break; + case VBIC_MOD_RS: + mods->VBICsubstrateResist = value->rValue; + mods->VBICsubstrateResistGiven = TRUE; + break; + case VBIC_MOD_RBP: + mods->VBICparBaseResist = value->rValue; + if (mods->VBICparBaseResist < 0.1) mods->VBICparBaseResist = 0.1; + mods->VBICparBaseResistGiven = TRUE; + break; + case VBIC_MOD_IS: + mods->VBICsatCur = value->rValue; + mods->VBICsatCurGiven = TRUE; + break; + case VBIC_MOD_NF: + mods->VBICemissionCoeffF = value->rValue; + mods->VBICemissionCoeffFGiven = TRUE; + break; + case VBIC_MOD_NR: + mods->VBICemissionCoeffR = value->rValue; + mods->VBICemissionCoeffRGiven = TRUE; + break; + case VBIC_MOD_FC: + mods->VBICdeplCapLimitF = value->rValue; + mods->VBICdeplCapLimitFGiven = TRUE; + break; + case VBIC_MOD_CBEO: + mods->VBICextOverlapCapBE = value->rValue; + mods->VBICextOverlapCapBEGiven=TRUE; + break; + case VBIC_MOD_CJE: + mods->VBICdepletionCapBE = value->rValue; + mods->VBICdepletionCapBEGiven = TRUE; + break; + case VBIC_MOD_PE: + mods->VBICpotentialBE = value->rValue; + mods->VBICpotentialBEGiven = TRUE; + break; + case VBIC_MOD_ME: + mods->VBICjunctionExpBE = value->rValue; + mods->VBICjunctionExpBEGiven = TRUE; + break; + case VBIC_MOD_AJE: + mods->VBICsmoothCapBE = value->rValue; + mods->VBICsmoothCapBEGiven = TRUE; + break; + case VBIC_MOD_CBCO: + mods->VBICextOverlapCapBC = value->rValue; + mods->VBICextOverlapCapBCGiven=TRUE; + break; + case VBIC_MOD_CJC: + mods->VBICdepletionCapBC = value->rValue; + mods->VBICdepletionCapBCGiven = TRUE; + break; + case VBIC_MOD_QCO: + mods->VBICepiCharge = value->rValue; + mods->VBICepiChargeGiven = TRUE; + break; + case VBIC_MOD_CJEP: + mods->VBICextCapBC = value->rValue; + mods->VBICextCapBCGiven = TRUE; + break; + case VBIC_MOD_PC: + mods->VBICpotentialBC = value->rValue; + mods->VBICpotentialBCGiven = TRUE; + break; + case VBIC_MOD_MC: + mods->VBICjunctionExpBC = value->rValue; + mods->VBICjunctionExpBCGiven = TRUE; + break; + case VBIC_MOD_AJC: + mods->VBICsmoothCapBC = value->rValue; + mods->VBICsmoothCapBCGiven = TRUE; + break; + case VBIC_MOD_CJCP: + mods->VBICextCapSC = value->rValue; + mods->VBICextCapSCGiven = TRUE; + break; + case VBIC_MOD_PS: + mods->VBICpotentialSC = value->rValue; + mods->VBICpotentialSCGiven = TRUE; + break; + case VBIC_MOD_MS: + mods->VBICjunctionExpSC = value->rValue; + mods->VBICjunctionExpSCGiven = TRUE; + break; + case VBIC_MOD_AJS: + mods->VBICsmoothCapSC = value->rValue; + mods->VBICsmoothCapSCGiven = TRUE; + break; + case VBIC_MOD_IBEI: + mods->VBICidealSatCurBE = value->rValue; + mods->VBICidealSatCurBEGiven = TRUE; + break; + case VBIC_MOD_WBE: + mods->VBICportionIBEI = value->rValue; + mods->VBICportionIBEIGiven = TRUE; + break; + case VBIC_MOD_NEI: + mods->VBICidealEmissCoeffBE = value->rValue; + mods->VBICidealEmissCoeffBEGiven = TRUE; + break; + case VBIC_MOD_IBEN: + mods->VBICnidealSatCurBE = value->rValue; + mods->VBICnidealSatCurBEGiven = TRUE; + break; + case VBIC_MOD_NEN: + mods->VBICnidealEmissCoeffBE = value->rValue; + mods->VBICnidealEmissCoeffBEGiven = TRUE; + break; + case VBIC_MOD_IBCI: + mods->VBICidealSatCurBC = value->rValue; + mods->VBICidealSatCurBCGiven = TRUE; + break; + case VBIC_MOD_NCI: + mods->VBICidealEmissCoeffBC = value->rValue; + mods->VBICidealEmissCoeffBCGiven = TRUE; + break; + case VBIC_MOD_IBCN: + mods->VBICnidealSatCurBC = value->rValue; + mods->VBICnidealSatCurBCGiven = TRUE; + break; + case VBIC_MOD_NCN: + mods->VBICnidealEmissCoeffBC = value->rValue; + mods->VBICnidealEmissCoeffBCGiven = TRUE; + break; + case VBIC_MOD_AVC1: + mods->VBICavalanchePar1BC = value->rValue; + mods->VBICavalanchePar1BCGiven = TRUE; + break; + case VBIC_MOD_AVC2: + mods->VBICavalanchePar2BC = value->rValue; + mods->VBICavalanchePar2BCGiven = TRUE; + break; + case VBIC_MOD_ISP: + mods->VBICparasitSatCur = value->rValue; + mods->VBICparasitSatCurGiven = TRUE; + break; + case VBIC_MOD_WSP: + mods->VBICportionICCP = value->rValue; + mods->VBICportionICCPGiven = TRUE; + break; + case VBIC_MOD_NFP: + mods->VBICparasitFwdEmissCoeff = value->rValue; + mods->VBICparasitFwdEmissCoeffGiven = TRUE; + break; + case VBIC_MOD_IBEIP: + mods->VBICidealParasitSatCurBE = value->rValue; + mods->VBICidealParasitSatCurBEGiven = TRUE; + break; + case VBIC_MOD_IBENP: + mods->VBICnidealParasitSatCurBE = value->rValue; + mods->VBICnidealParasitSatCurBEGiven = TRUE; + break; + case VBIC_MOD_IBCIP: + mods->VBICidealParasitSatCurBC = value->rValue; + mods->VBICidealParasitSatCurBCGiven = TRUE; + break; + case VBIC_MOD_NCIP: + mods->VBICidealParasitEmissCoeffBC = value->rValue; + mods->VBICidealParasitEmissCoeffBCGiven = TRUE; + break; + case VBIC_MOD_IBCNP: + mods->VBICnidealParasitSatCurBC = value->rValue; + mods->VBICnidealParasitSatCurBCGiven = TRUE; + break; + case VBIC_MOD_NCNP: + mods->VBICnidealParasitEmissCoeffBC = value->rValue; + mods->VBICnidealParasitEmissCoeffBCGiven = TRUE; + break; + case VBIC_MOD_VEF: + mods->VBICearlyVoltF = value->rValue; + mods->VBICearlyVoltFGiven = TRUE; + break; + case VBIC_MOD_VER: + mods->VBICearlyVoltR = value->rValue; + mods->VBICearlyVoltRGiven = TRUE; + break; + case VBIC_MOD_IKF: + mods->VBICrollOffF = value->rValue; + mods->VBICrollOffFGiven = TRUE; + break; + case VBIC_MOD_IKR: + mods->VBICrollOffR = value->rValue; + mods->VBICrollOffRGiven = TRUE; + break; + case VBIC_MOD_IKP: + mods->VBICparRollOff = value->rValue; + mods->VBICparRollOffGiven = TRUE; + break; + case VBIC_MOD_TF: + mods->VBICtransitTimeF = value->rValue; + mods->VBICtransitTimeFGiven = TRUE; + break; + case VBIC_MOD_QTF: + mods->VBICvarTransitTimeF = value->rValue; + mods->VBICvarTransitTimeFGiven = TRUE; + break; + case VBIC_MOD_XTF: + mods->VBICtransitTimeBiasCoeffF = value->rValue; + mods->VBICtransitTimeBiasCoeffFGiven = TRUE; + break; + case VBIC_MOD_VTF: + mods->VBICtransitTimeFVBC = value->rValue; + mods->VBICtransitTimeFVBCGiven = TRUE; + break; + case VBIC_MOD_ITF: + mods->VBICtransitTimeHighCurrentF = value->rValue; + mods->VBICtransitTimeHighCurrentFGiven = TRUE; + break; + case VBIC_MOD_TR: + mods->VBICtransitTimeR = value->rValue; + mods->VBICtransitTimeRGiven = TRUE; + break; + case VBIC_MOD_TD: + mods->VBICdelayTimeF = value->rValue; + mods->VBICdelayTimeFGiven = TRUE; + break; + case VBIC_MOD_KFN: + mods->VBICfNcoef = value->rValue; + mods->VBICfNcoefGiven = TRUE; + break; + case VBIC_MOD_AFN: + mods->VBICfNexpA = value->rValue; + mods->VBICfNexpAGiven = TRUE; + break; + case VBIC_MOD_BFN: + mods->VBICfNexpB = value->rValue; + mods->VBICfNexpBGiven = TRUE; + break; + case VBIC_MOD_XRE: + mods->VBICtempExpRE = value->rValue; + mods->VBICtempExpREGiven = TRUE; + break; + case VBIC_MOD_XRBI: + mods->VBICtempExpRBI = value->rValue; + mods->VBICtempExpRBIGiven = TRUE; + break; + case VBIC_MOD_XRCI: + mods->VBICtempExpRCI = value->rValue; + mods->VBICtempExpRCIGiven = TRUE; + break; + case VBIC_MOD_XRS: + mods->VBICtempExpRS = value->rValue; + mods->VBICtempExpRSGiven = TRUE; + break; + case VBIC_MOD_XVO: + mods->VBICtempExpVO = value->rValue; + mods->VBICtempExpVOGiven = TRUE; + break; + case VBIC_MOD_EA: + mods->VBICactivEnergyEA = value->rValue; + mods->VBICactivEnergyEAGiven = TRUE; + break; + case VBIC_MOD_EAIE: + mods->VBICactivEnergyEAIE = value->rValue; + mods->VBICactivEnergyEAIEGiven = TRUE; + break; + case VBIC_MOD_EAIC: + mods->VBICactivEnergyEAIC = value->rValue; + mods->VBICactivEnergyEAICGiven = TRUE; + break; + case VBIC_MOD_EAIS: + mods->VBICactivEnergyEAIS = value->rValue; + mods->VBICactivEnergyEAISGiven = TRUE; + break; + case VBIC_MOD_EANE: + mods->VBICactivEnergyEANE = value->rValue; + mods->VBICactivEnergyEANEGiven = TRUE; + break; + case VBIC_MOD_EANC: + mods->VBICactivEnergyEANC = value->rValue; + mods->VBICactivEnergyEANCGiven = TRUE; + break; + case VBIC_MOD_EANS: + mods->VBICactivEnergyEANS = value->rValue; + mods->VBICactivEnergyEANSGiven = TRUE; + break; + case VBIC_MOD_XIS: + mods->VBICtempExpIS = value->rValue; + mods->VBICtempExpISGiven = TRUE; + break; + case VBIC_MOD_XII: + mods->VBICtempExpII = value->rValue; + mods->VBICtempExpIIGiven = TRUE; + break; + case VBIC_MOD_XIN: + mods->VBICtempExpIN = value->rValue; + mods->VBICtempExpINGiven = TRUE; + break; + case VBIC_MOD_TNF: + mods->VBICtempExpNF = value->rValue; + mods->VBICtempExpNFGiven = TRUE; + break; + case VBIC_MOD_TAVC: + mods->VBICtempExpAVC = value->rValue; + mods->VBICtempExpAVCGiven = TRUE; + break; + case VBIC_MOD_RTH: + mods->VBICthermalResist = value->rValue; + mods->VBICthermalResistGiven = TRUE; + break; + case VBIC_MOD_CTH: + mods->VBICthermalCapacitance = value->rValue; + mods->VBICthermalCapacitanceGiven = TRUE; + break; + case VBIC_MOD_VRT: + mods->VBICpunchThroughVoltageBC = value->rValue; + mods->VBICpunchThroughVoltageBCGiven = TRUE; + break; + case VBIC_MOD_ART: + mods->VBICdeplCapCoeff1 = value->rValue; + mods->VBICdeplCapCoeff1Given = TRUE; + break; + case VBIC_MOD_CCSO: + mods->VBICfixedCapacitanceCS = value->rValue; + mods->VBICfixedCapacitanceCSGiven = TRUE; + break; + case VBIC_MOD_QBM: + mods->VBICsgpQBselector = value->rValue; + mods->VBICsgpQBselectorGiven = TRUE; + break; + case VBIC_MOD_NKF: + mods->VBIChighCurrentBetaRolloff = value->rValue; + mods->VBIChighCurrentBetaRolloffGiven = TRUE; + break; + case VBIC_MOD_XIKF: + mods->VBICtempExpIKF = value->rValue; + mods->VBICtempExpIKFGiven = TRUE; + break; + case VBIC_MOD_XRCX: + mods->VBICtempExpRCX = value->rValue; + mods->VBICtempExpRCXGiven = TRUE; + break; + case VBIC_MOD_XRBX: + mods->VBICtempExpRBX = value->rValue; + mods->VBICtempExpRBXGiven = TRUE; + break; + case VBIC_MOD_XRBP: + mods->VBICtempExpRBP = value->rValue; + mods->VBICtempExpRBPGiven = TRUE; + break; + case VBIC_MOD_ISRR: + mods->VBICsepISRR = value->rValue; + mods->VBICsepISRRGiven = TRUE; + break; + case VBIC_MOD_XISR: + mods->VBICtempExpXISR = value->rValue; + mods->VBICtempExpXISRGiven = TRUE; + break; + case VBIC_MOD_DEAR: + mods->VBICdear = value->rValue; + mods->VBICdearGiven = TRUE; + break; + case VBIC_MOD_EAP: + mods->VBICeap = value->rValue; + mods->VBICeapGiven = TRUE; + break; + case VBIC_MOD_VBBE: + mods->VBICvbbe = value->rValue; + mods->VBICvbbeGiven = TRUE; + break; + case VBIC_MOD_NBBE: + mods->VBICnbbe = value->rValue; + mods->VBICnbbeGiven = TRUE; + break; + case VBIC_MOD_IBBE: + mods->VBICibbe = value->rValue; + mods->VBICibbeGiven = TRUE; + break; + case VBIC_MOD_TVBBE1: + mods->VBICtvbbe1 = value->rValue; + mods->VBICtvbbe1Given = TRUE; + break; + case VBIC_MOD_TVBBE2: + mods->VBICtvbbe2 = value->rValue; + mods->VBICtvbbe2Given = TRUE; + break; + case VBIC_MOD_TNBBE: + mods->VBICtnbbe = value->rValue; + mods->VBICtnbbeGiven = TRUE; + break; + case VBIC_MOD_EBBE: + mods->VBICebbe = value->rValue; + mods->VBICebbeGiven = TRUE; + break; + case VBIC_MOD_DTEMP: + mods->VBIClocTempDiff = value->rValue; + mods->VBIClocTempDiffGiven = TRUE; + break; + case VBIC_MOD_VERS: + mods->VBICrevVersion = value->rValue; + mods->VBICrevVersionGiven = TRUE; + break; + case VBIC_MOD_VREF: + mods->VBICrefVersion = value->rValue; + mods->VBICrefVersionGiven = TRUE; + break; + default: + return(E_BADPARM); + } + return(OK); +} diff --git a/src/spicelib/devices/vbic/vbicnoise.c b/src/spicelib/devices/vbic/vbicnoise.c new file mode 100644 index 000000000..636376696 --- /dev/null +++ b/src/spicelib/devices/vbic/vbicnoise.c @@ -0,0 +1,269 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Gary W. Ng +Model Author: 1995 Colin McAndrew Motorola +Spice3 Implementation: 2003 Dietmar Warning DAnalyse GmbH +**********/ + +#include "ngspice.h" +#include "vbicdefs.h" +#include "cktdefs.h" +#include "iferrmsg.h" +#include "noisedef.h" +#include "suffix.h" + +/* + * VBICnoise (mode, operation, firstModel, ckt, data, OnDens) + * + * This routine names and evaluates all of the noise sources + * associated with VBIC's. It starts with the model *firstModel and + * traverses all of its insts. It then proceeds to any other models + * on the linked list. The total output noise density generated by + * all of the VBIC's is summed with the variable "OnDens". + */ + +extern void NevalSrc(); +extern double Nintegrate(); + +int +VBICnoise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, Ndata *data, double *OnDens) +{ + VBICmodel *firstModel = (VBICmodel *) genmodel; + VBICmodel *model; + VBICinstance *inst; + char name[N_MXVLNTH]; + double tempOnoise; + double tempInoise; + double noizDens[VBICNSRCS]; + double lnNdens[VBICNSRCS]; + int i; + + /* define the names of the noise sources */ + + static char *VBICnNames[VBICNSRCS] = { + /* Note that we have to keep the order consistent with the + strchr definitions in VBICdefs.h */ + "_rc", /* noise due to rc */ + "_rci", /* noise due to rci */ + "_rb", /* noise due to rb */ + "_rbi", /* noise due to rbi */ + "_re", /* noise due to re */ + "_rbp", /* noise due to rbp */ + "_ic", /* noise due to ic */ + "_ib", /* noise due to ib */ + "_ibep", /* noise due to ib */ + "_1overfbe", /* flicker (1/f) noise */ + "_1overfbep", /* flicker (1/f) noise */ + "" /* total transistor noise */ + }; + + for (model=firstModel; model != NULL; model=model->VBICnextModel) { + for (inst=model->VBICinstances; inst != NULL; + inst=inst->VBICnextInstance) { + + if (inst->VBICowner != ARCHme) continue; + + switch (operation) { + + case N_OPEN: + + /* see if we have to to produce a summary report */ + /* if so, name all the noise generators */ + + if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) { + switch (mode) { + + case N_DENS: + for (i=0; i < VBICNSRCS; i++) { + (void)sprintf(name,"onoise_%s%s", + inst->VBICname,VBICnNames[i]); + + + data->namelist = (IFuid *) + trealloc((char *)data->namelist, + (data->numPlots + 1)*sizeof(IFuid)); + if (!data->namelist) return(E_NOMEM); + (*(SPfrontEnd->IFnewUid))(ckt, + &(data->namelist[data->numPlots++]), + (IFuid)NULL,name,UID_OTHER,(void **)NULL); + /* we've added one more plot */ + } + break; + + case INT_NOIZ: + for (i=0; i < VBICNSRCS; i++) { + (void)sprintf(name,"onoise_total_%s%s", + inst->VBICname,VBICnNames[i]); + + data->namelist = (IFuid *) + trealloc((char *)data->namelist, + (data->numPlots + 1)*sizeof(IFuid)); + if (!data->namelist) return(E_NOMEM); + (*(SPfrontEnd->IFnewUid))(ckt, + &(data->namelist[data->numPlots++]), + (IFuid)NULL,name,UID_OTHER,(void **)NULL); + /* we've added one more plot */ + + (void)sprintf(name,"inoise_total_%s%s", + inst->VBICname,VBICnNames[i]); + +data->namelist = (IFuid *)trealloc((char *)data->namelist,(data->numPlots + 1)*sizeof(IFuid)); +if (!data->namelist) return(E_NOMEM); + (*(SPfrontEnd->IFnewUid))(ckt, + &(data->namelist[data->numPlots++]), + (IFuid)NULL,name,UID_OTHER,(void **)NULL); + /* we've added one more plot */ + } + break; + } + } + break; + + case N_CALC: + switch (mode) { + + case N_DENS: + NevalSrc(&noizDens[VBICRCNOIZ],&lnNdens[VBICRCNOIZ], + ckt,THERMNOISE,inst->VBICcollCXNode,inst->VBICcollNode, + model->VBICcollectorConduct * inst->VBICarea * inst->VBICm); + + NevalSrc(&noizDens[VBICRCINOIZ],&lnNdens[VBICRCINOIZ], + ckt,THERMNOISE,inst->VBICcollCXNode,inst->VBICcollCINode, + *(ckt->CKTstate0 + inst->VBICirci_Vrci)); + + NevalSrc(&noizDens[VBICRBNOIZ],&lnNdens[VBICRBNOIZ], + ckt,THERMNOISE,inst->VBICbaseBXNode,inst->VBICbaseNode, + model->VBICbaseConduct * inst->VBICarea * inst->VBICm); + + NevalSrc(&noizDens[VBICRBINOIZ],&lnNdens[VBICRBINOIZ], + ckt,THERMNOISE,inst->VBICbaseBXNode,inst->VBICbaseBINode, + *(ckt->CKTstate0 + inst->VBICirbi_Vrbi)); + + NevalSrc(&noizDens[VBICRENOIZ],&lnNdens[VBICRENOIZ], + ckt,THERMNOISE,inst->VBICemitEINode,inst->VBICemitNode, + model->VBICemitterConduct * inst->VBICarea * inst->VBICm); + + NevalSrc(&noizDens[VBICRBPNOIZ],&lnNdens[VBICRBPNOIZ], + ckt,THERMNOISE,inst->VBICemitEINode,inst->VBICemitNode, + *(ckt->CKTstate0 + inst->VBICirbp_Vrbp)); + + + NevalSrc(&noizDens[VBICICNOIZ],&lnNdens[VBICICNOIZ], + ckt,SHOTNOISE,inst->VBICcollCINode, inst->VBICemitEINode, + *(ckt->CKTstate0 + inst->VBICitzf)); + + NevalSrc(&noizDens[VBICIBNOIZ],&lnNdens[VBICIBNOIZ], + ckt,SHOTNOISE,inst->VBICbaseBINode, inst->VBICemitEINode, + *(ckt->CKTstate0 + inst->VBICibe)); + + NevalSrc(&noizDens[VBICIBEPNOIZ],&lnNdens[VBICIBEPNOIZ], + ckt,SHOTNOISE,inst->VBICbaseBXNode, inst->VBICbaseBPNode, + *(ckt->CKTstate0 + inst->VBICibep)); + + + NevalSrc(&noizDens[VBICFLBENOIZ],(double*)NULL,ckt, + N_GAIN,inst->VBICbaseBINode, inst->VBICemitEINode, + (double)0.0); + noizDens[VBICFLBENOIZ] *= inst->VBICm * model->VBICfNcoef * + exp(model->VBICfNexpA * + log(MAX(fabs(*(ckt->CKTstate0 + inst->VBICibe)/inst->VBICm),N_MINLOG))) / + pow(data->freq, model->VBICfNexpB); + lnNdens[VBICFLBENOIZ] = + log(MAX(noizDens[VBICFLBENOIZ],N_MINLOG)); + + NevalSrc(&noizDens[VBICFLBEPNOIZ],(double*)NULL,ckt, + N_GAIN,inst->VBICbaseBXNode, inst->VBICbaseBPNode, + (double)0.0); + noizDens[VBICFLBEPNOIZ] *= inst->VBICm * model->VBICfNcoef * + exp(model->VBICfNexpA * + log(MAX(fabs(*(ckt->CKTstate0 + inst->VBICibep)/inst->VBICm),N_MINLOG))) / + pow(data->freq, model->VBICfNexpB); + lnNdens[VBICFLBEPNOIZ] = + log(MAX(noizDens[VBICFLBEPNOIZ],N_MINLOG)); + + + noizDens[VBICTOTNOIZ] = noizDens[VBICRCNOIZ] + + noizDens[VBICRCINOIZ] + + noizDens[VBICRBNOIZ] + + noizDens[VBICRBINOIZ] + + noizDens[VBICRENOIZ] + + noizDens[VBICRBPNOIZ] + + noizDens[VBICICNOIZ] + + noizDens[VBICIBNOIZ] + + noizDens[VBICIBEPNOIZ] + + noizDens[VBICFLBENOIZ] + + noizDens[VBICFLBEPNOIZ]; + + lnNdens[VBICTOTNOIZ] = + log(noizDens[VBICTOTNOIZ]); + + *OnDens += noizDens[VBICTOTNOIZ]; + + if (data->delFreq == 0.0) { + + /* if we haven't done any previous integration, we need to */ + /* initialize our "history" variables */ + + for (i=0; i < VBICNSRCS; i++) { + inst->VBICnVar[LNLSTDENS][i] = lnNdens[i]; + } + + /* clear out our integration variables if it's the first pass */ + + if (data->freq == ((NOISEAN*)ckt->CKTcurJob)->NstartFreq) { + for (i=0; i < VBICNSRCS; i++) { + inst->VBICnVar[OUTNOIZ][i] = 0.0; + inst->VBICnVar[INNOIZ][i] = 0.0; + } + } + } else { /* data->delFreq != 0.0 (we have to integrate) */ + +/* In order to get the best curve fit, we have to integrate each component separately */ + + for (i=0; i < VBICNSRCS; i++) { + if (i != VBICTOTNOIZ) { + tempOnoise = Nintegrate(noizDens[i], lnNdens[i], + inst->VBICnVar[LNLSTDENS][i], data); + tempInoise = Nintegrate(noizDens[i] * data->GainSqInv , + lnNdens[i] + data->lnGainInv, + inst->VBICnVar[LNLSTDENS][i] + data->lnGainInv, + data); + inst->VBICnVar[LNLSTDENS][i] = lnNdens[i]; + data->outNoiz += tempOnoise; + data->inNoise += tempInoise; + if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) { + inst->VBICnVar[OUTNOIZ][i] += tempOnoise; + inst->VBICnVar[OUTNOIZ][VBICTOTNOIZ] += tempOnoise; + inst->VBICnVar[INNOIZ][i] += tempInoise; + inst->VBICnVar[INNOIZ][VBICTOTNOIZ] += tempInoise; + } + } + } + } + if (data->prtSummary) { + for (i=0; i < VBICNSRCS; i++) { /* print a summary report */ + data->outpVector[data->outNumber++] = noizDens[i]; + } + } + break; + + case INT_NOIZ: /* already calculated, just output */ + if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) { + for (i=0; i < VBICNSRCS; i++) { + data->outpVector[data->outNumber++] = inst->VBICnVar[OUTNOIZ][i]; + data->outpVector[data->outNumber++] = inst->VBICnVar[INNOIZ][i]; + } + } /* if */ + break; + } /* switch (mode) */ + break; + + case N_CLOSE: + return (OK); /* do nothing, the main calling routine will close */ + break; /* the plots */ + } /* switch (operation) */ + } /* for inst */ + } /* for model */ + +return(OK); +} diff --git a/src/spicelib/devices/vbic/vbicparam.c b/src/spicelib/devices/vbic/vbicparam.c new file mode 100644 index 000000000..74437527a --- /dev/null +++ b/src/spicelib/devices/vbic/vbicparam.c @@ -0,0 +1,72 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1995 Colin McAndrew Motorola +Spice3 Implementation: 2003 Dietmar Warning DAnalyse GmbH +**********/ + +/* + * This routine sets instance parameters for + * VBICs in the circuit. + */ + +#include "ngspice.h" +#include "const.h" +#include "ifsim.h" +#include "vbicdefs.h" +#include "sperror.h" +#include "suffix.h" + + +/* ARGSUSED */ +int +VBICparam(int param, IFvalue *value, GENinstance *instPtr, IFvalue *select) +{ + VBICinstance *here = (VBICinstance*)instPtr; + + switch(param) { + case VBIC_AREA: + here->VBICarea = value->rValue; + here->VBICareaGiven = TRUE; + break; + case VBIC_OFF: + here->VBICoff = value->iValue; + break; + case VBIC_IC_VBE: + here->VBICicVBE = value->rValue; + here->VBICicVBEGiven = TRUE; + break; + case VBIC_IC_VCE: + here->VBICicVCE = value->rValue; + here->VBICicVCEGiven = TRUE; + break; + case VBIC_TEMP: + here->VBICtemp = value->rValue+CONSTCtoK; + here->VBICtempGiven = TRUE; + break; + case VBIC_DTEMP: + here->VBICdtemp = value->rValue; + here->VBICdtempGiven = TRUE; + break; + case VBIC_M: + here->VBICm = value->rValue; + here->VBICmGiven = TRUE; + break; + case VBIC_IC : + switch(value->v.numValue) { + case 2: + here->VBICicVCE = *(value->v.vec.rVec+1); + here->VBICicVCEGiven = TRUE; + case 1: + here->VBICicVBE = *(value->v.vec.rVec); + here->VBICicVBEGiven = TRUE; + break; + default: + return(E_BADPARM); + } + break; + default: + return(E_BADPARM); + } + return(OK); +} diff --git a/src/spicelib/devices/vbic/vbicpzld.c b/src/spicelib/devices/vbic/vbicpzld.c new file mode 100644 index 000000000..89a6e7905 --- /dev/null +++ b/src/spicelib/devices/vbic/vbicpzld.c @@ -0,0 +1,273 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1995 Colin McAndrew Motorola +Spice3 Implementation: 2003 Dietmar Warning DAnalyse GmbH +**********/ + +/* + * Function to load the COMPLEX circuit matrix using the + * small signal parameters saved during a previous DC operating + * point analysis. + */ + +#include "ngspice.h" +#include "cktdefs.h" +#include "vbicdefs.h" +#include "sperror.h" +#include "suffix.h" + +int +VBICpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s) +{ + VBICinstance *here; + VBICmodel *model = (VBICmodel*)inModel; + double Ibe_Vbei,Ibex_Vbex + ,Itzf_Vbei,Itzf_Vbci,Itzr_Vbci,Itzr_Vbei,Ibc_Vbci + ,Ibc_Vbei,Ibep_Vbep,Ircx_Vrcx,Irci_Vrci + ,Irci_Vbci,Irci_Vbcx,Irbx_Vrbx,Irbi_Vrbi,Irbi_Vbei + ,Irbi_Vbci,Ire_Vre,Irbp_Vrbp,Irbp_Vbep,Irbp_Vbci; + double XQbe_Vbei, XQbe_Vbci, XQbex_Vbex, XQbc_Vbci, + XQbcx_Vbcx, XQbep_Vbep, XQbep_Vbci; + + /* loop through all the models */ + for( ; model != NULL; model = model->VBICnextModel) { + + /* loop through all the instances of the model */ + for( here = model->VBICinstances; here!= NULL; + here = here->VBICnextInstance) { + if (here->VBICowner != ARCHme) continue; + + + Ircx_Vrcx = 1.0 / model->VBICextCollResist * here->VBICarea * here->VBICm; + Irbx_Vrbx = 1.0 / model->VBICextBaseResist * here->VBICarea * here->VBICm; + Ire_Vre = 1.0 / model->VBICemitterResist * here->VBICarea * here->VBICm; + + Ibe_Vbei = *(ckt->CKTstate0 + here->VBICibe_Vbei); + Ibex_Vbex = *(ckt->CKTstate0 + here->VBICibex_Vbex); + Itzf_Vbei = *(ckt->CKTstate0 + here->VBICitzf_Vbei); + Itzf_Vbci = *(ckt->CKTstate0 + here->VBICitzf_Vbci); + Itzr_Vbci = *(ckt->CKTstate0 + here->VBICitzr_Vbci); + Itzr_Vbei = *(ckt->CKTstate0 + here->VBICitzr_Vbei); + Ibc_Vbci = *(ckt->CKTstate0 + here->VBICibc_Vbci); + Ibc_Vbei = *(ckt->CKTstate0 + here->VBICibc_Vbei); + Ibep_Vbep = *(ckt->CKTstate0 + here->VBICibep_Vbep); + Irci_Vrci = *(ckt->CKTstate0 + here->VBICirci_Vrci); + Irci_Vbci = *(ckt->CKTstate0 + here->VBICirci_Vbci); + Irci_Vbcx = *(ckt->CKTstate0 + here->VBICirci_Vbcx); + Irbi_Vrbi = *(ckt->CKTstate0 + here->VBICirbi_Vrbi); + Irbi_Vbei = *(ckt->CKTstate0 + here->VBICirbi_Vbei); + Irbi_Vbci = *(ckt->CKTstate0 + here->VBICirbi_Vbci); + Irbp_Vrbp = *(ckt->CKTstate0 + here->VBICirbp_Vrbp); + Irbp_Vbep = *(ckt->CKTstate0 + here->VBICirbp_Vbep); + Irbp_Vbci = *(ckt->CKTstate0 + here->VBICirbp_Vbci); + +/* +c The real part +*/ +/* +c Stamp element: Ibe +*/ + *(here->VBICbaseBIBaseBIPtr) += Ibe_Vbei; + *(here->VBICbaseBIEmitEIPtr) += -Ibe_Vbei; + *(here->VBICemitEIBaseBIPtr) += -Ibe_Vbei; + *(here->VBICemitEIEmitEIPtr) += Ibe_Vbei; +/* +c Stamp element: Ibex +*/ + *(here->VBICbaseBXBaseBXPtr) += Ibex_Vbex; + *(here->VBICbaseBXEmitEIPtr) += -Ibex_Vbex; + *(here->VBICemitEIBaseBXPtr) += -Ibex_Vbex; + *(here->VBICemitEIEmitEIPtr) += Ibex_Vbex; +/* +c Stamp element: Itzf +*/ + *(here->VBICcollCIBaseBIPtr) += Itzf_Vbei; + *(here->VBICcollCIEmitEIPtr) += -Itzf_Vbei; + *(here->VBICcollCIBaseBIPtr) += Itzf_Vbci; + *(here->VBICcollCICollCIPtr) += -Itzf_Vbci; + *(here->VBICemitEIBaseBIPtr) += -Itzf_Vbei; + *(here->VBICemitEIEmitEIPtr) += Itzf_Vbei; + *(here->VBICemitEIBaseBIPtr) += -Itzf_Vbci; + *(here->VBICemitEICollCIPtr) += Itzf_Vbci; +/* +c Stamp element: Itzr +*/ + *(here->VBICemitEIBaseBIPtr) += Itzr_Vbci; + *(here->VBICemitEICollCIPtr) += -Itzr_Vbci; + *(here->VBICemitEIBaseBIPtr) += Itzr_Vbei; + *(here->VBICemitEIEmitEIPtr) += -Itzr_Vbei; + *(here->VBICcollCIBaseBIPtr) += -Itzr_Vbci; + *(here->VBICcollCICollCIPtr) += Itzr_Vbci; + *(here->VBICcollCIBaseBIPtr) += -Itzr_Vbei; + *(here->VBICcollCIEmitEIPtr) += Itzr_Vbei; +/* +c Stamp element: Ibc +*/ + *(here->VBICbaseBIBaseBIPtr) += Ibc_Vbci; + *(here->VBICbaseBICollCIPtr) += -Ibc_Vbci; + *(here->VBICbaseBIBaseBIPtr) += Ibc_Vbei; + *(here->VBICbaseBIEmitEIPtr) += -Ibc_Vbei; + *(here->VBICcollCIBaseBIPtr) += -Ibc_Vbci; + *(here->VBICcollCICollCIPtr) += Ibc_Vbci; + *(here->VBICcollCIBaseBIPtr) += -Ibc_Vbei; + *(here->VBICcollCIEmitEIPtr) += Ibc_Vbei; +/* +c Stamp element: Ibep +*/ + *(here->VBICbaseBXBaseBXPtr) += Ibep_Vbep; + *(here->VBICbaseBXBaseBPPtr) += -Ibep_Vbep; + *(here->VBICbaseBPBaseBXPtr) += -Ibep_Vbep; + *(here->VBICbaseBPBaseBPPtr) += Ibep_Vbep; +/* +c Stamp element: Ircx +*/ + *(here->VBICcollCollPtr) += Ircx_Vrcx; + *(here->VBICcollCXCollCXPtr) += Ircx_Vrcx; + *(here->VBICcollCXCollPtr) += -Ircx_Vrcx; + *(here->VBICcollCollCXPtr) += -Ircx_Vrcx; +/* +c Stamp element: Irci +*/ + *(here->VBICcollCXCollCXPtr) += Irci_Vrci; + *(here->VBICcollCXCollCIPtr) += -Irci_Vrci; + *(here->VBICcollCXBaseBIPtr) += Irci_Vbci; + *(here->VBICcollCXCollCIPtr) += -Irci_Vbci; + *(here->VBICcollCXBaseBIPtr) += Irci_Vbcx; + *(here->VBICcollCXCollCXPtr) += -Irci_Vbcx; + *(here->VBICcollCICollCXPtr) += -Irci_Vrci; + *(here->VBICcollCICollCIPtr) += Irci_Vrci; + *(here->VBICcollCIBaseBIPtr) += -Irci_Vbci; + *(here->VBICcollCICollCIPtr) += Irci_Vbci; + *(here->VBICcollCIBaseBIPtr) += -Irci_Vbcx; + *(here->VBICcollCICollCXPtr) += Irci_Vbcx; +/* +c Stamp element: Irbx +*/ + *(here->VBICbaseBasePtr) += Irbx_Vrbx; + *(here->VBICbaseBXBaseBXPtr) += Irbx_Vrbx; + *(here->VBICbaseBXBasePtr) += -Irbx_Vrbx; + *(here->VBICbaseBaseBXPtr) += -Irbx_Vrbx; +/* +c Stamp element: Irbi +*/ + *(here->VBICbaseBXBaseBXPtr) += Irbi_Vrbi; + *(here->VBICbaseBXBaseBIPtr) += -Irbi_Vrbi; + *(here->VBICbaseBXBaseBIPtr) += Irbi_Vbei; + *(here->VBICbaseBXEmitEIPtr) += -Irbi_Vbei; + *(here->VBICbaseBXBaseBIPtr) += Irbi_Vbci; + *(here->VBICbaseBXCollCIPtr) += -Irbi_Vbci; + *(here->VBICbaseBIBaseBXPtr) += -Irbi_Vrbi; + *(here->VBICbaseBIBaseBIPtr) += Irbi_Vrbi; + *(here->VBICbaseBIBaseBIPtr) += -Irbi_Vbei; + *(here->VBICbaseBIEmitEIPtr) += Irbi_Vbei; + *(here->VBICbaseBIBaseBIPtr) += -Irbi_Vbci; + *(here->VBICbaseBICollCIPtr) += Irbi_Vbci; +/* +c Stamp element: Ire +*/ + *(here->VBICemitEmitPtr) += Ire_Vre; + *(here->VBICemitEIEmitEIPtr) += Ire_Vre; + *(here->VBICemitEIEmitPtr) += -Ire_Vre; + *(here->VBICemitEmitEIPtr) += -Ire_Vre; +/* +c Stamp element: Irbp +*/ + *(here->VBICbaseBPBaseBPPtr) += Irbp_Vrbp; + *(here->VBICbaseBPCollCXPtr) += -Irbp_Vrbp; + *(here->VBICbaseBPBaseBXPtr) += Irbp_Vbep; + *(here->VBICbaseBPBaseBPPtr) += -Irbp_Vbep; + *(here->VBICbaseBPBaseBIPtr) += Irbp_Vbci; + *(here->VBICbaseBPCollCIPtr) += -Irbp_Vbci; + *(here->VBICcollCXBaseBPPtr) += -Irbp_Vrbp; + *(here->VBICcollCXCollCXPtr) += Irbp_Vrbp; + *(here->VBICcollCXBaseBXPtr) += -Irbp_Vbep; + *(here->VBICcollCXBaseBPPtr) += Irbp_Vbep; + *(here->VBICcollCXBaseBIPtr) += -Irbp_Vbci; + *(here->VBICcollCXCollCIPtr) += Irbp_Vbci; +/* +c The complex part +*/ + XQbe_Vbei = *(ckt->CKTstate0 + here->VBICcqbe); + XQbe_Vbci = *(ckt->CKTstate0 + here->VBICcqbeci); + XQbex_Vbex = *(ckt->CKTstate0 + here->VBICcqbex); + XQbc_Vbci = *(ckt->CKTstate0 + here->VBICcqbc); + XQbcx_Vbcx = *(ckt->CKTstate0 + here->VBICcqbcx); + XQbep_Vbep = *(ckt->CKTstate0 + here->VBICcqbep); + XQbep_Vbci = *(ckt->CKTstate0 + here->VBICcqbepci); +/* +c Stamp element: Qbe +*/ + *(here->VBICbaseBIBaseBIPtr) += (XQbe_Vbei * (s->real)); + *(here->VBICbaseBIBaseBIPtr + 1) += (XQbe_Vbei * (s->imag)); + *(here->VBICbaseBIEmitEIPtr) += (-XQbe_Vbei * (s->real)); + *(here->VBICbaseBIEmitEIPtr + 1) += (-XQbe_Vbei * (s->imag)); + *(here->VBICbaseBIBaseBIPtr) += (XQbe_Vbci * (s->real)); + *(here->VBICbaseBIBaseBIPtr + 1) += (XQbe_Vbci * (s->imag)); + *(here->VBICbaseBICollCIPtr) += (-XQbe_Vbci * (s->real)); + *(here->VBICbaseBICollCIPtr + 1) += (-XQbe_Vbci * (s->imag)); + *(here->VBICemitEIBaseBIPtr) += (-XQbe_Vbei * (s->real)); + *(here->VBICemitEIBaseBIPtr + 1) += (-XQbe_Vbei * (s->imag)); + *(here->VBICemitEIEmitEIPtr) += (XQbe_Vbei * (s->real)); + *(here->VBICemitEIEmitEIPtr + 1) += (XQbe_Vbei * (s->imag)); + *(here->VBICemitEIBaseBIPtr) += (-XQbe_Vbci * (s->real)); + *(here->VBICemitEIBaseBIPtr + 1) += (-XQbe_Vbci * (s->imag)); + *(here->VBICemitEICollCIPtr) += (XQbe_Vbci * (s->real)); + *(here->VBICemitEICollCIPtr + 1) += (XQbe_Vbci * (s->imag)); +/* +c Stamp element: Qbex +*/ + *(here->VBICbaseBXBaseBXPtr) += (XQbex_Vbex * (s->real)); + *(here->VBICbaseBXBaseBXPtr + 1) += (XQbex_Vbex * (s->imag)); + *(here->VBICbaseBXEmitEIPtr) += (-XQbex_Vbex * (s->real)); + *(here->VBICbaseBXEmitEIPtr + 1) += (-XQbex_Vbex * (s->imag)); + *(here->VBICemitEIBaseBXPtr) += (-XQbex_Vbex * (s->real)); + *(here->VBICemitEIBaseBXPtr + 1) += (-XQbex_Vbex * (s->imag)); + *(here->VBICemitEIEmitEIPtr ) += (XQbex_Vbex * (s->real)); + *(here->VBICemitEIEmitEIPtr + 1) += (XQbex_Vbex * (s->imag)); +/* +c Stamp element: Qbc +*/ + *(here->VBICbaseBIBaseBIPtr) += (XQbc_Vbci * (s->real)); + *(here->VBICbaseBIBaseBIPtr + 1) += (XQbc_Vbci * (s->imag)); + *(here->VBICbaseBICollCIPtr) += (-XQbc_Vbci * (s->real)); + *(here->VBICbaseBICollCIPtr + 1) += (-XQbc_Vbci * (s->imag)); + *(here->VBICcollCIBaseBIPtr) += (-XQbc_Vbci * (s->real)); + *(here->VBICcollCIBaseBIPtr + 1) += (-XQbc_Vbci * (s->imag)); + *(here->VBICcollCICollCIPtr) += (XQbc_Vbci * (s->real)); + *(here->VBICcollCICollCIPtr + 1) += (XQbc_Vbci * (s->imag)); +/* +c Stamp element: Qbcx +*/ + *(here->VBICbaseBIBaseBIPtr) += (XQbcx_Vbcx * (s->real)); + *(here->VBICbaseBIBaseBIPtr + 1) += (XQbcx_Vbcx * (s->imag)); + *(here->VBICbaseBICollCXPtr) += (-XQbcx_Vbcx * (s->real)); + *(here->VBICbaseBICollCXPtr + 1) += (-XQbcx_Vbcx * (s->imag)); + *(here->VBICcollCXBaseBIPtr) += (-XQbcx_Vbcx * (s->real)); + *(here->VBICcollCXBaseBIPtr + 1) += (-XQbcx_Vbcx * (s->imag)); + *(here->VBICcollCXCollCXPtr) += (XQbcx_Vbcx * (s->real)); + *(here->VBICcollCXCollCXPtr + 1) += (XQbcx_Vbcx * (s->imag)); +/* +c Stamp element: Qbep +*/ + *(here->VBICbaseBXBaseBXPtr) += (XQbep_Vbep * (s->real)); + *(here->VBICbaseBXBaseBXPtr + 1) += (XQbep_Vbep * (s->imag)); + *(here->VBICbaseBXBaseBPPtr) += (-XQbep_Vbep * (s->real)); + *(here->VBICbaseBXBaseBPPtr + 1) += (-XQbep_Vbep * (s->imag)); + *(here->VBICbaseBXBaseBIPtr) += (XQbep_Vbci * (s->real)); + *(here->VBICbaseBXBaseBIPtr + 1) += (XQbep_Vbci * (s->imag)); + *(here->VBICbaseBXCollCIPtr) += (-XQbep_Vbci * (s->real)); + *(here->VBICbaseBXCollCIPtr + 1) += (-XQbep_Vbci * (s->imag)); + *(here->VBICbaseBPBaseBXPtr) += (-XQbep_Vbep * (s->real)); + *(here->VBICbaseBPBaseBXPtr + 1) += (-XQbep_Vbep * (s->imag)); + *(here->VBICbaseBPBaseBPPtr) += (XQbep_Vbep * (s->real)); + *(here->VBICbaseBPBaseBPPtr + 1) += (XQbep_Vbep * (s->imag)); + *(here->VBICbaseBPBaseBIPtr) += (-XQbep_Vbci * (s->real)); + *(here->VBICbaseBPBaseBIPtr + 1) += (-XQbep_Vbci * (s->imag)); + *(here->VBICbaseBPCollCIPtr) += (XQbep_Vbci * (s->real)); + *(here->VBICbaseBPCollCIPtr + 1) += (XQbep_Vbci * (s->imag)); + + } + } + return(OK); +} diff --git a/src/spicelib/devices/vbic/vbicsetup.c b/src/spicelib/devices/vbic/vbicsetup.c new file mode 100644 index 000000000..d156e6462 --- /dev/null +++ b/src/spicelib/devices/vbic/vbicsetup.c @@ -0,0 +1,557 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1995 Colin McAndrew Motorola +Spice3 Implementation: 2003 Dietmar Warning DAnalyse GmbH +**********/ + +/* + * This routine should only be called when circuit topology + * changes, since its computations do not depend on most + * device or model parameters, only on topology (as + * affected by emitter, collector, and base resistances) + */ + +#include "ngspice.h" +#include "cktdefs.h" +#include "smpdefs.h" +#include "vbicdefs.h" +#include "const.h" +#include "sperror.h" +#include "ifsim.h" +#include "suffix.h" + +int +VBICsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) + /* load the VBIC structure with those pointers needed later + * for fast matrix loading + */ +{ + VBICmodel *model = (VBICmodel*)inModel; + VBICinstance *here; + int error; + CKTnode *tmp; + + /* loop through all the transistor models */ + for( ; model != NULL; model = model->VBICnextModel ) { + + if(model->VBICtype != NPN && model->VBICtype != PNP) { + model->VBICtype = NPN; + } + if(!model->VBICtnomGiven) { + model->VBICtnom = 27.0; + } + if(!model->VBICextCollResistGiven) { + model->VBICextCollResist = 0.0; + } + if(!model->VBICintCollResistGiven) { + model->VBICintCollResist = 0.1; + } + if(!model->VBICepiSatVoltageGiven) { + model->VBICepiSatVoltage = 0.0; + } + if(!model->VBICepiDopingGiven) { + model->VBICepiDoping = 0.0; + } + if(!model->VBIChighCurFacGiven) { + model->VBIChighCurFac = 1.0; + } + if(!model->VBICextBaseResistGiven) { + model->VBICextBaseResist = 0.0; + } + if(!model->VBICintBaseResistGiven) { + model->VBICintBaseResist = 0.1; + } + if(!model->VBICemitterResistGiven) { + model->VBICemitterResist = 0.0; + } + if(!model->VBICsubstrateResistGiven) { + model->VBICsubstrateResist = 0.0; + } + if(!model->VBICparBaseResistGiven) { + model->VBICparBaseResist = 0.1; + } + if(!model->VBICsatCurGiven) { + model->VBICsatCur = 1e-16; + } + if(!model->VBICemissionCoeffFGiven) { + model->VBICemissionCoeffF = 1.0; + } + if(!model->VBICemissionCoeffRGiven) { + model->VBICemissionCoeffR = 1.0; + } + if(!model->VBICdeplCapLimitFGiven) { + model->VBICdeplCapLimitF = 0.9; + } + if(!model->VBICextOverlapCapBEGiven) { + model->VBICextOverlapCapBE = 0.0; + } + if(!model->VBICdepletionCapBEGiven) { + model->VBICdepletionCapBE = 0.0; + } + if(!model->VBICpotentialBEGiven) { + model->VBICpotentialBE = 0.75; + } + if(!model->VBICjunctionExpBEGiven) { + model->VBICjunctionExpBE = 0.33; + } + if(!model->VBICsmoothCapBEGiven) { + model->VBICsmoothCapBE = -0.5; + } + if(!model->VBICextOverlapCapBCGiven) { + model->VBICextOverlapCapBC = 0.0; + } + if(!model->VBICdepletionCapBCGiven) { + model->VBICdepletionCapBC = 0.0; + } + if(!model->VBICepiChargeGiven) { + model->VBICepiCharge = 0.0; + } + if(!model->VBICextCapBCGiven) { + model->VBICextCapBC = 0.0; + } + if(!model->VBICpotentialBCGiven) { + model->VBICpotentialBC = 0.75; + } + if(!model->VBICjunctionExpBCGiven) { + model->VBICjunctionExpBC = 0.33; + } + if(!model->VBICsmoothCapBCGiven) { + model->VBICsmoothCapBC = -0.5; + } + if(!model->VBICextCapSCGiven) { + model->VBICextCapSC = 0.0; + } + if(!model->VBICpotentialSCGiven) { + model->VBICpotentialSC = 0.75; + } + if(!model->VBICjunctionExpSCGiven) { + model->VBICjunctionExpSC = 0.33; + } + if(!model->VBICsmoothCapSCGiven) { + model->VBICsmoothCapSC = -0.5; + } + if(!model->VBICidealSatCurBEGiven) { + model->VBICidealSatCurBE = 1e-18; + } + if(!model->VBICportionIBEIGiven) { + model->VBICportionIBEI = 1.0; + } + if(!model->VBICidealEmissCoeffBEGiven) { + model->VBICidealEmissCoeffBE = 1.0; + } + if(!model->VBICnidealSatCurBEGiven) { + model->VBICnidealSatCurBE = 0.0; + } + if(!model->VBICnidealEmissCoeffBEGiven) { + model->VBICnidealEmissCoeffBE = 2.0; + } + if(!model->VBICidealSatCurBCGiven) { + model->VBICidealSatCurBC = 1e-16; + } + if(!model->VBICidealEmissCoeffBCGiven) { + model->VBICidealEmissCoeffBC = 1.0; + } + if(!model->VBICnidealSatCurBCGiven) { + model->VBICnidealSatCurBC = 0.0; + } + if(!model->VBICnidealEmissCoeffBCGiven) { + model->VBICnidealEmissCoeffBC = 2.0; + } + if(!model->VBICavalanchePar1BCGiven) { + model->VBICavalanchePar1BC = 0.0; + } + if(!model->VBICavalanchePar2BCGiven) { + model->VBICavalanchePar2BC = 0.0; + } + if(!model->VBICparasitSatCurGiven) { + model->VBICparasitSatCur = 0.0; + } + if(!model->VBICportionICCPGiven) { + model->VBICportionICCP = 1.0; + } + if(!model->VBICparasitFwdEmissCoeffGiven) { + model->VBICparasitFwdEmissCoeff = 1.0; + } + if(!model->VBICidealParasitSatCurBEGiven) { + model->VBICidealParasitSatCurBE = 0.0; + } + if(!model->VBICnidealParasitSatCurBEGiven) { + model->VBICnidealParasitSatCurBE = 0.0; + } + if(!model->VBICidealParasitSatCurBCGiven) { + model->VBICidealParasitSatCurBC = 0.0; + } + if(!model->VBICidealParasitEmissCoeffBCGiven) { + model->VBICidealParasitEmissCoeffBC = 1.0; + } + if(!model->VBICnidealParasitSatCurBCGiven) { + model->VBICnidealParasitSatCurBC = 0.0; + } + if(!model->VBICnidealParasitEmissCoeffBCGiven) { + model->VBICnidealParasitEmissCoeffBC = 2.0; + } + if(!model->VBICearlyVoltFGiven) { + model->VBICearlyVoltF = 0.0; + } + if(!model->VBICearlyVoltRGiven) { + model->VBICearlyVoltR = 0.0; + } + if(!model->VBICrollOffFGiven) { + model->VBICrollOffF = 0.0; + } + if(!model->VBICrollOffRGiven) { + model->VBICrollOffR = 0.0; + } + if(!model->VBICparRollOffGiven) { + model->VBICparRollOff = 0.0; + } + if(!model->VBICtransitTimeFGiven) { + model->VBICtransitTimeF = 0.0; + } + if(!model->VBICvarTransitTimeFGiven) { + model->VBICvarTransitTimeF = 0.0; + } + if(!model->VBICtransitTimeBiasCoeffFGiven) { + model->VBICtransitTimeBiasCoeffF = 0.0; + } + if(!model->VBICtransitTimeFVBCGiven) { + model->VBICtransitTimeFVBC = 0.0; + } + if(!model->VBICtransitTimeHighCurrentFGiven) { + model->VBICtransitTimeHighCurrentF = 0.0; + } + if(!model->VBICtransitTimeRGiven) { + model->VBICtransitTimeR = 0.0; + } + if(!model->VBICdelayTimeFGiven) { + model->VBICdelayTimeF = 0.0; + } + if(!model->VBICfNcoefGiven) { + model->VBICfNcoef = 0.0; + } + if(!model->VBICfNexpAGiven) { + model->VBICfNexpA = 1.0; + } + if(!model->VBICfNexpBGiven) { + model->VBICfNexpB = 1.0; + } + if(!model->VBICtempExpREGiven) { + model->VBICtempExpRE = 0.0; + } + if(!model->VBICtempExpRBIGiven) { + model->VBICtempExpRBI = 0.0; + } + if(!model->VBICtempExpRCIGiven) { + model->VBICtempExpRCI = 0.0; + } + if(!model->VBICtempExpRSGiven) { + model->VBICtempExpRS = 0.0; + } + if(!model->VBICtempExpVOGiven) { + model->VBICtempExpVO = 0.0; + } + if(!model->VBICactivEnergyEAGiven) { + model->VBICactivEnergyEA = 1.12; + } + if(!model->VBICactivEnergyEAIEGiven) { + model->VBICactivEnergyEAIE = 1.12; + } + if(!model->VBICactivEnergyEAICGiven) { + model->VBICactivEnergyEAIC = 1.12; + } + if(!model->VBICactivEnergyEAISGiven) { + model->VBICactivEnergyEAIS = 1.12; + } + if(!model->VBICactivEnergyEANEGiven) { + model->VBICactivEnergyEANE = 1.12; + } + if(!model->VBICactivEnergyEANCGiven) { + model->VBICactivEnergyEANC = 1.12; + } + if(!model->VBICactivEnergyEANSGiven) { + model->VBICactivEnergyEANS = 1.12; + } + if(!model->VBICtempExpISGiven) { + model->VBICtempExpIS = 3.0; + } + if(!model->VBICtempExpIIGiven) { + model->VBICtempExpII = 3.0; + } + if(!model->VBICtempExpINGiven) { + model->VBICtempExpIN = 3.0; + } + if(!model->VBICtempExpNFGiven) { + model->VBICtempExpNF = 0.0; + } + if(!model->VBICtempExpAVCGiven) { + model->VBICtempExpAVC = 0.0; + } + if(!model->VBICthermalResistGiven) { + model->VBICthermalResist = 0.0; + } + if(!model->VBICthermalCapacitanceGiven) { + model->VBICthermalCapacitance = 0.0; + } + if(!model->VBICpunchThroughVoltageBCGiven) { + model->VBICpunchThroughVoltageBC = 0.0; + } + if(!model->VBICdeplCapCoeff1Given) { + model->VBICdeplCapCoeff1 = 0.1; + } + if(!model->VBICfixedCapacitanceCSGiven) { + model->VBICfixedCapacitanceCS = 0.0; + } + if(!model->VBICsgpQBselectorGiven) { + model->VBICsgpQBselector = 0.0; + } + if(!model->VBIChighCurrentBetaRolloffGiven) { + model->VBIChighCurrentBetaRolloff = 0.5; + } + if(!model->VBICtempExpIKFGiven) { + model->VBICtempExpIKF = 0.0; + } + if(!model->VBICtempExpRCXGiven) { + model->VBICtempExpRCX = 0.0; + } + if(!model->VBICtempExpRBXGiven) { + model->VBICtempExpRBX = 0.0; + } + if(!model->VBICtempExpRBPGiven) { + model->VBICtempExpRBP = 0.0; + } + if(!model->VBICsepISRRGiven) { + model->VBICsepISRR = 1.0; + } + if(!model->VBICtempExpXISRGiven) { + model->VBICtempExpXISR = 0.0; + } + if(!model->VBICdearGiven) { + model->VBICdear = 0.0; + } + if(!model->VBICeapGiven) { + model->VBICeap = 1.12; + } + if(!model->VBICvbbeGiven) { + model->VBICvbbe = 0.0; + } + if(!model->VBICnbbeGiven) { + model->VBICnbbe = 1.0; + } + if(!model->VBICibbeGiven) { + model->VBICibbe = 1e-06; + } + if(!model->VBICtvbbe1Given) { + model->VBICtvbbe1 = 0.0; + } + if(!model->VBICtvbbe2Given) { + model->VBICtvbbe2 = 0.0; + } + if(!model->VBICtnbbeGiven) { + model->VBICtnbbe = 0.0; + } + if(!model->VBICebbeGiven) { + model->VBICebbe = 0.0; + } + if(!model->VBIClocTempDiffGiven) { + model->VBIClocTempDiff = 0.0; + } + if(!model->VBICrevVersionGiven) { + model->VBICrevVersion = 1.2; + } + if(!model->VBICrefVersionGiven) { + model->VBICrefVersion = 0.0; + } + + /* loop through all the instances of the model */ + for (here = model->VBICinstances; here != NULL ; + here=here->VBICnextInstance) { + CKTnode *tmpNode; + IFuid tmpName; + + if (here->VBICowner != ARCHme) + goto matrixpointers; + + if(!here->VBICareaGiven) { + here->VBICarea = 1.0; + } + if(!here->VBICmGiven) { + here->VBICm = 1.0; + } + if(!here->VBICdtempGiven) { + here->VBICdtemp = 0.0; + } + + here->VBICstate = *states; + *states += VBICnumStates; + if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN) ){ + *states += 8 * (ckt->CKTsenInfo->SENparms); + } + +matrixpointers: + if(model->VBICextCollResist == 0) { + here->VBICcollCXNode = here->VBICcollNode; + } else if(here->VBICcollCXNode == 0) { + error = CKTmkVolt(ckt,&tmp,here->VBICname,"collector"); + if(error) return(error); + here->VBICcollCXNode = tmp->number; + if (ckt->CKTcopyNodesets) { + if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; + } + } + } + } + if(model->VBICextBaseResist == 0) { + here->VBICbaseBXNode = here->VBICbaseNode; + } else if(here->VBICbaseBXNode == 0){ + error = CKTmkVolt(ckt,&tmp,here->VBICname, "base"); + if(error) return(error); + here->VBICbaseBXNode = tmp->number; + if (ckt->CKTcopyNodesets) { + if (CKTinst2Node(ckt,here,2,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; + } + } + } + } + if(model->VBICemitterResist == 0) { + here->VBICemitEINode = here->VBICemitNode; + } else if(here->VBICemitEINode == 0) { + error = CKTmkVolt(ckt,&tmp,here->VBICname, "emitter"); + if(error) return(error); + here->VBICemitEINode = tmp->number; + if (ckt->CKTcopyNodesets) { + if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; + } + } + } + } + + error = CKTmkVolt(ckt, &tmp, here->VBICname, "collCI"); + if(error) return(error); + here->VBICcollCINode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->VBICname, "baseBP"); + if(error) return(error); + here->VBICbaseBPNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->VBICname, "baseBI"); + if(error) return(error); + here->VBICbaseBINode = tmp->number; + +/* macro to make elements with built in test for out of memory */ +#define TSTALLOC(ptr,first,second) \ +if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\ + return(E_NOMEM);\ +} + TSTALLOC(VBICcollCollPtr,VBICcollNode,VBICcollNode) + TSTALLOC(VBICbaseBasePtr,VBICbaseNode,VBICbaseNode) + TSTALLOC(VBICemitEmitPtr,VBICemitNode,VBICemitNode) + TSTALLOC(VBICcollCXCollCXPtr,VBICcollCXNode,VBICcollCXNode) + TSTALLOC(VBICcollCICollCIPtr,VBICcollCINode,VBICcollCINode) + TSTALLOC(VBICbaseBXBaseBXPtr,VBICbaseBXNode,VBICbaseBXNode) + TSTALLOC(VBICbaseBIBaseBIPtr,VBICbaseBINode,VBICbaseBINode) + TSTALLOC(VBICemitEIEmitEIPtr,VBICemitEINode,VBICemitEINode) + TSTALLOC(VBICbaseBPBaseBPPtr,VBICbaseBPNode,VBICbaseBPNode) + + TSTALLOC(VBICbaseEmitPtr,VBICbaseNode,VBICemitNode) + TSTALLOC(VBICemitBasePtr,VBICemitNode,VBICbaseNode) + TSTALLOC(VBICbaseCollPtr,VBICbaseNode,VBICcollNode) + TSTALLOC(VBICcollBasePtr,VBICcollNode,VBICbaseNode) + TSTALLOC(VBICcollCollCXPtr,VBICcollNode,VBICcollCXNode) + TSTALLOC(VBICbaseBaseBXPtr,VBICbaseNode,VBICbaseBXNode) + TSTALLOC(VBICemitEmitEIPtr,VBICemitNode,VBICemitEINode) + TSTALLOC(VBICcollCXCollCIPtr,VBICcollCXNode,VBICcollCINode) + TSTALLOC(VBICcollCXBaseBXPtr,VBICcollCXNode,VBICbaseBXNode) + TSTALLOC(VBICcollCXBaseBIPtr,VBICcollCXNode,VBICbaseBINode) + TSTALLOC(VBICcollCXBaseBPPtr,VBICcollCXNode,VBICbaseBPNode) + TSTALLOC(VBICcollCIBaseBIPtr,VBICcollCINode,VBICbaseBINode) + TSTALLOC(VBICcollCIEmitEIPtr,VBICcollCINode,VBICemitEINode) + TSTALLOC(VBICbaseBXBaseBIPtr,VBICbaseBXNode,VBICbaseBINode) + TSTALLOC(VBICbaseBXEmitEIPtr,VBICbaseBXNode,VBICemitEINode) + TSTALLOC(VBICbaseBXBaseBPPtr,VBICbaseBXNode,VBICbaseBPNode) + TSTALLOC(VBICbaseBIEmitEIPtr,VBICbaseBINode,VBICemitEINode) + + TSTALLOC(VBICcollCXCollPtr,VBICcollCXNode,VBICcollNode) + TSTALLOC(VBICbaseBXBasePtr,VBICbaseBXNode,VBICbaseNode) + TSTALLOC(VBICemitEIEmitPtr,VBICemitEINode,VBICemitNode) + TSTALLOC(VBICcollCICollCXPtr,VBICcollCINode,VBICcollCXNode) + TSTALLOC(VBICbaseBICollCXPtr,VBICbaseBINode,VBICcollCXNode) + TSTALLOC(VBICbaseBPCollCXPtr,VBICbaseBPNode,VBICcollCXNode) + TSTALLOC(VBICbaseBXCollCIPtr,VBICbaseBXNode,VBICcollCINode) + TSTALLOC(VBICbaseBICollCIPtr,VBICbaseBINode,VBICcollCINode) + TSTALLOC(VBICemitEICollCIPtr,VBICemitEINode,VBICcollCINode) + TSTALLOC(VBICbaseBPCollCIPtr,VBICbaseBPNode,VBICcollCINode) + TSTALLOC(VBICbaseBIBaseBXPtr,VBICbaseBINode,VBICbaseBXNode) + TSTALLOC(VBICemitEIBaseBXPtr,VBICemitEINode,VBICbaseBXNode) + TSTALLOC(VBICbaseBPBaseBXPtr,VBICbaseBPNode,VBICbaseBXNode) + TSTALLOC(VBICemitEIBaseBIPtr,VBICemitEINode,VBICbaseBINode) + TSTALLOC(VBICbaseBPBaseBIPtr,VBICbaseBPNode,VBICbaseBINode) + + } + } + return(OK); +} + +int +VBICunsetup(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + VBICmodel *model; + VBICinstance *here; + + for (model = (VBICmodel *)inModel; model != NULL; + model = model->VBICnextModel) + { + for (here = model->VBICinstances; here != NULL; + here=here->VBICnextInstance) + { + if (here->VBICcollCXNode + && here->VBICcollCXNode != here->VBICcollNode) + { + CKTdltNNum(ckt, here->VBICcollCXNode); + here->VBICcollCXNode = 0; + } + if (here->VBICcollCINode + && here->VBICcollCINode != here->VBICcollNode) + { + CKTdltNNum(ckt, here->VBICcollCINode); + here->VBICcollCINode = 0; + } + if (here->VBICbaseBXNode + && here->VBICbaseBXNode != here->VBICbaseNode) + { + CKTdltNNum(ckt, here->VBICbaseBXNode); + here->VBICbaseBXNode = 0; + } + if (here->VBICbaseBINode + && here->VBICbaseBINode != here->VBICbaseNode) + { + CKTdltNNum(ckt, here->VBICbaseBINode); + here->VBICbaseBINode = 0; + } + if (here->VBICbaseBPNode + && here->VBICbaseBPNode != here->VBICbaseNode) + { + CKTdltNNum(ckt, here->VBICbaseBPNode); + here->VBICbaseBPNode = 0; + } + if (here->VBICemitEINode + && here->VBICemitEINode != here->VBICemitNode) + { + CKTdltNNum(ckt, here->VBICemitEINode); + here->VBICemitEINode = 0; + } + } + } + return OK; +} diff --git a/src/spicelib/devices/vbic/vbictemp.c b/src/spicelib/devices/vbic/vbictemp.c new file mode 100644 index 000000000..58bfebc0a --- /dev/null +++ b/src/spicelib/devices/vbic/vbictemp.c @@ -0,0 +1,468 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1995 Colin McAndrew Motorola +Spice3 Implementation: 2003 Dietmar Warning DAnalyse GmbH +**********/ + +#include "ngspice.h" +#include "cktdefs.h" +#include "smpdefs.h" +#include "vbicdefs.h" +#include "const.h" +#include "sperror.h" +#include "ifsim.h" +#include "suffix.h" + + +/* ARGSUSED */ +int +VBICtemp(GENmodel *inModel, CKTcircuit *ckt) + /* Pre-compute many useful parameters + */ +{ + VBICmodel *model = (VBICmodel *)inModel; + VBICinstance *here; + double p[108], pnom[108], TAMB; + int iret, vbic_3T_it_cf_t(double *, double *, double *); + double vt; + + /* loop through all the bipolar models */ + for( ; model != NULL; model = model->VBICnextModel ) { + + if(!model->VBICtnomGiven) model->VBICtnom = ckt->CKTnomTemp - CONSTCtoK; + + if(model->VBICextCollResistGiven && model->VBICextCollResist != 0.0) { + model->VBICcollectorConduct = 1.0 / model->VBICextCollResist; + } else { + model->VBICcollectorConduct = 0.0; + } + if(model->VBICextBaseResistGiven && model->VBICextBaseResist != 0.0) { + model->VBICbaseConduct = 1.0 / model->VBICextBaseResist; + } else { + model->VBICbaseConduct = 0.0; + } + if(model->VBICemitterResistGiven && model->VBICemitterResist != 0.0) { + model->VBICemitterConduct = 1.0 / model->VBICemitterResist; + } else { + model->VBICemitterConduct = 0.0; + } + + /* loop through all the instances of the model */ + for (here = model->VBICinstances; here != NULL ; + here=here->VBICnextInstance) { + if (here->VBICowner != ARCHme) continue; + + if(!here->VBICtempGiven) here->VBICtemp = ckt->CKTtemp; + + if(here->VBICdtempGiven) here->VBICtemp = here->VBICtemp + here->VBICdtemp; + + TAMB = here->VBICtemp - CONSTCtoK; + + pnom[0] = model->VBICtnom; + pnom[1] = model->VBICextCollResist; + pnom[2] = model->VBICintCollResist; + pnom[3] = model->VBICepiSatVoltage; + pnom[4] = model->VBICepiDoping; + pnom[5] = model->VBIChighCurFac; + pnom[6] = model->VBICextBaseResist; + pnom[7] = model->VBICintBaseResist; + pnom[8] = model->VBICemitterResist; + pnom[9] = model->VBICsubstrateResist; + pnom[10] = model->VBICparBaseResist; + pnom[11] = model->VBICsatCur; + pnom[12] = model->VBICemissionCoeffF; + pnom[13] = model->VBICemissionCoeffR; + pnom[14] = model->VBICdeplCapLimitF; + pnom[15] = model->VBICextOverlapCapBE; + pnom[16] = model->VBICdepletionCapBE; + pnom[17] = model->VBICpotentialBE; + pnom[18] = model->VBICjunctionExpBE; + pnom[19] = model->VBICsmoothCapBE; + pnom[20] = model->VBICextOverlapCapBC; + pnom[21] = model->VBICdepletionCapBC; + pnom[22] = model->VBICepiCharge; + pnom[23] = model->VBICextCapBC; + pnom[24] = model->VBICpotentialBC; + pnom[25] = model->VBICjunctionExpBC; + pnom[26] = model->VBICsmoothCapBC; + pnom[27] = model->VBICextCapSC; + pnom[28] = model->VBICpotentialSC; + pnom[29] = model->VBICjunctionExpSC; + pnom[30] = model->VBICsmoothCapSC; + pnom[31] = model->VBICidealSatCurBE; + pnom[32] = model->VBICportionIBEI; + pnom[33] = model->VBICidealEmissCoeffBE; + pnom[34] = model->VBICnidealSatCurBE; + pnom[35] = model->VBICnidealEmissCoeffBE; + pnom[36] = model->VBICidealSatCurBC; + pnom[37] = model->VBICidealEmissCoeffBC; + pnom[38] = model->VBICnidealSatCurBC; + pnom[39] = model->VBICnidealEmissCoeffBC; + pnom[40] = model->VBICavalanchePar1BC; + pnom[41] = model->VBICavalanchePar2BC; + pnom[42] = model->VBICparasitSatCur; + pnom[43] = model->VBICportionICCP; + pnom[44] = model->VBICparasitFwdEmissCoeff; + pnom[45] = model->VBICidealParasitSatCurBE; + pnom[46] = model->VBICnidealParasitSatCurBE; + pnom[47] = model->VBICidealParasitSatCurBC; + pnom[48] = model->VBICidealParasitEmissCoeffBC; + pnom[49] = model->VBICnidealParasitSatCurBC; + pnom[50] = model->VBICnidealParasitEmissCoeffBC; + pnom[51] = model->VBICearlyVoltF; + pnom[52] = model->VBICearlyVoltR; + pnom[53] = model->VBICrollOffF; + pnom[54] = model->VBICrollOffR; + pnom[55] = model->VBICparRollOff; + pnom[56] = model->VBICtransitTimeF; + pnom[57] = model->VBICvarTransitTimeF; + pnom[58] = model->VBICtransitTimeBiasCoeffF; + pnom[59] = model->VBICtransitTimeFVBC; + pnom[60] = model->VBICtransitTimeHighCurrentF; + pnom[61] = model->VBICtransitTimeR; + pnom[62] = model->VBICdelayTimeF; + pnom[63] = model->VBICfNcoef; + pnom[64] = model->VBICfNexpA; + pnom[65] = model->VBICfNexpB; + pnom[66] = model->VBICtempExpRE; + pnom[67] = model->VBICtempExpRBI; + pnom[68] = model->VBICtempExpRCI; + pnom[69] = model->VBICtempExpRS; + pnom[70] = model->VBICtempExpVO; + pnom[71] = model->VBICactivEnergyEA; + pnom[72] = model->VBICactivEnergyEAIE; + pnom[73] = model->VBICactivEnergyEAIC; + pnom[74] = model->VBICactivEnergyEAIS; + pnom[75] = model->VBICactivEnergyEANE; + pnom[76] = model->VBICactivEnergyEANC; + pnom[77] = model->VBICactivEnergyEANS; + pnom[78] = model->VBICtempExpIS; + pnom[79] = model->VBICtempExpII; + pnom[80] = model->VBICtempExpIN; + pnom[81] = model->VBICtempExpNF; + pnom[82] = model->VBICtempExpAVC; + pnom[83] = model->VBICthermalResist; + pnom[84] = model->VBICthermalCapacitance; + pnom[85] = model->VBICpunchThroughVoltageBC; + pnom[86] = model->VBICdeplCapCoeff1; + pnom[87] = model->VBICfixedCapacitanceCS; + pnom[88] = model->VBICsgpQBselector; + pnom[89] = model->VBIChighCurrentBetaRolloff; + pnom[90] = model->VBICtempExpIKF; + pnom[91] = model->VBICtempExpRCX; + pnom[92] = model->VBICtempExpRBX; + pnom[93] = model->VBICtempExpRBP; + pnom[94] = model->VBICsepISRR; + pnom[95] = model->VBICtempExpXISR; + pnom[96] = model->VBICdear; + pnom[97] = model->VBICeap; + pnom[98] = model->VBICvbbe; + pnom[99] = model->VBICnbbe; + pnom[100] = model->VBICibbe; + pnom[101] = model->VBICtvbbe1; + pnom[102] = model->VBICtvbbe2; + pnom[103] = model->VBICtnbbe; + pnom[104] = model->VBICebbe; + pnom[105] = model->VBIClocTempDiff; + pnom[106] = model->VBICrevVersion; + pnom[107] = model->VBICrefVersion; + + iret = vbic_3T_it_cf_t(p,pnom,&TAMB); + + here->VBICttnom = p[0]; + here->VBICtextCollResist = p[1]; + here->VBICtintCollResist = p[2]; + here->VBICtepiSatVoltage = p[3]; + here->VBICtepiDoping = p[4]; + here->VBICtextBaseResist = p[6]; + here->VBICtintBaseResist = p[7]; + here->VBICtemitterResist = p[8]; + here->VBICtsubstrateResist = p[9]; + here->VBICtparBaseResist = p[10]; + here->VBICtsatCur = p[11]; + here->VBICtemissionCoeffF = p[12]; + here->VBICtemissionCoeffR = p[13]; + here->VBICtdepletionCapBE = p[16]; + here->VBICtpotentialBE = p[17]; + here->VBICtdepletionCapBC = p[21]; + here->VBICtextCapBC = p[23]; + here->VBICtpotentialBC = p[24]; + here->VBICtextCapSC = p[27]; + here->VBICtpotentialSC = p[28]; + here->VBICtidealSatCurBE = p[31]; + here->VBICtnidealSatCurBE = p[34]; + here->VBICtidealSatCurBC = p[36]; + here->VBICtnidealSatCurBC = p[38]; + here->VBICtavalanchePar2BC = p[41]; + here->VBICtparasitSatCur = p[42]; + here->VBICtidealParasitSatCurBE = p[45]; + here->VBICtnidealParasitSatCurBE = p[46]; + here->VBICtidealParasitSatCurBC = p[47]; + here->VBICtnidealParasitSatCurBC = p[49]; + here->VBICtrollOffF = p[53]; + here->VBICtsepISRR = p[94]; + here->VBICtvbbe = p[98]; + here->VBICtnbbe = p[99]; + + vt = here->VBICtemp * CONSTKoverQ; + here->VBICtVcrit = vt * + log(vt / (CONSTroot2*model->VBICsatCur*here->VBICarea*here->VBICm)); + } + } + return(OK); +} + +int vbic_3T_it_cf_t(p,pnom,TAMB) +double *p, *pnom, *TAMB; +{ + double Tini, Tdev, Vtv, rT, dT, xvar1; + double xvar2, xvar3, xvar4, xvar5, xvar6, psiio; + double psiin; + +/* Direct copy p<-pnom for temperature independent parameters */ + + p[5]=pnom[5]; + p[14]=pnom[14]; + p[15]=pnom[15]; + p[18]=pnom[18]; + p[19]=pnom[19]; + p[20]=pnom[20]; + p[22]=pnom[22]; + p[25]=pnom[25]; + p[26]=pnom[26]; + p[29]=pnom[29]; + p[30]=pnom[30]; + p[32]=pnom[32]; + p[33]=pnom[33]; + p[35]=pnom[35]; + p[37]=pnom[37]; + p[39]=pnom[39]; + p[40]=pnom[40]; + p[43]=pnom[43]; + p[44]=pnom[44]; + p[48]=pnom[48]; + p[50]=pnom[50]; + p[51]=pnom[51]; + p[52]=pnom[52]; + p[54]=pnom[54]; + p[55]=pnom[55]; + p[56]=pnom[56]; + p[57]=pnom[57]; + p[58]=pnom[58]; + p[59]=pnom[59]; + p[60]=pnom[60]; + p[61]=pnom[61]; + p[62]=pnom[62]; + p[63]=pnom[63]; + p[64]=pnom[64]; + p[65]=pnom[65]; + p[66]=pnom[66]; + p[67]=pnom[67]; + p[68]=pnom[68]; + p[69]=pnom[69]; + p[70]=pnom[70]; + p[71]=pnom[71]; + p[72]=pnom[72]; + p[73]=pnom[73]; + p[74]=pnom[74]; + p[75]=pnom[75]; + p[76]=pnom[76]; + p[77]=pnom[77]; + p[78]=pnom[78]; + p[79]=pnom[79]; + p[80]=pnom[80]; + p[81]=pnom[81]; + p[82]=pnom[82]; + p[83]=pnom[83]; + p[84]=pnom[84]; + p[85]=pnom[85]; + p[86]=pnom[86]; + p[87]=pnom[87]; + p[88]=pnom[88]; + p[89]=pnom[89]; + p[90]=pnom[90]; + p[91]=pnom[91]; + p[92]=pnom[92]; + p[93]=pnom[93]; + p[95]=pnom[95]; + p[96]=pnom[96]; + p[97]=pnom[97]; + p[100]=pnom[100]; + p[101]=pnom[101]; + p[102]=pnom[102]; + p[103]=pnom[103]; + p[105]=pnom[105]; + p[106]=pnom[106]; + p[107]=pnom[107]; + +/* Temperature mappings for model parameters */ + + Tini=2.731500e+02+pnom[0]; + Tdev=(2.731500e+02+(*TAMB))+pnom[105]; + Vtv=1.380662e-23*Tdev/1.602189e-19; + rT=Tdev/Tini; + dT=Tdev-Tini; + xvar1=pow(rT,pnom[90]); + p[53]=pnom[53]*xvar1; + xvar1=pow(rT,pnom[91]); + p[1]=pnom[1]*xvar1; + xvar1=pow(rT,pnom[68]); + p[2]=pnom[2]*xvar1; + xvar1=pow(rT,pnom[92]); + p[6]=pnom[6]*xvar1; + xvar1=pow(rT,pnom[67]); + p[7]=pnom[7]*xvar1; + xvar1=pow(rT,pnom[66]); + p[8]=pnom[8]*xvar1; + xvar1=pow(rT,pnom[69]); + p[9]=pnom[9]*xvar1; + xvar1=pow(rT,pnom[93]); + p[10]=pnom[10]*xvar1; + xvar2=pow(rT,pnom[78]); + xvar3=-pnom[71]*(1.0-rT)/Vtv; + xvar4=exp(xvar3); + xvar1=(xvar2*xvar4); + xvar5=(1.0/pnom[12]); + xvar6=pow(xvar1,xvar5); + p[11]=pnom[11]*xvar6; + xvar2=pow(rT,pnom[95]); + xvar3=-pnom[96]*(1.0-rT)/Vtv; + xvar4=exp(xvar3); + xvar1=(xvar2*xvar4); + xvar5=(1.0/pnom[13]); + xvar6=pow(xvar1,xvar5); + p[94]=pnom[94]*xvar6; + xvar2=pow(rT,pnom[78]); + xvar3=-pnom[97]*(1.0-rT)/Vtv; + xvar4=exp(xvar3); + xvar1=(xvar2*xvar4); + xvar5=(1.0/pnom[44]); + xvar6=pow(xvar1,xvar5); + p[42]=pnom[42]*xvar6; + xvar2=pow(rT,pnom[79]); + xvar3=-pnom[72]*(1.0-rT)/Vtv; + xvar4=exp(xvar3); + xvar1=(xvar2*xvar4); + xvar5=(1.0/pnom[33]); + xvar6=pow(xvar1,xvar5); + p[31]=pnom[31]*xvar6; + xvar2=pow(rT,pnom[80]); + xvar3=-pnom[75]*(1.0-rT)/Vtv; + xvar4=exp(xvar3); + xvar1=(xvar2*xvar4); + xvar5=(1.0/pnom[35]); + xvar6=pow(xvar1,xvar5); + p[34]=pnom[34]*xvar6; + xvar2=pow(rT,pnom[79]); + xvar3=-pnom[73]*(1.0-rT)/Vtv; + xvar4=exp(xvar3); + xvar1=(xvar2*xvar4); + xvar5=(1.0/pnom[37]); + xvar6=pow(xvar1,xvar5); + p[36]=pnom[36]*xvar6; + xvar2=pow(rT,pnom[80]); + xvar3=-pnom[76]*(1.0-rT)/Vtv; + xvar4=exp(xvar3); + xvar1=(xvar2*xvar4); + xvar5=(1.0/pnom[39]); + xvar6=pow(xvar1,xvar5); + p[38]=pnom[38]*xvar6; + xvar2=pow(rT,pnom[79]); + xvar3=-pnom[73]*(1.0-rT)/Vtv; + xvar4=exp(xvar3); + xvar1=(xvar2*xvar4); + xvar5=(1.0/pnom[37]); + xvar6=pow(xvar1,xvar5); + p[45]=pnom[45]*xvar6; + xvar2=pow(rT,pnom[80]); + xvar3=-pnom[76]*(1.0-rT)/Vtv; + xvar4=exp(xvar3); + xvar1=(xvar2*xvar4); + xvar5=(1.0/pnom[39]); + xvar6=pow(xvar1,xvar5); + p[46]=pnom[46]*xvar6; + xvar2=pow(rT,pnom[79]); + xvar3=-pnom[74]*(1.0-rT)/Vtv; + xvar4=exp(xvar3); + xvar1=(xvar2*xvar4); + xvar5=(1.0/pnom[48]); + xvar6=pow(xvar1,xvar5); + p[47]=pnom[47]*xvar6; + xvar2=pow(rT,pnom[80]); + xvar3=-pnom[77]*(1.0-rT)/Vtv; + xvar4=exp(xvar3); + xvar1=(xvar2*xvar4); + xvar5=(1.0/pnom[50]); + xvar6=pow(xvar1,xvar5); + p[49]=pnom[49]*xvar6; + p[12]=pnom[12]*(1.0+dT*pnom[81]); + p[13]=pnom[13]*(1.0+dT*pnom[81]); + p[41]=pnom[41]*(1.0+dT*pnom[82]); + p[98]=pnom[98]*(1.0+dT*(pnom[101]+dT*pnom[102])); + p[99]=pnom[99]*(1.0+dT*pnom[103]); + xvar2=0.5*pnom[17]*rT/Vtv; + xvar3=exp(xvar2); + xvar4=-0.5*pnom[17]*rT/Vtv; + xvar5=exp(xvar4); + xvar1=xvar3-xvar5; + xvar6=log(xvar1); + psiio=2.0*(Vtv/rT)*xvar6; + xvar1=log(rT); + psiin=psiio*rT-3.0*Vtv*xvar1-pnom[72]*(rT-1.0); + xvar2=-psiin/Vtv; + xvar3=exp(xvar2); + xvar1=0.5*(1.0+sqrt(1.0+4.0*xvar3)); + xvar4=log(xvar1); + p[17]=psiin+2.0*Vtv*xvar4; + xvar2=0.5*pnom[24]*rT/Vtv; + xvar3=exp(xvar2); + xvar4=-0.5*pnom[24]*rT/Vtv; + xvar5=exp(xvar4); + xvar1=xvar3-xvar5; + xvar6=log(xvar1); + psiio=2.0*(Vtv/rT)*xvar6; + xvar1=log(rT); + psiin=psiio*rT-3.0*Vtv*xvar1-pnom[73]*(rT-1.0); + xvar2=-psiin/Vtv; + xvar3=exp(xvar2); + xvar1=0.5*(1.0+sqrt(1.0+4.0*xvar3)); + xvar4=log(xvar1); + p[24]=psiin+2.0*Vtv*xvar4; + xvar2=0.5*pnom[28]*rT/Vtv; + xvar3=exp(xvar2); + xvar4=-0.5*pnom[28]*rT/Vtv; + xvar5=exp(xvar4); + xvar1=xvar3-xvar5; + xvar6=log(xvar1); + psiio=2.0*(Vtv/rT)*xvar6; + xvar1=log(rT); + psiin=psiio*rT-3.0*Vtv*xvar1-pnom[74]*(rT-1.0); + xvar2=-psiin/Vtv; + xvar3=exp(xvar2); + xvar1=0.5*(1.0+sqrt(1.0+4.0*xvar3)); + xvar4=log(xvar1); + p[28]=psiin+2.0*Vtv*xvar4; + xvar1=pnom[17]/p[17]; + xvar2=pow(xvar1,pnom[18]); + p[16]=pnom[16]*xvar2; + xvar1=pnom[24]/p[24]; + xvar2=pow(xvar1,pnom[25]); + p[21]=pnom[21]*xvar2; + xvar1=pnom[24]/p[24]; + xvar2=pow(xvar1,pnom[25]); + p[23]=pnom[23]*xvar2; + xvar1=pnom[28]/p[28]; + xvar2=pow(xvar1,pnom[29]); + p[27]=pnom[27]*xvar2; + xvar1=pow(rT,pnom[78]); + xvar2=-pnom[71]*(1.0-rT)/Vtv; + xvar3=exp(xvar2); + p[4]=pnom[4]*xvar1*xvar3; + xvar1=pow(rT,pnom[70]); + p[3]=pnom[3]*xvar1; + xvar1=-p[98]/(p[99]*Vtv); + p[104]=exp(xvar1); + p[0]=(*TAMB)+p[105]; + return(0); +} diff --git a/src/spicelib/devices/vbic/vbictrunc.c b/src/spicelib/devices/vbic/vbictrunc.c new file mode 100644 index 000000000..cb2b25fd0 --- /dev/null +++ b/src/spicelib/devices/vbic/vbictrunc.c @@ -0,0 +1,41 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1995 Colin McAndrew Motorola +Spice3 Implementation: 2003 Dietmar Warning DAnalyse GmbH +**********/ + +/* + * This routine performs truncation error calculations for + * VBICs in the circuit. + */ + +#include "ngspice.h" +#include "cktdefs.h" +#include "vbicdefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +VBICtrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep) +{ + VBICmodel *model = (VBICmodel*)inModel; + VBICinstance *here; + + for( ; model != NULL; model = model->VBICnextModel) { + for(here=model->VBICinstances;here!=NULL; + here = here->VBICnextInstance){ + if (here->VBICowner != ARCHme) continue; + + CKTterr(here->VBICqbe,ckt,timeStep); + CKTterr(here->VBICqbex,ckt,timeStep); + CKTterr(here->VBICqbc,ckt,timeStep); + CKTterr(here->VBICqbcx,ckt,timeStep); + CKTterr(here->VBICqbep,ckt,timeStep); + CKTterr(here->VBICqbeo,ckt,timeStep); + CKTterr(here->VBICqbco,ckt,timeStep); + } + } + return(OK); +} diff --git a/src/spicelib/parser/inp2q.c b/src/spicelib/parser/inp2q.c index 28ad42e77..0803e426c 100644 --- a/src/spicelib/parser/inp2q.c +++ b/src/spicelib/parser/inp2q.c @@ -69,6 +69,7 @@ void INP2Q(void *ckt, INPtables * tab, card * current, void *gnode) if (thismodel != NULL) { if((thismodel->INPmodType != INPtypelook("BJT")) && (thismodel->INPmodType != INPtypelook("BJT2")) + && (thismodel->INPmodType != INPtypelook("VBIC")) #ifdef CIDER && (thismodel->INPmodType != INPtypelook("NBJT")) && (thismodel->INPmodType != INPtypelook("NBJT2")) diff --git a/src/spicelib/parser/inpdomod.c b/src/spicelib/parser/inpdomod.c index 14a28ea38..49fdd73ea 100644 --- a/src/spicelib/parser/inpdomod.c +++ b/src/spicelib/parser/inpdomod.c @@ -49,7 +49,7 @@ char *INPdomodel(void *ckt, card * image, INPtables * tab) err = INPmkTemp( "Device type BJT not available in this binary\n"); } - break; + break; case 2: type = INPtypelook("BJT2"); if(type < 0) { @@ -57,9 +57,16 @@ char *INPdomodel(void *ckt, card * image, INPtables * tab) "Device type BJT2 not available in this binary\n"); } break; - default: /* placeholder; use level 3 for the next model */ + case 4: + type = INPtypelook("VBIC"); + if(type < 0) { + err = INPmkTemp( + "Device type VBIC not available in this binary\n"); + } + break; + default: /* placeholder; use level 4 for the next model */ err = INPmkTemp( - "Only BJT levels 1 and 2 are supported in this binary\n"); + "Only BJT levels 1-2, 4 are supported in this binary\n"); break; } @@ -289,14 +296,6 @@ char *INPdomodel(void *ckt, card * image, INPtables * tab) INPmkTemp ("Device type BSIM6 not available in this binary\n");} break; - case 17: - type = INPtypelook("HiSIM1"); - if (type < 0) { - err = - INPmkTemp - ("Placeholder: Device type HiSIM1 not available in this binary\n"); - } - break; case 29: type = INPtypelook("B3SOIPD"); if (type < 0) { @@ -386,6 +385,14 @@ char *INPdomodel(void *ckt, card * image, INPtables * tab) ("Device type SOI3 not available in this binary (internal STAG release)\n"); } break; + case 64: + type = INPtypelook("HiSIM1"); + if (type < 0) { + err = + INPmkTemp + ("Placeholder: Device type HiSIM1 not available in this binary\n"); + } + break; default: /* placeholder; use level xxx for the next model */ err = INPmkTemp diff --git a/tests/vbic/CEamp.sp b/tests/vbic/CEamp.sp new file mode 100644 index 000000000..446d52136 --- /dev/null +++ b/tests/vbic/CEamp.sp @@ -0,0 +1,26 @@ +VBIC Pole Zero Test + +Vcc 3 0 5 +Rc 2 3 1k +Rb 3 1 200k +I1 0 1 AC 1 +Vmeas 4 2 +Cshunt 4 0 .1u + +Q1 2 1 0 0 N1 + +.control +ac dec 100 0.1Meg 10G +plot db(i(vmeas)) +plot ph(i(vmeas)) +pz 1 0 4 0 cur pz +print all +.endc + +.MODEL N1 NPN LEVEL=4 ++ IS=1e-16 IBEI=1e-18 IBEN=5e-15 IBCI=2e-17 IBCN=5e-15 ISP=1e-15 RCX=10 ++ RCI=60 RBX=10 RBI=40 RE=2 RS=20 RBP=40 VEF=10 VER=4 IKF=2e-3 ITF=8e-2 ++ XTF=20 IKR=2e-4 IKP=2e-4 CJE=1e-13 CJC=2e-14 CJEP=1e-13 CJCP=4e-13 VO=2 ++ GAMM=2e-11 HRCF=2 QCO=1e-12 AVC1=2 AVC2=15 TF=10e-12 TR=100e-12 TD=2e-11 RTH=300 + +.END diff --git a/tests/vbic/FG.sp b/tests/vbic/FG.sp new file mode 100644 index 000000000..89ff271dc --- /dev/null +++ b/tests/vbic/FG.sp @@ -0,0 +1,21 @@ +VBIC Gummel Test +V1 Q1_E 0 5.0 +VC Q1_C 0 0.0 +VB Q1_B 0 0.0 +Q1 Q1_C Q1_B Q1_E P1 +.DC V1 0.2 1.2 10m +.OPTIONS GMIN=1e-13 + +.control +run +plot abs(i(vc)) abs(i(vb)) ylimit 1e-15 0.1 ylog +plot abs(i(vc))/abs(i(vb)) vs abs(-i(vc)) xlimit 1e-09 0.1 xlog +.endc + +.MODEL P1 PNP LEVEL=4 ++ IS=1e-16 IBEI=1e-18 IBEN=5e-15 IBCI=2e-17 IBCN=5e-15 ISP=1e-15 RCX=10 ++ RCI=60 RBX=10 RBI=40 RE=2 RS=20 RBP=40 VEF=10 VER=4 IKF=2e-3 ITF=8e-2 ++ XTF=20 IKR=2e-4 IKP=2e-4 CJE=1e-13 CJC=2e-14 CJEP=1e-13 CJCP=4e-13 VO=2 ++ GAMM=2e-11 HRCF=2 QCO=1e-12 AVC1=2 AVC2=15 TF=10e-12 TR=100e-12 TD=2e-11 RTH=300 + +.END diff --git a/tests/vbic/FO.sp b/tests/vbic/FO.sp new file mode 100644 index 000000000..91d0c1669 --- /dev/null +++ b/tests/vbic/FO.sp @@ -0,0 +1,20 @@ +VBIC Output Test +V1 V1_P V1_N 0.0 +VB V1_N 0 0.5 +VC Q1_C 0 0.0 +Q1 Q1_C V1_P 0 N1 +.DC VC 0 5 50M VB 700M 1 50M + +.control +run +plot -i(vc) +plot -i(vb) +.endc + +.MODEL N1 NPN LEVEL=4 ++ IS=1e-16 IBEI=1e-18 IBEN=5e-15 IBCI=2e-17 IBCN=5e-15 ISP=1e-15 RCX=10 ++ RCI=60 RBX=10 RBI=40 RE=2 RS=20 RBP=40 VEF=10 VER=4 IKF=2e-3 ITF=8e-2 ++ XTF=20 IKR=2e-4 IKP=2e-4 CJE=1e-13 CJC=2e-14 CJEP=1e-13 CJCP=4e-13 VO=2 ++ GAMM=2e-11 HRCF=2 QCO=1e-12 AVC1=2 AVC2=15 TF=10e-12 TR=100e-12 TD=2e-11 RTH=300 + +.END diff --git a/tests/vbic/diffamp.sp b/tests/vbic/diffamp.sp new file mode 100644 index 000000000..016e585f5 --- /dev/null +++ b/tests/vbic/diffamp.sp @@ -0,0 +1,45 @@ +VBIC DiffAmp Test +Q8 Q8_B Q8_B VCC P1 +Q9 Q9_B Q9_B Q8_B P1 +V1 VCC 0 3.3 +V2 V2_P R3_N AC 1 DC 0 Sine(0 10m 10Meg 0 0) +I1 VCC I1_N 10u +Q12 Q9_B I1_N 0 N1 M=2 +Q13 Q5_B I1_N 0 N1 M=2 +Q10 Q1_E I1_N 0 N1 +Q11 I1_N I1_N 0 N1 +E1 E1_P 0 Q3_C Q4_C 1 +rl e1_p 0 1e6 +Q2 Q6_C R3_N Q1_E N1 +R4 R3_N 0 1K +Q3 Q3_C Q9_B Q5_C P1 +Q1 Q5_C V2_P Q1_E N1 +Q6 Q6_C Q5_B VCC P1 +R1 Q3_C 0 100k +Q7 Q5_B Q5_B VCC P1 +Q4 Q4_C Q9_B Q6_C P1 +R2 Q4_C 0 100k +R3 VCC R3_N 1K +Q5 Q5_C Q5_B VCC P1 +*.OP +.TRAN 1n 1u 0 10n +*.AC DEC 25 100k 1G + +.control +run +plot v(e1_p) +.endc + +.MODEL N1 NPN LEVEL=4 ++ IS=1e-16 IBEI=1e-18 IBEN=5e-15 IBCI=2e-17 IBCN=5e-15 ISP=1e-15 RCX=10 ++ RCI=60 RBX=10 RBI=40 RE=2 RS=20 RBP=40 VEF=10 VER=4 IKF=2e-3 ITF=8e-2 ++ XTF=20 IKR=2e-4 IKP=2e-4 CJE=1e-13 CJC=2e-14 CJEP=1e-13 CJCP=4e-13 VO=2 ++ GAMM=2e-11 HRCF=2 QCO=1e-12 AVC1=2 AVC2=15 TF=10e-12 TR=100e-12 TD=2e-11 RTH=300 + +.MODEL P1 PNP LEVEL=4 ++ IS=1e-16 IBEI=1e-18 IBEN=5e-15 IBCI=2e-17 IBCN=5e-15 ISP=1e-15 RCX=10 ++ RCI=60 RBX=10 RBI=40 RE=2 RS=20 RBP=40 VEF=10 VER=4 IKF=2e-3 ITF=8e-2 ++ XTF=20 IKR=2e-4 IKP=2e-4 CJE=1e-13 CJC=2e-14 CJEP=1e-13 CJCP=4e-13 VO=2 ++ GAMM=2e-11 HRCF=2 QCO=1e-12 AVC1=2 AVC2=15 TF=10e-12 TR=100e-12 TD=2e-11 RTH=300 + +.END diff --git a/tests/vbic/diode.sp b/tests/vbic/diode.sp new file mode 100644 index 000000000..943cb30e7 --- /dev/null +++ b/tests/vbic/diode.sp @@ -0,0 +1,19 @@ +VBIC diode test +Q1 0 0 VCC P1 +V1 VCC 0 1.0 + +.OP + +.MODEL N1 NPN LEVEL=4 ++ IS=1e-16 IBEI=1e-18 IBEN=5e-15 IBCI=2e-17 IBCN=5e-15 ISP=1e-15 RCX=10 ++ RCI=60 RBX=10 RBI=40 RE=2 RS=20 RBP=40 VEF=10 VER=4 IKF=2e-3 ITF=8e-2 ++ XTF=20 IKR=2e-4 IKP=2e-4 CJE=1e-13 CJC=2e-14 CJEP=1e-13 CJCP=4e-13 VO=2 ++ GAMM=2e-11 HRCF=2 QCO=1e-12 AVC1=2 AVC2=15 TF=10e-12 TR=100e-12 TD=2e-11 RTH=300 + +.MODEL P1 PNP LEVEL=4 ++ IS=1e-16 IBEI=1e-18 IBEN=5e-15 IBCI=2e-17 IBCN=5e-15 ISP=1e-15 RCX=10 ++ RCI=60 RBX=10 RBI=40 RE=2 RS=20 RBP=40 VEF=10 VER=4 IKF=2e-3 ITF=8e-2 ++ XTF=20 IKR=2e-4 IKP=2e-4 CJE=1e-13 CJC=2e-14 CJEP=1e-13 CJCP=4e-13 VO=2 ++ GAMM=2e-11 HRCF=2 QCO=1e-12 AVC1=2 AVC2=15 TF=10e-12 TR=100e-12 TD=2e-11 RTH=300 + +.END diff --git a/tests/vbic/noise_scale_test.sp b/tests/vbic/noise_scale_test.sp new file mode 100644 index 000000000..9366895e3 --- /dev/null +++ b/tests/vbic/noise_scale_test.sp @@ -0,0 +1,25 @@ +VBIC Noise Scale Test +V1 R3_P 0 5 +V2 V2_P 0 5 AC 1 +C1 R3_N V2_P 1n +R4 R3_N 0 100k +Q1 VOUT R3_N Q1_E N1 M=2 +*Q2 VOUT R3_N Q1_E N1 +R1 R3_P VOUT 100k +R2 Q1_E 0 10k +R3 R3_P R3_N 500k +.NOISE v(vout) V2 DEC 25 1k 100Meg + +.control +run +plot sqrt(onoise_spectrum) loglog +.endc + +.MODEL N1 NPN LEVEL=4 ++ IS=1e-16 IBEI=1e-18 IBEN=5e-15 IBCI=2e-17 IBCN=5e-15 ISP=1e-15 RCX=10 ++ RCI=60 RBX=10 RBI=40 RE=2 RS=20 RBP=40 VEF=10 VER=4 IKF=2e-3 ITF=8e-2 ++ XTF=20 IKR=2e-4 IKP=2e-4 CJE=1e-13 CJC=2e-14 CJEP=1e-13 CJCP=4e-13 VO=2 ++ GAMM=2e-11 HRCF=2 QCO=1e-12 AVC1=2 AVC2=15 TF=10e-12 TR=100e-12 TD=2e-11 ++ RTH=300 KFN=10e-15 AFN=1 BFN=1 + +.END diff --git a/tests/vbic/temp.sp b/tests/vbic/temp.sp new file mode 100644 index 000000000..5b3a05620 --- /dev/null +++ b/tests/vbic/temp.sp @@ -0,0 +1,20 @@ +VBIC Temp test +V1 1 0 1.0 +VC 1 Q1_C 0.0 +VB 1 Q1_B 0.0 +Q1 Q1_C Q1_B 0 N1 +.OPTIONS TEMP=150 +.DC V1 0.2 1.2 10m + +.control +run +plot i(vc) i(vb) +.endc + +.MODEL N1 NPN LEVEL=4 ++ IS=1e-16 IBEI=1e-18 IBEN=5e-15 IBCI=2e-17 IBCN=5e-15 ISP=1e-15 RCX=10 ++ RCI=60 RBX=10 RBI=40 RE=2 RS=20 RBP=40 VEF=10 VER=4 IKF=2e-3 ITF=8e-2 ++ XTF=20 IKR=2e-4 IKP=2e-4 CJE=1e-13 CJC=2e-14 CJEP=1e-13 CJCP=4e-13 VO=2 ++ GAMM=2e-11 HRCF=2 QCO=1e-12 AVC1=2 AVC2=15 TF=10e-12 TR=100e-12 TD=2e-11 RTH=300 + +.END diff --git a/tests/vbic/tran_aplac_test.sp b/tests/vbic/tran_aplac_test.sp new file mode 100644 index 000000000..803d47266 --- /dev/null +++ b/tests/vbic/tran_aplac_test.sp @@ -0,0 +1,23 @@ +VBIC Aplac Transient Test +V1 R3_P 0 5 +V2 V2_P 0 5 Pulse(0 100m 0 10n 10n 490.1n 1u) +C1 R3_N V2_P 1n +R4 R3_N 0 100k +Q1 R1_N R3_N Q1_E N1 +R1 R3_P R1_N 100k +R2 Q1_E 0 10k +R3 R3_P R3_N 500k + +.control +tran 10n 10u +run +plot v(Q1_E) +.endc + +.MODEL N1 NPN LEVEL=4 ++ IS=1e-16 IBEI=1e-18 IBEN=5e-15 IBCI=2e-17 IBCN=5e-15 ISP=1e-15 RCX=10 ++ RCI=60 RBX=10 RBI=40 RE=2 RS=20 RBP=40 VEF=10 VER=4 IKF=2e-3 ITF=8e-2 ++ XTF=20 IKR=2e-4 IKP=2e-4 CJE=1e-13 CJC=2e-14 CJEP=1e-13 CJCP=4e-13 VO=2 ++ GAMM=2e-11 HRCF=2 QCO=1e-12 AVC1=2 AVC2=15 TF=10e-12 TR=100e-12 TD=2e-11 RTH=300 + +.END diff --git a/tests/vbic/vbic.sp b/tests/vbic/vbic.sp new file mode 100644 index 000000000..edc2d53bb --- /dev/null +++ b/tests/vbic/vbic.sp @@ -0,0 +1,46 @@ +VBIC Test +VC 1 0 DC 2.0 +VB 2 0 DC 0.7 +VE 3 0 DC 0.0 +*VS 4 0 DC 0.0 +Q1 1 2 3 VBIC_HSPICE +.OPTIONS GMIN=1e-13 +*.OP +.DC VB 0.2 1.0 0.01 + +.control +run +plot abs(-i(vc)) abs(-i(vb)) ylimit 1e-12 0.1 ylog +plot abs(-i(vc))/abs(-i(vb)) vs abs(-i(vc)) xlimit 1e-09 0.1 xlog +.endc + +.MODEL VBIC NPN LEVEL=4 ++ RCX=10 RCI=10 RBX=1 RBI=10 RE=1 RBP=10 RS=10 ++ IBEN=1.0E-13 ++ RTH=100 + +.MODEL VBIC_HSPICE NPN LEVEL=4 ++ AFN=1 AJC=-0.5 AJE=0.5 AJS=0.5 ++ AVC1=0 AVC2=0 BFN=1 CBCO=0 CBEO=0 CJC=2E-14 ++ CJCP=4E-13 CJE=1E-13 CJEP=1E-13 CTH=0 ++ EA=1.12 EAIC=1.12 EAIE=1.12 EAIS=1.12 EANC=1.12 ++ EANE=1.12 EANS=1.12 FC=0.9 GAMM=2E-11 HRCF=2 ++ IBCI=2E-17 IBCIP=0 IBCN=5E-15 IBCNP=0 ++ IBEI=1E-18 IBEIP=0 IBEN=5E-15 IBENP=0 ++ IKF=2E-3 IKP=2E-4 IKR=2E-4 IS=1E-16 ISP=1E-15 ITF=8E-2 ++ KFN=0 MC=0.33 ME=0.33 MS=0.33 ++ NCI=1 NCIP=1 NCN=2 NCNP=2 NEI=1 NEN=2 ++ NF=1 NFP=1 NR=1 PC=0.75 PE=0.75 PS=0.75 QCO=1E-12 QTF=0 ++ RBI=4 RBP=4 RBX=1 RCI=6 RCX=1 RE=0.2 RS=2 ++ RTH=300 TAVC=0 TD=2E-11 TF=10E-12 TNF=0 TR=100E-12 ++ TNOM=25 VEF=10 VER=4 VO=2 ++ VTF=0 WBE=1 WSP=1 ++ XII=3 XIN=3 XIS=3 XRBI=1 XRCI=1 XRE=1 XRS=1 XTF=20 XVO=0 + +.MODEL VBIC_APLAC NPN LEVEL=4 ++ IS=1e-16 IBEI=1e-18 IBEN=5e-15 IBCI=2e-17 IBCN=5e-15 ISP=1e-15 RCX=10 ++ RCI=60 RBX=10 RBI=40 RE=2 RS=20 RBP=40 VEF=10 VER=4 IKF=2e-3 ITF=8e-2 ++ XTF=20 IKR=2e-4 IKP=2e-4 CJE=1e-13 CJC=2e-14 CJEP=1e-13 CJCP=4e-13 VO=2 ++ GAMM=2e-11 HRCF=2 QCO=1e-12 AVC1=2 AVC2=15 TF=10e-12 TR=100e-12 TD=2e-11 RTH=300 + +.END