diff --git a/ChangeLog b/ChangeLog index c5bbb97f9..fe7097277 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2004-06-22 Paolo Nenzi + + * src/spicelib/devices/vbic: Vbic code updated. Thanks to Dietmar + Warning (warning@danalyse.de )now we have the four terminal + version of the VBIC model. The old three terminal version has + been discarded. + 2004-06-21 Paolo Nenzi * src/frontend/subckt.c: patch from Stuart Brorson diff --git a/DEVICES b/DEVICES index 1372b6e41..398fde810 100644 --- a/DEVICES +++ b/DEVICES @@ -327,7 +327,7 @@ VBIC - Bipolar Junction Transistor Web Site: http://www.designers-guide.com/VBIC/index.html - Notes: This is the three terminals model, without excess phase + Notes: This is the 4 terminals model, without excess phase and thermal network. diff --git a/src/spicelib/devices/vbic/vbic.c b/src/spicelib/devices/vbic/vbic.c index fe383ece0..3cd32aa15 100644 --- a/src/spicelib/devices/vbic/vbic.c +++ b/src/spicelib/devices/vbic/vbic.c @@ -28,17 +28,20 @@ IFparm VBICpTable[] = { /* parameters */ 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("subsnode", VBIC_QUEST_SUBSNODE, IF_INTEGER, "Number of substrate 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"), + OPU("subsSInode",VBIC_QUEST_SUBSSINODE,IF_INTEGER, "Internal substrate 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("is", VBIC_QUEST_CS, IF_REAL, "Substrate 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"), @@ -48,6 +51,8 @@ IFparm VBICpTable[] = { /* parameters */ 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("cbep", VBIC_QUEST_CBEP, IF_REAL, "Parasitic Base to emitter capacitance"), + OP("cbcp", VBIC_QUEST_CBCP, IF_REAL, "Parasitic 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."), @@ -176,7 +181,7 @@ IFparm VBICmPTable[] = { /* model parameters */ 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"), + IOP("vref", VBIC_MOD_VREF, IF_REAL, "Reference Version") }; char *VBICnames[] = { diff --git a/src/spicelib/devices/vbic/vbicacld.c b/src/spicelib/devices/vbic/vbicacld.c index 501609d8d..b85ef69f7 100644 --- a/src/spicelib/devices/vbic/vbicacld.c +++ b/src/spicelib/devices/vbic/vbicacld.c @@ -26,9 +26,11 @@ VBICacLoad(GENmodel *inModel, CKTcircuit *ckt) ,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; + ,Irbi_Vbci,Ire_Vre,Irbp_Vrbp,Irbp_Vbep,Irbp_Vbci + ,Ibcp_Vbcp,Iccp_Vbep,Irs_Vrs,Iccp_Vbci,Iccp_Vbcp; double XQbe_Vbei, XQbe_Vbci, XQbex_Vbex, XQbc_Vbci, - XQbcx_Vbcx, XQbep_Vbep, XQbep_Vbci; + XQbcx_Vbcx, XQbep_Vbep, XQbep_Vbci, + XQbcp_Vbcp; /* loop through all the models */ for( ; model != NULL; model = model->VBICnextModel) { @@ -42,6 +44,7 @@ VBICacLoad(GENmodel *inModel, CKTcircuit *ckt) 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; + Irs_Vrs = 1.0 / here->VBICtsubstrateResist * here->VBICarea * here->VBICm; Ibe_Vbei = *(ckt->CKTstate0 + here->VBICibe_Vbei); Ibex_Vbex = *(ckt->CKTstate0 + here->VBICibex_Vbex); @@ -61,6 +64,10 @@ VBICacLoad(GENmodel *inModel, CKTcircuit *ckt) Irbp_Vrbp = *(ckt->CKTstate0 + here->VBICirbp_Vrbp); Irbp_Vbep = *(ckt->CKTstate0 + here->VBICirbp_Vbep); Irbp_Vbci = *(ckt->CKTstate0 + here->VBICirbp_Vbci); + Ibcp_Vbcp = *(ckt->CKTstate0 + here->VBICibcp_Vbcp); + Iccp_Vbep = *(ckt->CKTstate0 + here->VBICiccp_Vbep); + Iccp_Vbci = *(ckt->CKTstate0 + here->VBICiccp_Vbci); + Iccp_Vbcp = *(ckt->CKTstate0 + here->VBICiccp_Vbcp); /* c The real part @@ -186,6 +193,35 @@ c Stamp element: Irbp *(here->VBICcollCXBaseBIPtr) += -Irbp_Vbci; *(here->VBICcollCXCollCIPtr) += Irbp_Vbci; /* +c Stamp element: Ibcp +*/ + *(here->VBICsubsSISubsSIPtr) += Ibcp_Vbcp; + *(here->VBICsubsSIBaseBPPtr) += -Ibcp_Vbcp; + *(here->VBICbaseBPSubsSIPtr) += -Ibcp_Vbcp; + *(here->VBICbaseBPBaseBPPtr) += Ibcp_Vbcp; +/* +c Stamp element: Iccp +*/ + *(here->VBICbaseBXBaseBXPtr) += Iccp_Vbep; + *(here->VBICbaseBXBaseBPPtr) += -Iccp_Vbep; + *(here->VBICbaseBXBaseBIPtr) += Iccp_Vbci; + *(here->VBICbaseBXCollCIPtr) += -Iccp_Vbci; + *(here->VBICbaseBXSubsSIPtr) += Iccp_Vbcp; + *(here->VBICbaseBXBaseBPPtr) += -Iccp_Vbcp; + *(here->VBICsubsSIBaseBXPtr) += -Iccp_Vbep; + *(here->VBICsubsSIBaseBPPtr) += Iccp_Vbep; + *(here->VBICsubsSIBaseBIPtr) += -Iccp_Vbci; + *(here->VBICsubsSICollCIPtr) += Iccp_Vbci; + *(here->VBICsubsSISubsSIPtr) += -Iccp_Vbcp; + *(here->VBICsubsSIBaseBPPtr) += Iccp_Vbcp; +/* +c Stamp element: Irs +*/ + *(here->VBICsubsSubsPtr) += Irs_Vrs; + *(here->VBICsubsSISubsSIPtr) += Irs_Vrs; + *(here->VBICsubsSISubsPtr) += -Irs_Vrs; + *(here->VBICsubsSubsSIPtr) += -Irs_Vrs; +/* c The complex part */ XQbe_Vbei = *(ckt->CKTstate0 + here->VBICcqbe) * ckt->CKTomega; @@ -195,6 +231,7 @@ c The complex part XQbcx_Vbcx = *(ckt->CKTstate0 + here->VBICcqbcx) * ckt->CKTomega; XQbep_Vbep = *(ckt->CKTstate0 + here->VBICcqbep) * ckt->CKTomega; XQbep_Vbci = *(ckt->CKTstate0 + here->VBICcqbepci) * ckt->CKTomega; + XQbcp_Vbcp = *(ckt->CKTstate0 + here->VBICcqbcp) * ckt->CKTomega; /* c Stamp element: Qbe */ @@ -238,6 +275,13 @@ c Stamp element: Qbep *(here->VBICbaseBPBaseBPPtr + 1) += XQbep_Vbep; *(here->VBICbaseBPBaseBIPtr + 1) += -XQbep_Vbci; *(here->VBICbaseBPCollCIPtr + 1) += XQbep_Vbci; +/* +c Stamp element: Qbcp +*/ + *(here->VBICsubsSISubsSIPtr + 1) += XQbcp_Vbcp; + *(here->VBICsubsSIBaseBPPtr + 1) += -XQbcp_Vbcp; + *(here->VBICbaseBPSubsSIPtr + 1) += -XQbcp_Vbcp; + *(here->VBICbaseBPBaseBPPtr + 1) += XQbcp_Vbcp; } } diff --git a/src/spicelib/devices/vbic/vbicask.c b/src/spicelib/devices/vbic/vbicask.c index 5aca1fbb9..b1bae198a 100644 --- a/src/spicelib/devices/vbic/vbicask.c +++ b/src/spicelib/devices/vbic/vbicask.c @@ -58,6 +58,9 @@ VBICask(CKTcircuit *ckt, GENinstance *instPtr, int which, IFvalue *value, IFvalu case VBIC_QUEST_EMITNODE: value->iValue = here->VBICemitNode; return(OK); + case VBIC_QUEST_SUBSNODE: + value->iValue = here->VBICsubsNode; + return(OK); case VBIC_QUEST_COLLCXNODE: value->iValue = here->VBICcollCXNode; return(OK); @@ -67,6 +70,9 @@ VBICask(CKTcircuit *ckt, GENinstance *instPtr, int which, IFvalue *value, IFvalu case VBIC_QUEST_EMITEINODE: value->iValue = here->VBICemitEINode; return(OK); + case VBIC_QUEST_SUBSSINODE: + value->iValue = here->VBICsubsSINode; + return(OK); case VBIC_QUEST_VBE: value->rValue = *(ckt->CKTstate0 + here->VBICvbei); return(OK); @@ -81,8 +87,9 @@ VBICask(CKTcircuit *ckt, GENinstance *instPtr, int which, IFvalue *value, IFvalu case VBIC_QUEST_CB: value->rValue = *(ckt->CKTstate0 + here->VBICibe) + *(ckt->CKTstate0 + here->VBICibc) + + *(ckt->CKTstate0 + here->VBICibex) + *(ckt->CKTstate0 + here->VBICibep) + - *(ckt->CKTstate0 + here->VBICibex); + *(ckt->CKTstate0 + here->VBICiccp); return(OK); case VBIC_QUEST_CE: value->rValue = - *(ckt->CKTstate0 + here->VBICibe) - @@ -90,12 +97,19 @@ VBICask(CKTcircuit *ckt, GENinstance *instPtr, int which, IFvalue *value, IFvalu *(ckt->CKTstate0 + here->VBICitzf) + *(ckt->CKTstate0 + here->VBICitzr); return(OK); + case VBIC_QUEST_CS: + value->rValue = *(ckt->CKTstate0 + here->VBICiccp) - + *(ckt->CKTstate0 + here->VBICibcp); + 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)); + fabs(*(ckt->CKTstate0 + here->VBICibc) * *(ckt->CKTstate0 + here->VBICvbci)) + + fabs(*(ckt->CKTstate0 + here->VBICibcp) * *(ckt->CKTstate0 + here->VBICvbcp)) + + fabs(*(ckt->CKTstate0 + here->VBICiccp)) + * fabs(*(ckt->CKTstate0 + here->VBICvbep) - *(ckt->CKTstate0 + here->VBICvbcp)); return(OK); case VBIC_QUEST_GM: value->rValue = *(ckt->CKTstate0 + here->VBICitzf_Vbei); @@ -124,6 +138,12 @@ VBICask(CKTcircuit *ckt, GENinstance *instPtr, int which, IFvalue *value, IFvalu case VBIC_QUEST_CBCX: value->rValue = here->VBICcapbcx; return(OK); + case VBIC_QUEST_CBEP: + value->rValue = here->VBICcapbep; + return(OK); + case VBIC_QUEST_CBCP: + value->rValue = here->VBICcapbcp; + return(OK); case VBIC_QUEST_QBE: value->rValue = *(ckt->CKTstate0 + here->VBICqbe); return(OK); diff --git a/src/spicelib/devices/vbic/vbicconv.c b/src/spicelib/devices/vbic/vbicconv.c index c10c4687a..aef5d2633 100644 --- a/src/spicelib/devices/vbic/vbicconv.c +++ b/src/spicelib/devices/vbic/vbicconv.c @@ -30,6 +30,7 @@ VBICconvTest(GENmodel *inModel, CKTcircuit *ckt) double delvrci; double delvrbi; double delvrbp; + double delvbcp; double ibehat; double ibexhat; double itzfhat; @@ -39,12 +40,14 @@ VBICconvTest(GENmodel *inModel, CKTcircuit *ckt) 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; + double ibcphat; + double iccphat; + double Vbei, Vbex, Vbci, Vbcx, Vbep, Vrci, Vrbi, Vrbp, Vbcp; + double Ibe, Ibex, Itzf, Itzr, Ibc, Ibep, Irci, Irbi, Irbp, Ibcp, Iccp; for( ; model != NULL; model = model->VBICnextModel) { - for(here=model->VBICinstances;here!=NULL; - here = here->VBICnextInstance) { + for(here=model->VBICinstances;here!=NULL;here = here->VBICnextInstance) { + if (here->VBICowner != ARCHme) continue; Vbei=model->VBICtype*( @@ -71,6 +74,9 @@ VBICconvTest(GENmodel *inModel, CKTcircuit *ckt) Vrbp =model->VBICtype*( *(ckt->CKTrhsOld+here->VBICbaseBPNode)- *(ckt->CKTrhsOld+here->VBICcollCXNode)); + Vbcp =model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICsubsSINode)- + *(ckt->CKTrhsOld+here->VBICbaseBPNode)); delvbei = Vbei - *(ckt->CKTstate0 + here->VBICvbei); delvbex = Vbex - *(ckt->CKTstate0 + here->VBICvbex); delvbci = Vbci - *(ckt->CKTstate0 + here->VBICvbci); @@ -79,6 +85,7 @@ VBICconvTest(GENmodel *inModel, CKTcircuit *ckt) delvrci = Vrci - *(ckt->CKTstate0 + here->VBICvrci); delvrbi = Vrbi - *(ckt->CKTstate0 + here->VBICvrbi); delvrbp = Vrbp - *(ckt->CKTstate0 + here->VBICvrbp); + delvbcp = Vbcp - *(ckt->CKTstate0 + here->VBICvbcp); ibehat = *(ckt->CKTstate0 + here->VBICibe) + *(ckt->CKTstate0 + here->VBICibe_Vbei)*delvbei; ibexhat = *(ckt->CKTstate0 + here->VBICibex) + @@ -97,6 +104,10 @@ VBICconvTest(GENmodel *inModel, CKTcircuit *ckt) *(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; + ibcphat = *(ckt->CKTstate0 + here->VBICibcp) + + *(ckt->CKTstate0 + here->VBICibcp_Vbcp)*delvbcp; + iccphat = *(ckt->CKTstate0 + here->VBICiccp) + *(ckt->CKTstate0 + here->VBICiccp_Vbep)*delvbep + + *(ckt->CKTstate0 + here->VBICiccp_Vbci)*delvbci + *(ckt->CKTstate0 + here->VBICiccp_Vbcp)*delvbcp; Ibe = *(ckt->CKTstate0 + here->VBICibe); Ibex = *(ckt->CKTstate0 + here->VBICibex); Itzf = *(ckt->CKTstate0 + here->VBICitzf); @@ -106,6 +117,8 @@ VBICconvTest(GENmodel *inModel, CKTcircuit *ckt) Irci = *(ckt->CKTstate0 + here->VBICirci); Irbi = *(ckt->CKTstate0 + here->VBICirbi); Irbp = *(ckt->CKTstate0 + here->VBICirbp); + Ibcp = *(ckt->CKTstate0 + here->VBICibcp); + Iccp = *(ckt->CKTstate0 + here->VBICiccp); /* * check convergence */ @@ -162,6 +175,20 @@ VBICconvTest(GENmodel *inModel, CKTcircuit *ckt) ckt->CKTnoncon++; ckt->CKTtroubleElt = (GENinstance *) here; return(OK); /* no reason to continue - we've failed... */ + } else { + tol=ckt->CKTreltol*MAX(fabs(ibcphat),fabs(Ibcp))+ckt->CKTabstol; + if (fabs(ibcphat-Ibcp) > tol) { + ckt->CKTnoncon++; + ckt->CKTtroubleElt = (GENinstance *) here; + return(OK); /* no reason to continue - we've failed... */ + } else { + tol=ckt->CKTreltol*MAX(fabs(iccphat),fabs(Iccp))+ckt->CKTabstol; + if (fabs(iccphat-Iccp) > tol) { + ckt->CKTnoncon++; + ckt->CKTtroubleElt = (GENinstance *) here; + return(OK); /* no reason to continue - we've failed... */ + } + } } } } diff --git a/src/spicelib/devices/vbic/vbicdefs.h b/src/spicelib/devices/vbic/vbicdefs.h index 144e5d98a..9fef0d9d3 100644 --- a/src/spicelib/devices/vbic/vbicdefs.h +++ b/src/spicelib/devices/vbic/vbicdefs.h @@ -29,12 +29,14 @@ typedef struct sVBICinstance { 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 VBICsubsNode; /* number of substrate 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 */ + int VBICsubsSINode; /* number of internal substrate node */ double VBICarea; /* area factor for the vbic */ double VBICicVBE; /* initial condition voltage B-E*/ @@ -85,6 +87,8 @@ typedef struct sVBICinstance { * (base,base) */ double *VBICemitEmitPtr; /* pointer to sparse matrix at * (emitter,emitter) */ + double *VBICsubsSubsPtr; /* pointer to sparse matrix at + * (substrate,substrate) */ double *VBICcollCXCollCXPtr; /* pointer to sparse matrix at * (collector prime,collector prime) */ double *VBICcollCICollCIPtr; /* pointer to sparse matrix at @@ -97,6 +101,8 @@ typedef struct sVBICinstance { * (collector prime,collector prime) */ double *VBICemitEIEmitEIPtr; /* pointer to sparse matrix at * (emitter prime,emitter prime) */ + double *VBICsubsSISubsSIPtr; /* pointer to sparse matrix at + * (substrate prime, substrate prime) */ double *VBICbaseEmitPtr; /* pointer to sparse matrix at * (base,emit) */ @@ -112,6 +118,8 @@ typedef struct sVBICinstance { * (base,base prime) */ double *VBICemitEmitEIPtr; /* pointer to sparse matrix at * (emitter,emitter prime) */ + double *VBICsubsSubsSIPtr; /* pointer to sparse matrix at + * (substrate, Substrate connection) */ double *VBICcollCXCollCIPtr; /* pointer to sparse matrix at * (collector prime,base prime) */ double *VBICcollCXBaseBXPtr; /* pointer to sparse matrix at @@ -130,8 +138,12 @@ typedef struct sVBICinstance { * (base primt,emitter prime) */ double *VBICbaseBXBaseBPPtr; /* pointer to sparse matrix at * (base primt,emitter prime) */ + double *VBICbaseBXSubsSIPtr; /* pointer to sparse matrix at + * (base primt,emitter prime) */ double *VBICbaseBIEmitEIPtr; /* pointer to sparse matrix at * (base primt,emitter prime) */ + double *VBICbaseBPSubsSIPtr; /* pointer to sparse matrix at + * (base primt,emitter prime) */ double *VBICcollCXCollPtr; /* pointer to sparse matrix at * (collector prime,collector) */ @@ -139,6 +151,8 @@ typedef struct sVBICinstance { * (base prime,base ) */ double *VBICemitEIEmitPtr; /* pointer to sparse matrix at * (emitter prime,emitter) */ + double *VBICsubsSISubsPtr; /* pointer to sparse matrix at + * (Substrate connection, substrate) */ double *VBICcollCICollCXPtr; /* pointer to sparse matrix at * (collector prime,base prime) */ double *VBICbaseBICollCXPtr; /* pointer to sparse matrix at @@ -153,16 +167,24 @@ typedef struct sVBICinstance { * (emitter prime,collector prime) */ double *VBICbaseBPCollCIPtr; /* pointer to sparse matrix at * (base primt,emitter prime) */ + double *VBICsubsSICollCIPtr; /* pointer to sparse matrix at + * (substrate,collector 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 *VBICsubsSIBaseBXPtr; /* pointer to sparse matrix at + * (substrate,substrate) */ double *VBICemitEIBaseBIPtr; /* pointer to sparse matrix at * (emitter prime,base prime) */ double *VBICbaseBPBaseBIPtr; /* pointer to sparse matrix at * (base primt,emitter prime) */ + double *VBICsubsSIBaseBIPtr; /* pointer to sparse matrix at + * (substrate,base prime) */ + double *VBICsubsSIBaseBPPtr; /* pointer to sparse matrix at + * (substrate,substrate) */ unsigned VBICareaGiven :1; /* flag to indicate area was specified */ unsigned VBICoff :1; /* 'off' flag for vbic */ @@ -181,6 +203,7 @@ typedef struct sVBICinstance { double VBICcapbc; double VBICcapbcx; double VBICcapbep; + double VBICcapbcp; double *VBICsens; #define VBICsenGpi VBICsens /* stores the perturbed values of gpi */ @@ -208,9 +231,11 @@ typedef struct sVBICinstance { #define VBICIBEPNOIZ 8 #define VBICFLBENOIZ 9 #define VBICFLBEPNOIZ 10 -#define VBICTOTNOIZ 11 +#define VBICRSNOIZ 11 +#define VBICICCPNOIZ 12 +#define VBICTOTNOIZ 13 -#define VBICNSRCS 12 /* the number of VBIC noise sources */ +#define VBICNSRCS 14 /* the number of VBIC noise sources */ #ifndef NONOISE double VBICnVar[NSTATVARS][VBICNSRCS]; @@ -228,9 +253,10 @@ typedef struct sVBICinstance { #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 VBICvrci VBICstate+5 +#define VBICvrbi VBICstate+6 +#define VBICvrbp VBICstate+7 +#define VBICvbcp VBICstate+8 #define VBICibe VBICstate+9 #define VBICibe_Vbei VBICstate+10 @@ -294,15 +320,26 @@ typedef struct sVBICinstance { #define VBICcqbco VBICstate+52 #define VBICgqbco VBICstate+53 -#define VBICnumStates 54 +#define VBICibcp VBICstate+54 +#define VBICibcp_Vbcp VBICstate+55 + +#define VBICiccp VBICstate+56 +#define VBICiccp_Vbep VBICstate+57 +#define VBICiccp_Vbci VBICstate+58 +#define VBICiccp_Vbcp VBICstate+59 + +#define VBICqbcp VBICstate+60 +#define VBICcqbcp VBICstate+61 + +#define VBICnumStates 62 -#define VBICsensxpbe VBICstate+54 /* charge sensitivities and their - derivatives. +55 for the derivatives - +#define VBICsensxpbe VBICstate+64 /* charge sensitivities and their + derivatives. +65 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 VBICsensxpbex VBICstate+66 +#define VBICsensxpbc VBICstate+68 +#define VBICsensxpbcx VBICstate+70 +#define VBICsensxpbep VBICstate+72 #define VBICnumSenStates 10 @@ -430,6 +467,7 @@ typedef struct sVBICmodel { /* model structure for a vbic */ double VBICcollectorConduct; /* collector conductance */ double VBICbaseConduct; /* base conductance */ double VBICemitterConduct; /* emitter conductance */ + double VBICsubstrateConduct; /* substrate conductance */ unsigned VBICtnomGiven : 1; unsigned VBICextCollResistGiven : 1; @@ -674,52 +712,58 @@ typedef struct sVBICmodel { /* model structure for a vbic */ #define VBIC_QUEST_COLLNODE 212 #define VBIC_QUEST_BASENODE 213 #define VBIC_QUEST_EMITNODE 214 +#define VBIC_QUEST_SUBSNODE 215 #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_SUBSSINODE 222 #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 +#define VBIC_QUEST_CS 228 +#define VBIC_QUEST_GM 229 +#define VBIC_QUEST_GO 230 +#define VBIC_QUEST_GPI 231 +#define VBIC_QUEST_GMU 232 +#define VBIC_QUEST_GX 233 +#define VBIC_QUEST_QBE 234 +#define VBIC_QUEST_CQBE 235 +#define VBIC_QUEST_QBC 236 +#define VBIC_QUEST_CQBC 237 +#define VBIC_QUEST_QBX 238 +#define VBIC_QUEST_CQBX 239 +#define VBIC_QUEST_QBCP 240 +#define VBIC_QUEST_CQBCP 241 +#define VBIC_QUEST_CEXBC 242 +#define VBIC_QUEST_GEQCB 243 +#define VBIC_QUEST_GCSUB 244 +#define VBIC_QUEST_GDSUB 245 +#define VBIC_QUEST_GEQBX 246 +#define VBIC_QUEST_CBE 247 +#define VBIC_QUEST_CBEX 248 +#define VBIC_QUEST_CBC 249 +#define VBIC_QUEST_CBCX 250 +#define VBIC_QUEST_CBEP 251 +#define VBIC_QUEST_CBCP 252 +#define VBIC_QUEST_SENS_REAL 253 +#define VBIC_QUEST_SENS_IMAG 254 +#define VBIC_QUEST_SENS_MAG 255 +#define VBIC_QUEST_SENS_PH 256 +#define VBIC_QUEST_SENS_CPLX 257 +#define VBIC_QUEST_SENS_DC 258 +#define VBIC_QUEST_POWER 259 /* model questions */ #define VBIC_MOD_COLLCONDUCT 301 #define VBIC_MOD_BASECONDUCT 302 #define VBIC_MOD_EMITTERCONDUCT 303 -#define VBIC_MOD_TYPE 304 +#define VBIC_MOD_SUBSTRATECONDUCT 304 +#define VBIC_MOD_TYPE 305 #include "vbicext.h" #endif /*VBIC*/ diff --git a/src/spicelib/devices/vbic/vbicinit.c b/src/spicelib/devices/vbic/vbicinit.c index 11401a19c..d6b79a2c6 100644 --- a/src/spicelib/devices/vbic/vbicinit.c +++ b/src/spicelib/devices/vbic/vbicinit.c @@ -10,7 +10,7 @@ SPICEdev VBICinfo = { { "VBIC", - "Vertical Bipolar Inter-Company Model (3-terminal)", + "Vertical Bipolar Inter-Company Model", &VBICnSize, &VBICnSize, diff --git a/src/spicelib/devices/vbic/vbicload.c b/src/spicelib/devices/vbic/vbicload.c index 6e0a55ede..2459e3726 100644 --- a/src/spicelib/devices/vbic/vbicload.c +++ b/src/spicelib/devices/vbic/vbicload.c @@ -28,17 +28,19 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) 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; + ,Vbei,Vbex,Vbci,Vbep,Vbcp,Vrcx + ,Vbcx,Vrci,Vrbx,Vrbi,Vre,Vrbp,Vrs + ,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,Ibcp,Ibcp_Vbcp,Iccp,Iccp_Vbep,Iccp_Vbci + ,Iccp_Vbcp,Irs,Irs_Vrs,Qbcp,Qbcp_Vbcp,SCALE; int iret; - int vbic_3T_it_cf_fj(double * + int vbic_4T_it_cf_fj(double * ,double *,double *,double *,double *,double *,double * ,double *,double *,double *,double *,double *,double *, double * ,double *,double *,double *,double *,double *,double *, double * @@ -47,7 +49,9 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) ,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; @@ -58,6 +62,7 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) double delvrci; double delvrbi; double delvrbp; + double delvbcp; double ibehat; double ibexhat; double itzfhat; @@ -67,9 +72,11 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) double ircihat; double irbihat; double irbphat; + double ibcphat; + double iccphat; double ceq, geq, rhs_current; int icheck; - int ichk1, ichk2, ichk3, ichk4; + int ichk1, ichk2, ichk3, ichk4, ichk5; int error; int SenCond=0; double gqbeo, cqbeo, gqbco, cqbco, gbcx, cbcx; @@ -244,6 +251,10 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) Vre = model->VBICtype*( *(ckt->CKTrhsOp+here->VBICemitNode)- *(ckt->CKTrhsOp+here->VBICemitEINode)); + Vbcp = *(ckt->CKTstate1 + here->VBICvbcp); + Vrs = model->VBICtype*( + *(ckt->CKTrhsOp+here->VBICsubsNode)- + *(ckt->CKTrhsOp+here->VBICsubsSINode)); } else{ Vbei = *(ckt->CKTstate0 + here->VBICvbei); @@ -254,6 +265,7 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) Vrci = *(ckt->CKTstate0 + here->VBICvrci); Vrbi = *(ckt->CKTstate0 + here->VBICvrbi); Vrbp = *(ckt->CKTstate0 + here->VBICvrbp); + Vbcp = *(ckt->CKTstate0 + here->VBICvbcp); if((ckt->CKTsenInfo->SENmode == DCSEN)|| (ckt->CKTsenInfo->SENmode == TRANSEN)){ Vbe = model->VBICtype*( @@ -271,6 +283,9 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) Vre = model->VBICtype*( *(ckt->CKTrhsOld+here->VBICemitNode)- *(ckt->CKTrhsOld+here->VBICemitEINode)); + Vrs = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICsubsNode)- + *(ckt->CKTrhsOld+here->VBICsubsSINode)); } if(ckt->CKTsenInfo->SENmode == ACSEN){ Vbe = model->VBICtype*( @@ -288,6 +303,9 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) Vre = model->VBICtype*( *(ckt->CKTrhsOp+here->VBICemitNode)- *(ckt->CKTrhsOp+here->VBICemitEINode)); + Vrs = model->VBICtype*( + *(ckt->CKTrhsOp+here->VBICsubsNode)- + *(ckt->CKTrhsOp+here->VBICsubsSINode)); } } goto next1; @@ -321,6 +339,10 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) Vre = model->VBICtype*( *(ckt->CKTrhsOld+here->VBICemitNode)- *(ckt->CKTrhsOld+here->VBICemitEINode)); + Vbcp = *(ckt->CKTstate0 + here->VBICvbcp); + Vrs = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICsubsNode)- + *(ckt->CKTrhsOld+here->VBICsubsSINode)); } else if(ckt->CKTmode & MODEINITTRAN) { Vbe = model->VBICtype*( *(ckt->CKTrhsOld+here->VBICbaseNode)- @@ -345,6 +367,10 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) Vre = model->VBICtype*( *(ckt->CKTrhsOld+here->VBICemitNode)- *(ckt->CKTrhsOld+here->VBICemitEINode)); + Vbcp = *(ckt->CKTstate1 + here->VBICvbcp); + Vrs = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICsubsNode)- + *(ckt->CKTrhsOld+here->VBICsubsSINode)); if( (ckt->CKTmode & MODETRAN) && (ckt->CKTmode & MODEUIC) ) { Vbc = model->VBICtype * (here->VBICicVBE-here->VBICicVCE); } @@ -355,23 +381,24 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) vce=model->VBICtype*here->VBICicVCE; Vbc=Vbe-vce; Vbci=Vbcx=Vbc; - Vbep=0.0; + Vbep=Vbcp=0.0; Vrci=Vrbi=Vrbp=0.0; - Vrcx=Vrbx=Vre=0.0; + Vrcx=Vrbx=Vre=Vrs=0.0; } else if((ckt->CKTmode & MODEINITJCT) && (here->VBICoff==0)) { Vbe=Vbei=Vbex=model->VBICtype*here->VBICtVcrit; Vbc=Vbci=Vbcx=Vbep=0.0; + Vbcp=Vbc-Vbe; Vrci=Vrbi=Vrbp=0.0; - Vrcx=Vrbx=Vre=0.0; + Vrcx=Vrbx=Vre=Vrs=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; + Vbep=Vbcp=0.0; Vrci=Vrbi=Vrbp=0.0; - Vrcx=Vrbx=Vre=0.0; + Vrcx=Vrbx=Vre=Vrs=0.0; } else { #ifndef PREDICTOR if(ckt->CKTmode & MODEINITPRED) { @@ -392,6 +419,8 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) xfact * *(ckt->CKTstate2 + here->VBICvrbi); Vrbp = (1+xfact) * *(ckt->CKTstate1 + here->VBICvrbp)- xfact * *(ckt->CKTstate2 + here->VBICvrbp); + Vbcp = (1+xfact) * *(ckt->CKTstate1 + here->VBICvbcp)- + xfact * *(ckt->CKTstate2 + here->VBICvbcp); *(ckt->CKTstate0 + here->VBICvbei) = *(ckt->CKTstate1 + here->VBICvbei); *(ckt->CKTstate0 + here->VBICvbex) = @@ -408,6 +437,8 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) *(ckt->CKTstate1 + here->VBICvrbi); *(ckt->CKTstate0 + here->VBICvrbp) = *(ckt->CKTstate1 + here->VBICvrbp); + *(ckt->CKTstate0 + here->VBICvbcp) = + *(ckt->CKTstate1 + here->VBICvbcp); *(ckt->CKTstate0 + here->VBICibe) = *(ckt->CKTstate1 + here->VBICibe); *(ckt->CKTstate0 + here->VBICibe_Vbei) = @@ -462,6 +493,18 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) *(ckt->CKTstate1 + here->VBICirbp_Vbep); *(ckt->CKTstate0 + here->VBICirbp_Vbci) = *(ckt->CKTstate1 + here->VBICirbp_Vbci); + *(ckt->CKTstate0 + here->VBICibcp) = + *(ckt->CKTstate1 + here->VBICibcp); + *(ckt->CKTstate0 + here->VBICibcp_Vbcp) = + *(ckt->CKTstate1 + here->VBICibcp_Vbcp); + *(ckt->CKTstate0 + here->VBICiccp) = + *(ckt->CKTstate1 + here->VBICiccp); + *(ckt->CKTstate0 + here->VBICiccp_Vbep) = + *(ckt->CKTstate1 + here->VBICiccp_Vbep); + *(ckt->CKTstate0 + here->VBICiccp_Vbci) = + *(ckt->CKTstate1 + here->VBICiccp_Vbci); + *(ckt->CKTstate0 + here->VBICiccp_Vbcp) = + *(ckt->CKTstate1 + here->VBICiccp_Vbcp); } else { #endif /* PREDICTOR */ /* @@ -491,6 +534,9 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) Vrbp = model->VBICtype*( *(ckt->CKTrhsOld+here->VBICbaseBPNode)- *(ckt->CKTrhsOld+here->VBICcollCXNode)); + Vbcp = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICsubsSINode)- + *(ckt->CKTrhsOld+here->VBICbaseBPNode)); #ifndef PREDICTOR } #endif /* PREDICTOR */ @@ -502,6 +548,7 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) delvrci = Vrci - *(ckt->CKTstate0 + here->VBICvrci); delvrbi = Vrbi - *(ckt->CKTstate0 + here->VBICvrbi); delvrbp = Vrbp - *(ckt->CKTstate0 + here->VBICvrbp); + delvbcp = Vbcp - *(ckt->CKTstate0 + here->VBICvbcp); Vbe = model->VBICtype*( *(ckt->CKTrhsOld+here->VBICbaseNode)- *(ckt->CKTrhsOld+here->VBICemitNode)); @@ -517,6 +564,9 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) Vre = model->VBICtype*( *(ckt->CKTrhsOld+here->VBICemitNode)- *(ckt->CKTrhsOld+here->VBICemitEINode)); + Vrs = model->VBICtype*( + *(ckt->CKTrhsOld+here->VBICsubsNode)- + *(ckt->CKTrhsOld+here->VBICsubsSINode)); ibehat = *(ckt->CKTstate0 + here->VBICibe) + *(ckt->CKTstate0 + here->VBICibe_Vbei)*delvbei; @@ -536,6 +586,10 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) *(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; + ibcphat = *(ckt->CKTstate0 + here->VBICibcp) + + *(ckt->CKTstate0 + here->VBICibcp_Vbcp)*delvbcp; + iccphat = *(ckt->CKTstate0 + here->VBICiccp) + *(ckt->CKTstate0 + here->VBICiccp_Vbep)*delvbep + + *(ckt->CKTstate0 + here->VBICiccp_Vbci)*delvbci + *(ckt->CKTstate0 + here->VBICiccp_Vbcp)*delvbcp; /* * bypass if solution has not changed */ @@ -569,6 +623,9 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) if( (fabs(delvrbp) < ckt->CKTreltol*MAX(fabs(Vrbp), fabs(*(ckt->CKTstate0 + here->VBICvrbp)))+ ckt->CKTvoltTol) ) + if( (fabs(delvbcp) < ckt->CKTreltol*MAX(fabs(Vbcp), + fabs(*(ckt->CKTstate0 + here->VBICvbcp)))+ + ckt->CKTvoltTol) ) if( (fabs(ibehat-*(ckt->CKTstate0 + here->VBICibe)) < ckt->CKTreltol* MAX(fabs(ibehat), fabs(*(ckt->CKTstate0 + here->VBICibe)))+ @@ -604,6 +661,14 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) if( (fabs(irbphat-*(ckt->CKTstate0 + here->VBICirbp)) < ckt->CKTreltol* MAX(fabs(irbphat), fabs(*(ckt->CKTstate0 + here->VBICirbp)))+ + ckt->CKTabstol) ) + if( (fabs(ibcphat-*(ckt->CKTstate0 + here->VBICibcp)) < + ckt->CKTreltol* MAX(fabs(ibcphat), + fabs(*(ckt->CKTstate0 + here->VBICibcp)))+ + ckt->CKTabstol) ) + if( (fabs(iccphat-*(ckt->CKTstate0 + here->VBICiccp)) < + ckt->CKTreltol* MAX(fabs(iccphat), + fabs(*(ckt->CKTstate0 + here->VBICiccp)))+ ckt->CKTabstol) ) { /* * bypassing.... @@ -616,6 +681,7 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) Vrci = *(ckt->CKTstate0 + here->VBICvrci); Vrbi = *(ckt->CKTstate0 + here->VBICvrbi); Vrbp = *(ckt->CKTstate0 + here->VBICvrbp); + Vbcp = *(ckt->CKTstate0 + here->VBICvbcp); Ibe = *(ckt->CKTstate0 + here->VBICibe); Ibe_Vbei = *(ckt->CKTstate0 + here->VBICibe_Vbei); Ibex = *(ckt->CKTstate0 + here->VBICibex); @@ -645,6 +711,12 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) Irbp_Vbci = *(ckt->CKTstate0 + here->VBICirbp_Vbci); gqbeo = *(ckt->CKTstate0 + here->VBICgqbeo); gqbco = *(ckt->CKTstate0 + here->VBICgqbco); + Ibcp = *(ckt->CKTstate0 + here->VBICibcp); + Ibcp_Vbcp = *(ckt->CKTstate0 + here->VBICibcp_Vbcp); + Iccp = *(ckt->CKTstate0 + here->VBICiccp); + Iccp_Vbep = *(ckt->CKTstate0 + here->VBICiccp_Vbep); + Iccp_Vbci = *(ckt->CKTstate0 + here->VBICiccp_Vbci); + Iccp_Vbcp = *(ckt->CKTstate0 + here->VBICiccp_Vbcp); goto load; } /* @@ -661,22 +733,26 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) 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; + Vbcp = DEVpnjlim(Vbcp,*(ckt->CKTstate0 + here->VBICvbcp),vt, + here->VBICtVcrit,&ichk5); + if ((ichk1 == 1) || (ichk2 == 1) || (ichk3 == 1) || (ichk4 == 1) || (ichk5 == 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); + iret = vbic_4T_it_cf_fj(p + ,&Vbei,&Vbex,&Vbci,&Vbep,&Vbcp,&Vrcx + ,&Vbcx,&Vrci,&Vrbx,&Vrbi,&Vre,&Vrbp,&Vrs + ,&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,&Ibcp,&Ibcp_Vbcp,&Iccp,&Iccp_Vbep,&Iccp_Vbci + ,&Iccp_Vbcp,&Irs,&Irs_Vrs,&Qbcp,&Qbcp_Vbcp,&SCALE); Ibe += ckt->CKTgmin*Vbei; Ibe_Vbei += ckt->CKTgmin; @@ -690,6 +766,8 @@ next1: Irci_Vrci += ckt->CKTgmin; Irci_Vbci += ckt->CKTgmin; Irci_Vbcx += ckt->CKTgmin; + Ibcp += ckt->CKTgmin*Vbcp; + Ibcp_Vbcp += ckt->CKTgmin; if( (ckt->CKTmode & (MODETRAN | MODEAC)) || ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) || @@ -702,12 +780,14 @@ next1: *(ckt->CKTstate0 + here->VBICqbep) = Qbep; *(ckt->CKTstate0 + here->VBICqbeo) = Qbeo; *(ckt->CKTstate0 + here->VBICqbco) = Qbco; + *(ckt->CKTstate0 + here->VBICqbcp) = Qbcp; here->VBICcapbe = Qbe_Vbei; here->VBICcapbex = Qbex_Vbex; here->VBICcapbc = Qbc_Vbci; here->VBICcapbcx = Qbcx_Vbcx; here->VBICcapbep = Qbep_Vbep; + here->VBICcapbcp = Qbcp_Vbcp; /* * store small-signal parameters @@ -716,7 +796,7 @@ next1: (!(ckt->CKTmode & MODEUIC)) ) { if(ckt->CKTmode & MODEINITSMSIG) { *(ckt->CKTstate0 + here->VBICcqbe) = Qbe_Vbei; - *(ckt->CKTstate0 + here->VBICcqbeci) = Qbe_Vbci; + *(ckt->CKTstate0 + here->VBICcqbeci) = Qbe_Vbci; *(ckt->CKTstate0 + here->VBICcqbex) = Qbex_Vbex; *(ckt->CKTstate0 + here->VBICcqbc) = Qbc_Vbci; *(ckt->CKTstate0 + here->VBICcqbcx) = Qbcx_Vbcx; @@ -724,6 +804,7 @@ next1: *(ckt->CKTstate0 + here->VBICcqbepci) = Qbep_Vbci; *(ckt->CKTstate0 + here->VBICcqbeo) = Qbeo_Vbe; *(ckt->CKTstate0 + here->VBICcqbco) = Qbco_Vbc; + *(ckt->CKTstate0 + here->VBICcqbcp) = Qbcp_Vbcp; if(SenCond) { *(ckt->CKTstate0 + here->VBICibe) = Ibe; *(ckt->CKTstate0 + here->VBICibe_Vbei) = Ibe_Vbei; @@ -752,8 +833,14 @@ next1: *(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; + *(ckt->CKTstate0 + here->VBICgqbeo) = gqbeo; + *(ckt->CKTstate0 + here->VBICgqbco) = gqbco; + *(ckt->CKTstate0 + here->VBICibcp) = Ibcp; + *(ckt->CKTstate0 + here->VBICibcp_Vbcp) = Ibcp_Vbcp; + *(ckt->CKTstate0 + here->VBICiccp) = Iccp; + *(ckt->CKTstate0 + here->VBICiccp_Vbep) = Iccp_Vbep; + *(ckt->CKTstate0 + here->VBICiccp_Vbci) = Iccp_Vbci; + *(ckt->CKTstate0 + here->VBICiccp_Vbcp) = Iccp_Vbcp; } #ifdef SENSDEBUG printf("storing small signal parameters for op\n"); @@ -780,6 +867,8 @@ next1: *(ckt->CKTstate0 + here->VBICirci) = Irci; *(ckt->CKTstate0 + here->VBICirbi) = Irbi; *(ckt->CKTstate0 + here->VBICirbp) = Irbp; + *(ckt->CKTstate0 + here->VBICibcp) = Ibcp; + *(ckt->CKTstate0 + here->VBICiccp) = Iccp; continue; } @@ -798,6 +887,8 @@ next1: *(ckt->CKTstate0 + here->VBICqbeo) ; *(ckt->CKTstate1 + here->VBICqbco) = *(ckt->CKTstate0 + here->VBICqbco) ; + *(ckt->CKTstate1 + here->VBICqbcp) = + *(ckt->CKTstate0 + here->VBICqbcp) ; } error = NIintegrate(ckt,&geq,&ceq,Qbe_Vbei,here->VBICqbe); if(error) return(error); @@ -824,6 +915,11 @@ next1: Ibep_Vbep = Ibep_Vbep + geq; Ibep = Ibep + *(ckt->CKTstate0 + here->VBICcqbep); + error = NIintegrate(ckt,&geq,&ceq,Qbcp_Vbcp,here->VBICqbcp); + if(error) return(error); + Ibcp_Vbcp = Ibcp_Vbcp + geq; + Ibcp = Ibcp + *(ckt->CKTstate0 + here->VBICcqbcp); + if(ckt->CKTmode & MODEINITTRAN) { *(ckt->CKTstate1 + here->VBICcqbe) = *(ckt->CKTstate0 + here->VBICcqbe); @@ -835,6 +931,8 @@ next1: *(ckt->CKTstate0 + here->VBICcqbcx); *(ckt->CKTstate1 + here->VBICcqbep) = *(ckt->CKTstate0 + here->VBICcqbep); + *(ckt->CKTstate1 + here->VBICcqbcp) = + *(ckt->CKTstate0 + here->VBICcqbcp); } } } @@ -875,6 +973,7 @@ next2: *(ckt->CKTstate0 + here->VBICvrci) = Vrci; *(ckt->CKTstate0 + here->VBICvrbi) = Vrbi; *(ckt->CKTstate0 + here->VBICvrbp) = Vrbp; + *(ckt->CKTstate0 + here->VBICvbcp) = Vbcp; *(ckt->CKTstate0 + here->VBICibe) = Ibe; *(ckt->CKTstate0 + here->VBICibe_Vbei) = Ibe_Vbei; *(ckt->CKTstate0 + here->VBICibex) = Ibex; @@ -904,6 +1003,12 @@ next2: *(ckt->CKTstate0 + here->VBICirbp_Vbci) = Irbp_Vbci; *(ckt->CKTstate0 + here->VBICgqbeo) = gqbeo; *(ckt->CKTstate0 + here->VBICgqbco) = gqbco; + *(ckt->CKTstate0 + here->VBICibcp) = Ibcp; + *(ckt->CKTstate0 + here->VBICibcp_Vbcp) = Ibcp_Vbcp; + *(ckt->CKTstate0 + here->VBICiccp) = Iccp; + *(ckt->CKTstate0 + here->VBICiccp_Vbep) = Iccp_Vbep; + *(ckt->CKTstate0 + here->VBICiccp_Vbci) = Iccp_Vbci; + *(ckt->CKTstate0 + here->VBICiccp_Vbcp) = Iccp_Vbcp; /* Do not load the Jacobian and the rhs if perturbation is being carried out */ @@ -1087,6 +1192,41 @@ c Stamp element: Irbp *(here->VBICcollCXBaseBPPtr) += Irbp_Vbep; *(here->VBICcollCXBaseBIPtr) += -Irbp_Vbci; *(here->VBICcollCXCollCIPtr) += Irbp_Vbci; +/* +c Stamp element: Ibcp +*/ + rhs_current = model->VBICtype * (Ibcp - Ibcp_Vbcp*Vbcp); + *(ckt->CKTrhs + here->VBICsubsSINode) += -rhs_current; + *(here->VBICsubsSISubsSIPtr) += Ibcp_Vbcp; + *(here->VBICsubsSIBaseBPPtr) += -Ibcp_Vbcp; + *(ckt->CKTrhs + here->VBICbaseBPNode) += rhs_current; + *(here->VBICbaseBPSubsSIPtr) += -Ibcp_Vbcp; + *(here->VBICbaseBPBaseBPPtr) += Ibcp_Vbcp; +/* +c Stamp element: Iccp +*/ + rhs_current = model->VBICtype * (Iccp - Iccp_Vbep*Vbep - Iccp_Vbci*Vbci - Iccp_Vbcp*Vbcp); + *(ckt->CKTrhs + here->VBICbaseBXNode) += -rhs_current; + *(here->VBICbaseBXBaseBXPtr) += Iccp_Vbep; + *(here->VBICbaseBXBaseBPPtr) += -Iccp_Vbep; + *(here->VBICbaseBXBaseBIPtr) += Iccp_Vbci; + *(here->VBICbaseBXCollCIPtr) += -Iccp_Vbci; + *(here->VBICbaseBXSubsSIPtr) += Iccp_Vbcp; + *(here->VBICbaseBXBaseBPPtr) += -Iccp_Vbcp; + *(ckt->CKTrhs + here->VBICsubsSINode) += rhs_current; + *(here->VBICsubsSIBaseBXPtr) += -Iccp_Vbep; + *(here->VBICsubsSIBaseBPPtr) += Iccp_Vbep; + *(here->VBICsubsSIBaseBIPtr) += -Iccp_Vbci; + *(here->VBICsubsSICollCIPtr) += Iccp_Vbci; + *(here->VBICsubsSISubsSIPtr) += -Iccp_Vbcp; + *(here->VBICsubsSIBaseBPPtr) += Iccp_Vbcp; +/* +c Stamp element: Irs +*/ + *(here->VBICsubsSubsPtr) += Irs_Vrs; + *(here->VBICsubsSISubsSIPtr) += Irs_Vrs; + *(here->VBICsubsSISubsPtr) += -Irs_Vrs; + *(here->VBICsubsSubsSIPtr) += -Irs_Vrs; } @@ -1094,26 +1234,30 @@ c Stamp element: Irbp 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) +int vbic_4T_it_cf_fj(p + ,Vbei,Vbex,Vbci,Vbep,Vbcp,Vrcx + ,Vbcx,Vrci,Vrbx,Vrbi,Vre,Vrbp,Vrs + ,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,Ibcp,Ibcp_Vbcp,Iccp,Iccp_Vbep,Iccp_Vbci + ,Iccp_Vbcp,Irs,Irs_Vrs,Qbcp,Qbcp_Vbcp,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; + ,*Vbei,*Vbex,*Vbci,*Vbep,*Vbcp,*Vrcx + ,*Vbcx,*Vrci,*Vrbx,*Vrbi,*Vre,*Vrbp,*Vrs + ,*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,*Ibcp,*Ibcp_Vbcp,*Iccp,*Iccp_Vbep,*Iccp_Vbci + ,*Iccp_Vbcp,*Irs,*Irs_Vrs,*Qbcp,*Qbcp_Vbcp,*SCALE; { double Vtv,IVEF,IVER,IIKF,IIKR,IIKP,IVO; double IHRCF,IVTF,IITF,slTF,dv0,dvh,dvh_Vbei; @@ -1131,6 +1275,8 @@ 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 dvh_Vbcp,qlo_Vbcp,qhi_Vbcp,xvar1_Vbcp,xvar3_Vbcp,qdbcp,qdbcp_qlo; +double qdbcp_Vbcp,qdbcp_Vbep,qdbcp_qhi,dv_Vbcp,mv_Vbcp,vl_Vbcp,qdbcp_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; @@ -1140,21 +1286,23 @@ 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; +double qbp,qbp_q2p,qbp_Vbep,qbp_Vbci,argi_Vbcp,expi_Vbcp,Irp; +double Irp_expi,Irp_Vbcp,Iccp_Ifp,Iccp_Irp,Iccp_qbp,argn,argn_Vbei; +double expn,expn_argn,expn_Vbei,argx_Vbei,expx_Vbei,Ibe_expi,Ibe_expn; +double Ibe_expx,argi_Vbex,expi_Vbex,argn_Vbex,expn_Vbex,argx_Vbex,expx_Vbex; +double Ibex_expi,Ibex_expn,Ibex_expx,argn_Vbci,expn_Vbci,Ibcj,Ibcj_expi; +double Ibcj_Vbci,Ibcj_expn,argn_Vbep,expn_Vbep,Ibep_expi,Ibep_expn,xvar3_vl; +double avalf,avalf_vl,avalf_Vbci,avalf_xvar4,Igc,Igc_Itzf,Igc_Vbei; +double Igc_Vbci,Igc_Itzr,Igc_Ibcj,Igc_avalf,Ibc_Ibcj,Ibc_Igc,argx_Vbcx; +double expx_Vbcx,Kbci,Kbci_expi,Kbci_Vbci,Kbcx,Kbcx_expx,Kbcx_Vbcx; +double rKp1,rKp1_Kbci,rKp1_Vbci,rKp1_Kbcx,rKp1_Vbcx,xvar1_rKp1,xvar1_Vbcx; +double Iohm,Iohm_Vrci,Iohm_Kbci,Iohm_Vbci,Iohm_Kbcx,Iohm_Vbcx,Iohm_xvar1; +double derf,derf_Iohm,derf_Vrci,derf_Vbci,derf_Vbcx,Irci_Iohm,Irci_derf; +double Irbi_qb,Irbp_qbp,argn_Vbcp,expn_Vbcp,Ibcp_expi,Ibcp_expn,sgIf; +double rIf,rIf_Ifi,rIf_Vbei,mIf,mIf_rIf,mIf_Vbei,tff; +double tff_q1,tff_Vbei,tff_Vbci,tff_xvar2,tff_mIf,Qbe_qdbe,Qbe_tff; +double Qbe_Ifi,Qbe_qb,Qbex_qdbex,Qbc_qdbc,Qbc_Iri,Qbc_Kbci,Qbcx_Kbcx; +double Qbep_qdbep,Qbep_Ifp,Qbcp_qdbcp; /* Function and derivative code */ @@ -1599,6 +1747,87 @@ double Qbc_Kbci,Qbcx_Kbcx,Qbep_qdbep,Qbep_Ifp; qdbep_Vbep=qdbep_Vbep+qdbep_vl*vl_Vbep; } } + if(p[27]>0.0){ + dv0=-p[28]*p[14]; + if(p[30]<=0.0){ + dvh=(*Vbcp)+dv0; + dvh_Vbcp=1.0; + if(dvh>0.0){ + xvar1=(1.0-p[14]); + xvar2=(-1.0-p[29]); + pwq=pow(xvar1,xvar2); + qlo=p[28]*(1.0-pwq*(1.0-p[14])*(1.0-p[14]))/(1.0-p[29]); + qlo_Vbep=0.0; + qlo_Vbcp=0.0; + qhi=dvh*(1.0-p[14]+0.5*p[29]*dvh/p[28])*pwq; + qhi_dvh=(0.5*dvh*p[29]/p[28]-p[14]+1.0)*pwq+0.5*dvh*p[29]*pwq/p[28]; + qhi_Vbep=0.0; + qhi_Vbcp=qhi_dvh*dvh_Vbcp; + }else{ + xvar1=(1.0-(*Vbcp)/p[28]); + xvar1_Vbcp=-1.0/p[28]; + xvar2=(1.0-p[29]); + xvar3=pow(xvar1,xvar2); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vbcp=xvar3_xvar1*xvar1_Vbcp; + qlo=p[28]*(1.0-xvar3)/(1.0-p[29]); + qlo_xvar3=-p[28]/(1.0-p[29]); + qlo_Vbep=0.0; + qlo_Vbcp=qlo_xvar3*xvar3_Vbcp; + qhi=0.0; + qhi_Vbep=0.0; + qhi_Vbcp=0.0; + } + qdbcp=qlo+qhi; + qdbcp_qlo=1.0; + qdbcp_qhi=1.0; + qdbcp_Vbcp=qdbcp_qlo*qlo_Vbcp; + qdbcp_Vbep=qdbcp_qlo*qlo_Vbep; + qdbcp_Vbep=qdbcp_Vbep+qdbcp_qhi*qhi_Vbep; + qdbcp_Vbcp=qdbcp_Vbcp+qdbcp_qhi*qhi_Vbcp; + }else{ + mv0=sqrt(dv0*dv0+4.0*p[30]*p[30]); + vl0=-0.5*(dv0+mv0); + xvar1=(1.0-vl0/p[28]); + xvar2=(1.0-p[29]); + xvar3=pow(xvar1,xvar2); + q0=-p[28]*xvar3/(1.0-p[29]); + dv=(*Vbcp)+dv0; + dv_Vbcp=1.0; + mv=sqrt(dv*dv+4.0*p[30]*p[30]); + mv_dv=dv/sqrt((dv*dv)+4.0*(p[30]*p[30])); + mv_Vbcp=mv_dv*dv_Vbcp; + vl=0.5*(dv-mv)-dv0; + vl_dv=0.5; + vl_mv=-0.5; + vl_Vbcp=vl_dv*dv_Vbcp; + vl_Vbcp=vl_Vbcp+vl_mv*mv_Vbcp; + xvar1=(1.0-vl/p[28]); + xvar1_vl=-1.0/p[28]; + xvar1_Vbcp=xvar1_vl*vl_Vbcp; + xvar2=(1.0-p[29]); + xvar3=pow(xvar1,xvar2); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vbcp=xvar3_xvar1*xvar1_Vbcp; + qlo=-p[28]*xvar3/(1.0-p[29]); + qlo_xvar3=-p[28]/(1.0-p[29]); + qlo_Vbep=0.0; + qlo_Vbcp=qlo_xvar3*xvar3_Vbcp; + xvar1=(1.0-p[14]); + xvar2=(-p[29]); + xvar3=pow(xvar1,xvar2); + qdbcp=qlo+xvar3*((*Vbcp)-vl+vl0)-q0; + qdbcp_qlo=1.0; + qdbcp_Vbcp=xvar3; + qdbcp_vl=-xvar3; + qdbcp_Vbcp=qdbcp_Vbcp+qdbcp_qlo*qlo_Vbcp; + qdbcp_Vbep=qdbcp_qlo*qlo_Vbep; + qdbcp_Vbcp=qdbcp_Vbcp+qdbcp_vl*vl_Vbcp; + } + }else{ + qdbcp=0.0; + qdbcp_Vbcp=0.0; + } argi=(*Vbei)/(p[12]*Vtv); argi_Vbei=1.0/(p[12]*Vtv); expi=exp(argi); @@ -1706,6 +1935,23 @@ double Qbc_Kbci,Qbcx_Kbcx,Qbep_qdbep,Qbep_Ifp; qbp_q2p=1.0/sqrt(4.0*q2p+1.0); qbp_Vbep=qbp_q2p*q2p_Vbep; qbp_Vbci=qbp_q2p*q2p_Vbci; + argi=(*Vbcp)/(p[44]*Vtv); + argi_Vbcp=1.0/(p[44]*Vtv); + expi=exp(argi); + expi_argi=expi; + expi_Vbcp=expi_argi*argi_Vbcp; + Irp=p[42]*(expi-1.0); + Irp_expi=p[42]; + Irp_Vbcp=Irp_expi*expi_Vbcp; + (*Iccp)=(Ifp-Irp)/qbp; + Iccp_Ifp=1.0/qbp; + Iccp_Irp=-1.0/qbp; + Iccp_qbp=-(Ifp-Irp)/(qbp*qbp); + *Iccp_Vbep=Iccp_Ifp*Ifp_Vbep; + *Iccp_Vbci=Iccp_Ifp*Ifp_Vbci; + *Iccp_Vbcp=Iccp_Irp*Irp_Vbcp; + *Iccp_Vbep=(*Iccp_Vbep)+Iccp_qbp*qbp_Vbep; + *Iccp_Vbci=(*Iccp_Vbci)+Iccp_qbp*qbp_Vbci; }else{ Ifp=0.0; Ifp_Vbep=0.0; @@ -1713,6 +1959,10 @@ double Qbc_Kbci,Qbcx_Kbcx,Qbep_qdbep,Qbep_Ifp; qbp=1.0; qbp_Vbep=0.0; qbp_Vbci=0.0; + (*Iccp)=0.0; + *Iccp_Vbep=0.0; + *Iccp_Vbci=0.0; + *Iccp_Vbcp=0.0; } if(p[32]==1.0){ argi=(*Vbei)/(p[33]*Vtv); @@ -2018,6 +2268,33 @@ double Qbc_Kbci,Qbcx_Kbcx,Qbep_qdbep,Qbep_Ifp; *Irbp_Vbep=0.0; *Irbp_Vbci=0.0; } + if((p[47]>0.0)||(p[49]>0.0)){ + argi=(*Vbcp)/(p[48]*Vtv); + argi_Vbcp=1.0/(p[48]*Vtv); + expi=exp(argi); + expi_argi=expi; + expi_Vbcp=expi_argi*argi_Vbcp; + argn=(*Vbcp)/(p[50]*Vtv); + argn_Vbcp=1.0/(p[50]*Vtv); + expn=exp(argn); + expn_argn=expn; + expn_Vbcp=expn_argn*argn_Vbcp; + (*Ibcp)=p[47]*(expi-1.0)+p[49]*(expn-1.0); + Ibcp_expi=p[47]; + Ibcp_expn=p[49]; + *Ibcp_Vbcp=Ibcp_expi*expi_Vbcp; + *Ibcp_Vbcp=(*Ibcp_Vbcp)+Ibcp_expn*expn_Vbcp; + }else{ + (*Ibcp)=0.0; + *Ibcp_Vbcp=0.0; + } + if(p[9]>0.0){ + (*Irs)=(*Vrs)/p[9]; + *Irs_Vrs=1.0/p[9]; + }else{ + (*Irs)=0.0; + *Irs_Vrs=0.0; + } if(Ifi>0.0){ sgIf=1.0; }else{ @@ -2072,6 +2349,10 @@ double Qbc_Kbci,Qbcx_Kbcx,Qbep_qdbep,Qbep_Ifp; *Qbep_Vbep=Qbep_qdbep*qdbep_Vbep; *Qbep_Vbep=(*Qbep_Vbep)+Qbep_Ifp*Ifp_Vbep; *Qbep_Vbci=Qbep_Ifp*Ifp_Vbci; + (*Qbcp)=p[27]*qdbcp+p[87]*(*Vbcp); + Qbcp_qdbcp=p[27]; + *Qbcp_Vbcp=p[87]; + *Qbcp_Vbcp=(*Qbcp_Vbcp)+Qbcp_qdbcp*qdbcp_Vbcp; (*Qbeo)=(*Vbe)*p[15]; *Qbeo_Vbe=p[15]; (*Qbco)=(*Vbc)*p[20]; @@ -2129,6 +2410,16 @@ double Qbc_Kbci,Qbcx_Kbcx,Qbep_qdbep,Qbep_Ifp; *Qbeo_Vbe=(*SCALE)*(*Qbeo_Vbe); *Qbco=(*SCALE)*(*Qbco); *Qbco_Vbc=(*SCALE)*(*Qbco_Vbc); + *Ibcp=(*SCALE)*(*Ibcp); + *Ibcp_Vbcp=(*SCALE)*(*Ibcp_Vbcp); + *Iccp=(*SCALE)*(*Iccp); + *Iccp_Vbep=(*SCALE)*(*Iccp_Vbep); + *Iccp_Vbci=(*SCALE)*(*Iccp_Vbci); + *Iccp_Vbcp=(*SCALE)*(*Iccp_Vbcp); + *Irs=(*SCALE)*(*Irs); + *Irs_Vrs=(*SCALE)*(*Irs_Vrs); + *Qbcp=(*SCALE)*(*Qbcp); + *Qbcp_Vbcp=(*SCALE)*(*Qbcp_Vbcp); } return(0); } diff --git a/src/spicelib/devices/vbic/vbicmask.c b/src/spicelib/devices/vbic/vbicmask.c index 889f8fd1f..babc94cd0 100644 --- a/src/spicelib/devices/vbic/vbicmask.c +++ b/src/spicelib/devices/vbic/vbicmask.c @@ -23,7 +23,7 @@ VBICmAsk(CKTcircuit *ckt, GENmodel *instPtr, int which, IFvalue *value) switch(which) { case VBIC_MOD_TNOM: - value->rValue = here->VBICtnom-CONSTCtoK; + value->rValue = here->VBICtnom; return(OK); case VBIC_MOD_RCX: value->rValue = here->VBICextCollResist; diff --git a/src/spicelib/devices/vbic/vbicmpar.c b/src/spicelib/devices/vbic/vbicmpar.c index 914c0350d..66ffaaaf6 100644 --- a/src/spicelib/devices/vbic/vbicmpar.c +++ b/src/spicelib/devices/vbic/vbicmpar.c @@ -41,6 +41,7 @@ VBICmParam(int param, IFvalue *value, GENmodel *inModel) break; case VBIC_MOD_RCX: mods->VBICextCollResist = value->rValue; + if (mods->VBICextCollResist < 0.1) mods->VBICextCollResist = 0.1; mods->VBICextCollResistGiven = TRUE; break; case VBIC_MOD_RCI: @@ -62,6 +63,7 @@ VBICmParam(int param, IFvalue *value, GENmodel *inModel) break; case VBIC_MOD_RBX: mods->VBICextBaseResist = value->rValue; + if (mods->VBICextBaseResist < 0.1) mods->VBICextBaseResist = 0.1; mods->VBICextBaseResistGiven = TRUE; break; case VBIC_MOD_RBI: @@ -71,10 +73,12 @@ VBICmParam(int param, IFvalue *value, GENmodel *inModel) break; case VBIC_MOD_RE: mods->VBICemitterResist = value->rValue; + if (mods->VBICemitterResist < 0.1) mods->VBICemitterResist = 0.1; mods->VBICemitterResistGiven = TRUE; break; case VBIC_MOD_RS: mods->VBICsubstrateResist = value->rValue; + if (mods->VBICsubstrateResist < 0.1) mods->VBICsubstrateResist = 0.1; mods->VBICsubstrateResistGiven = TRUE; break; case VBIC_MOD_RBP: diff --git a/src/spicelib/devices/vbic/vbicnoise.c b/src/spicelib/devices/vbic/vbicnoise.c index 636376696..e6afbf936 100644 --- a/src/spicelib/devices/vbic/vbicnoise.c +++ b/src/spicelib/devices/vbic/vbicnoise.c @@ -51,9 +51,11 @@ VBICnoise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, Ndata * "_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 */ + "_ibep", /* noise due to ibep */ + "_1overfbe", /* flicker (1/f) noise ibe */ + "_1overfbep", /* flicker (1/f) noise ibep */ + "_rs", /* noise due to rs */ + "_iccp", /* noise due to iccp */ "" /* total transistor noise */ }; @@ -147,6 +149,10 @@ if (!data->namelist) return(E_NOMEM); ckt,THERMNOISE,inst->VBICemitEINode,inst->VBICemitNode, *(ckt->CKTstate0 + inst->VBICirbp_Vrbp)); + NevalSrc(&noizDens[VBICRSNOIZ],&lnNdens[VBICRSNOIZ], + ckt,THERMNOISE,inst->VBICsubsSINode,inst->VBICsubsNode, + model->VBICsubstrateConduct * inst->VBICarea * inst->VBICm); + NevalSrc(&noizDens[VBICICNOIZ],&lnNdens[VBICICNOIZ], ckt,SHOTNOISE,inst->VBICcollCINode, inst->VBICemitEINode, @@ -160,6 +166,10 @@ if (!data->namelist) return(E_NOMEM); ckt,SHOTNOISE,inst->VBICbaseBXNode, inst->VBICbaseBPNode, *(ckt->CKTstate0 + inst->VBICibep)); + NevalSrc(&noizDens[VBICICCPNOIZ],&lnNdens[VBICICCPNOIZ], + ckt,SHOTNOISE,inst->VBICbaseBXNode, inst->VBICsubsSINode, + *(ckt->CKTstate0 + inst->VBICiccp)); + NevalSrc(&noizDens[VBICFLBENOIZ],(double*)NULL,ckt, N_GAIN,inst->VBICbaseBINode, inst->VBICemitEINode, diff --git a/src/spicelib/devices/vbic/vbicpzld.c b/src/spicelib/devices/vbic/vbicpzld.c index 89a6e7905..5de192bf0 100644 --- a/src/spicelib/devices/vbic/vbicpzld.c +++ b/src/spicelib/devices/vbic/vbicpzld.c @@ -26,9 +26,11 @@ VBICpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s) ,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; + ,Irbi_Vbci,Ire_Vre,Irbp_Vrbp,Irbp_Vbep,Irbp_Vbci + ,Ibcp_Vbcp,Iccp_Vbep,Irs_Vrs,Iccp_Vbci,Iccp_Vbcp; double XQbe_Vbei, XQbe_Vbci, XQbex_Vbex, XQbc_Vbci, - XQbcx_Vbcx, XQbep_Vbep, XQbep_Vbci; + XQbcx_Vbcx, XQbep_Vbep, XQbep_Vbci, + XQbcp_Vbcp; /* loop through all the models */ for( ; model != NULL; model = model->VBICnextModel) { @@ -36,12 +38,14 @@ VBICpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s) /* 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; + 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; + Irs_Vrs = 1.0 / here->VBICtsubstrateResist * here->VBICarea * here->VBICm; Ibe_Vbei = *(ckt->CKTstate0 + here->VBICibe_Vbei); Ibex_Vbex = *(ckt->CKTstate0 + here->VBICibex_Vbex); @@ -61,6 +65,10 @@ VBICpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s) Irbp_Vrbp = *(ckt->CKTstate0 + here->VBICirbp_Vrbp); Irbp_Vbep = *(ckt->CKTstate0 + here->VBICirbp_Vbep); Irbp_Vbci = *(ckt->CKTstate0 + here->VBICirbp_Vbci); + Ibcp_Vbcp = *(ckt->CKTstate0 + here->VBICibcp_Vbcp); + Iccp_Vbep = *(ckt->CKTstate0 + here->VBICiccp_Vbep); + Iccp_Vbci = *(ckt->CKTstate0 + here->VBICiccp_Vbci); + Iccp_Vbcp = *(ckt->CKTstate0 + here->VBICiccp_Vbcp); /* c The real part @@ -186,6 +194,35 @@ c Stamp element: Irbp *(here->VBICcollCXBaseBIPtr) += -Irbp_Vbci; *(here->VBICcollCXCollCIPtr) += Irbp_Vbci; /* +c Stamp element: Ibcp +*/ + *(here->VBICsubsSISubsSIPtr) += Ibcp_Vbcp; + *(here->VBICsubsSIBaseBPPtr) += -Ibcp_Vbcp; + *(here->VBICbaseBPSubsSIPtr) += -Ibcp_Vbcp; + *(here->VBICbaseBPBaseBPPtr) += Ibcp_Vbcp; +/* +c Stamp element: Iccp +*/ + *(here->VBICbaseBXBaseBXPtr) += Iccp_Vbep; + *(here->VBICbaseBXBaseBPPtr) += -Iccp_Vbep; + *(here->VBICbaseBXBaseBIPtr) += Iccp_Vbci; + *(here->VBICbaseBXCollCIPtr) += -Iccp_Vbci; + *(here->VBICbaseBXSubsSIPtr) += Iccp_Vbcp; + *(here->VBICbaseBXBaseBPPtr) += -Iccp_Vbcp; + *(here->VBICsubsSIBaseBXPtr) += -Iccp_Vbep; + *(here->VBICsubsSIBaseBPPtr) += Iccp_Vbep; + *(here->VBICsubsSIBaseBIPtr) += -Iccp_Vbci; + *(here->VBICsubsSICollCIPtr) += Iccp_Vbci; + *(here->VBICsubsSISubsSIPtr) += -Iccp_Vbcp; + *(here->VBICsubsSIBaseBPPtr) += Iccp_Vbcp; +/* +c Stamp element: Irs +*/ + *(here->VBICsubsSubsPtr) += Irs_Vrs; + *(here->VBICsubsSISubsSIPtr) += Irs_Vrs; + *(here->VBICsubsSISubsPtr) += -Irs_Vrs; + *(here->VBICsubsSubsSIPtr) += -Irs_Vrs; +/* c The complex part */ XQbe_Vbei = *(ckt->CKTstate0 + here->VBICcqbe); @@ -195,77 +232,89 @@ c The complex part XQbcx_Vbcx = *(ckt->CKTstate0 + here->VBICcqbcx); XQbep_Vbep = *(ckt->CKTstate0 + here->VBICcqbep); XQbep_Vbci = *(ckt->CKTstate0 + here->VBICcqbepci); + XQbcp_Vbcp = *(ckt->CKTstate0 + here->VBICcqbcp) * ckt->CKTomega; /* 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)); + *(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)); + *(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)); + *(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)); + *(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)); + *(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); +/* +c Stamp element: Qbcp +*/ + *(here->VBICsubsSISubsSIPtr) += XQbcp_Vbcp; + *(here->VBICsubsSISubsSIPtr + 1) += XQbcp_Vbcp; + *(here->VBICsubsSIBaseBPPtr) += -XQbcp_Vbcp; + *(here->VBICsubsSIBaseBPPtr + 1) += -XQbcp_Vbcp; + *(here->VBICbaseBPSubsSIPtr) += -XQbcp_Vbcp; + *(here->VBICbaseBPSubsSIPtr + 1) += -XQbcp_Vbcp; + *(here->VBICbaseBPBaseBPPtr) += XQbcp_Vbcp; + *(here->VBICbaseBPBaseBPPtr + 1) += XQbcp_Vbcp; } } diff --git a/src/spicelib/devices/vbic/vbicsetup.c b/src/spicelib/devices/vbic/vbicsetup.c index fbecbd1ce..27aeae2dc 100644 --- a/src/spicelib/devices/vbic/vbicsetup.c +++ b/src/spicelib/devices/vbic/vbicsetup.c @@ -434,6 +434,21 @@ matrixpointers: } } } + if(model->VBICsubstrateResist == 0) { + here->VBICsubsSINode = here->VBICsubsNode; + } else if(here->VBICsubsSINode == 0) { + error = CKTmkVolt(ckt,&tmp,here->VBICname, "substrate"); + if(error) return(error); + here->VBICsubsSINode = tmp->number; + if (ckt->CKTcopyNodesets) { + if (CKTinst2Node(ckt,here,4,&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); @@ -447,6 +462,10 @@ matrixpointers: if(error) return(error); here->VBICbaseBINode = tmp->number; + error = CKTmkVolt(ckt, &tmp, here->VBICname, "subsSI"); + if(error) return(error); + here->VBICsubsSINode = 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){\ @@ -455,12 +474,14 @@ if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\ TSTALLOC(VBICcollCollPtr,VBICcollNode,VBICcollNode) TSTALLOC(VBICbaseBasePtr,VBICbaseNode,VBICbaseNode) TSTALLOC(VBICemitEmitPtr,VBICemitNode,VBICemitNode) + TSTALLOC(VBICsubsSubsPtr,VBICsubsNode,VBICsubsNode) 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(VBICsubsSISubsSIPtr,VBICsubsSINode,VBICsubsSINode) TSTALLOC(VBICbaseEmitPtr,VBICbaseNode,VBICemitNode) TSTALLOC(VBICemitBasePtr,VBICemitNode,VBICbaseNode) @@ -469,6 +490,7 @@ if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\ TSTALLOC(VBICcollCollCXPtr,VBICcollNode,VBICcollCXNode) TSTALLOC(VBICbaseBaseBXPtr,VBICbaseNode,VBICbaseBXNode) TSTALLOC(VBICemitEmitEIPtr,VBICemitNode,VBICemitEINode) + TSTALLOC(VBICsubsSubsSIPtr,VBICsubsNode,VBICsubsSINode) TSTALLOC(VBICcollCXCollCIPtr,VBICcollCXNode,VBICcollCINode) TSTALLOC(VBICcollCXBaseBXPtr,VBICcollCXNode,VBICbaseBXNode) TSTALLOC(VBICcollCXBaseBIPtr,VBICcollCXNode,VBICbaseBINode) @@ -478,11 +500,14 @@ if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\ TSTALLOC(VBICbaseBXBaseBIPtr,VBICbaseBXNode,VBICbaseBINode) TSTALLOC(VBICbaseBXEmitEIPtr,VBICbaseBXNode,VBICemitEINode) TSTALLOC(VBICbaseBXBaseBPPtr,VBICbaseBXNode,VBICbaseBPNode) + TSTALLOC(VBICbaseBXSubsSIPtr,VBICbaseBXNode,VBICsubsSINode) TSTALLOC(VBICbaseBIEmitEIPtr,VBICbaseBINode,VBICemitEINode) + TSTALLOC(VBICbaseBPSubsSIPtr,VBICbaseBPNode,VBICsubsSINode) TSTALLOC(VBICcollCXCollPtr,VBICcollCXNode,VBICcollNode) TSTALLOC(VBICbaseBXBasePtr,VBICbaseBXNode,VBICbaseNode) TSTALLOC(VBICemitEIEmitPtr,VBICemitEINode,VBICemitNode) + TSTALLOC(VBICsubsSISubsPtr,VBICsubsSINode,VBICsubsNode) TSTALLOC(VBICcollCICollCXPtr,VBICcollCINode,VBICcollCXNode) TSTALLOC(VBICbaseBICollCXPtr,VBICbaseBINode,VBICcollCXNode) TSTALLOC(VBICbaseBPCollCXPtr,VBICbaseBPNode,VBICcollCXNode) @@ -493,8 +518,12 @@ if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\ TSTALLOC(VBICbaseBIBaseBXPtr,VBICbaseBINode,VBICbaseBXNode) TSTALLOC(VBICemitEIBaseBXPtr,VBICemitEINode,VBICbaseBXNode) TSTALLOC(VBICbaseBPBaseBXPtr,VBICbaseBPNode,VBICbaseBXNode) + TSTALLOC(VBICsubsSIBaseBXPtr,VBICsubsSINode,VBICbaseBXNode) TSTALLOC(VBICemitEIBaseBIPtr,VBICemitEINode,VBICbaseBINode) TSTALLOC(VBICbaseBPBaseBIPtr,VBICbaseBPNode,VBICbaseBINode) + TSTALLOC(VBICsubsSICollCIPtr,VBICsubsSINode,VBICcollCINode) + TSTALLOC(VBICsubsSIBaseBIPtr,VBICsubsSINode,VBICbaseBINode) + TSTALLOC(VBICsubsSIBaseBPPtr,VBICsubsSINode,VBICbaseBPNode) } } @@ -551,6 +580,12 @@ VBICunsetup(inModel,ckt) CKTdltNNum(ckt, here->VBICemitEINode); here->VBICemitEINode = 0; } + if (here->VBICsubsSINode + && here->VBICsubsSINode != here->VBICsubsNode) + { + CKTdltNNum(ckt, here->VBICsubsSINode); + here->VBICsubsSINode = 0; + } } } return OK; diff --git a/src/spicelib/devices/vbic/vbictemp.c b/src/spicelib/devices/vbic/vbictemp.c index 58bfebc0a..1f9755922 100644 --- a/src/spicelib/devices/vbic/vbictemp.c +++ b/src/spicelib/devices/vbic/vbictemp.c @@ -24,7 +24,7 @@ VBICtemp(GENmodel *inModel, CKTcircuit *ckt) VBICmodel *model = (VBICmodel *)inModel; VBICinstance *here; double p[108], pnom[108], TAMB; - int iret, vbic_3T_it_cf_t(double *, double *, double *); + int iret, vbic_4T_it_cf_t(double *, double *, double *); double vt; /* loop through all the bipolar models */ @@ -47,11 +47,17 @@ VBICtemp(GENmodel *inModel, CKTcircuit *ckt) } else { model->VBICemitterConduct = 0.0; } + if(model->VBICsubstrateResistGiven && model->VBICsubstrateResist != 0.0) { + model->VBICsubstrateConduct = 1.0 / model->VBICsubstrateResist; + } else { + model->VBICsubstrateConduct = 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->VBICowner != ARCHme) continue; if(!here->VBICtempGiven) here->VBICtemp = ckt->CKTtemp; @@ -168,7 +174,7 @@ VBICtemp(GENmodel *inModel, CKTcircuit *ckt) pnom[106] = model->VBICrevVersion; pnom[107] = model->VBICrefVersion; - iret = vbic_3T_it_cf_t(p,pnom,&TAMB); + iret = vbic_4T_it_cf_t(p,pnom,&TAMB); here->VBICttnom = p[0]; here->VBICtextCollResist = p[1]; @@ -213,7 +219,7 @@ VBICtemp(GENmodel *inModel, CKTcircuit *ckt) return(OK); } -int vbic_3T_it_cf_t(p,pnom,TAMB) +int vbic_4T_it_cf_t(p,pnom,TAMB) double *p, *pnom, *TAMB; { double Tini, Tdev, Vtv, rT, dT, xvar1; diff --git a/src/spicelib/devices/vbic/vbictrunc.c b/src/spicelib/devices/vbic/vbictrunc.c index cb2b25fd0..35d5e0a91 100644 --- a/src/spicelib/devices/vbic/vbictrunc.c +++ b/src/spicelib/devices/vbic/vbictrunc.c @@ -35,6 +35,7 @@ VBICtrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep) CKTterr(here->VBICqbep,ckt,timeStep); CKTterr(here->VBICqbeo,ckt,timeStep); CKTterr(here->VBICqbco,ckt,timeStep); + CKTterr(here->VBICqbcp,ckt,timeStep); } } return(OK);