From d63123a269b1525c8d758cc9b1816665f18babe5 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Mon, 2 Apr 2018 20:15:13 +0200 Subject: [PATCH] gate resistance und gate conductance added, prime gate node added, not yet o.k. when rg is set, probably wrong signedness --- src/spicelib/devices/vdmos/vdmosdefs.h | 20 +++++++++ src/spicelib/devices/vdmos/vdmosload.c | 22 ++++++---- src/spicelib/devices/vdmos/vdmosset.c | 58 ++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 9 deletions(-) diff --git a/src/spicelib/devices/vdmos/vdmosdefs.h b/src/spicelib/devices/vdmos/vdmosdefs.h index 83df9d652..0d7f9a564 100644 --- a/src/spicelib/devices/vdmos/vdmosdefs.h +++ b/src/spicelib/devices/vdmos/vdmosdefs.h @@ -44,6 +44,7 @@ typedef struct sVDMOSinstance { const int VDMOSbNode; /* number of the bulk node of the mosfet */ int VDMOSdNodePrime; /* number of the internal drain node of the mosfet */ int VDMOSsNodePrime; /* number of the internal source node of the mosfet */ + int VDMOSgNodePrime; /* number of the internal gate node of the mosfet */ double VDMOSm; /* parallel device multiplier */ @@ -231,6 +232,25 @@ typedef struct sVDMOSinstance { * (source prime node,bulk node) */ double *VDMOSSPdpPtr; /* pointer to sparse matrix element at * (source prime node,drain prime node) */ + /* added for VDMOS */ + double *VDMOSGPgpPtr; /* pointer to sparse matrix element at + * (gate prime node, gate prime node) */ + double *VDMOSGPbPtr; /* pointer to sparse matrix element at + * (gate prime node, bulk node) */ + double *VDMOSGPdpPtr; /* pointer to sparse matrix element at + * (gate prime node, drain prime node) */ + double *VDMOSGPspPtr; /* pointer to sparse matrix element at + * (gate prime node, source prime node) */ + double *VDMOSBgpPtr; /* pointer to sparse matrix element at + * (bulk node, gate prime node) */ + double *VDMOSDPgpPtr; /* pointer to sparse matrix element at + * (drain prime node, gate prime node) */ + double *VDMOSSPgpPtr; /* pointer to sparse matrix element at + * (source prime node, gate prime node) */ + double *VDMOSGgpPtr; /* pointer to sparse matrix element at + * (gate node, gate prime node) */ + double *VDMOSGPgPtr; /* pointer to sparse matrix element at + * (gate prime node, gate node) */ } VDMOSinstance ; diff --git a/src/spicelib/devices/vdmos/vdmosload.c b/src/spicelib/devices/vdmos/vdmosload.c index 700ad986c..986aa00f9 100644 --- a/src/spicelib/devices/vdmos/vdmosload.c +++ b/src/spicelib/devices/vdmos/vdmosload.c @@ -171,7 +171,7 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt) *(ckt->CKTrhsOld + here->VDMOSbNode) - *(ckt->CKTrhsOld + here->VDMOSsNodePrime)); vgs = model->VDMOStype * ( - *(ckt->CKTrhsOld + here->VDMOSgNode) - + *(ckt->CKTrhsOld + here->VDMOSgNodePrime) - *(ckt->CKTrhsOld + here->VDMOSsNodePrime)); vds = model->VDMOStype * ( *(ckt->CKTrhsOld + here->VDMOSdNodePrime) - @@ -817,7 +817,7 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt) cdreq = -(model->VDMOStype)*(cdrain - here->VDMOSgds*(-vds) - here->VDMOSgm*vgd - here->VDMOSgmbs*vbd); } - *(ckt->CKTrhs + here->VDMOSgNode) -= + *(ckt->CKTrhs + here->VDMOSgNodePrime) -= (model->VDMOStype * (ceqgs + ceqgb + ceqgd)); *(ckt->CKTrhs + here->VDMOSbNode) -= (ceqbs + ceqbd - model->VDMOStype * ceqgb); @@ -830,7 +830,7 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt) */ *(here->VDMOSDdPtr) += (here->VDMOSdrainConductance); - *(here->VDMOSGgPtr) += ((gcgd + gcgs + gcgb)); + *(here->VDMOSGgPtr) += (here->VDMOSgateConductance); //((gcgd + gcgs + gcgb)); *(here->VDMOSSsPtr) += (here->VDMOSsourceConductance); *(here->VDMOSBbPtr) += (here->VDMOSgbd + here->VDMOSgbs + gcgb); *(here->VDMOSDPdpPtr) += @@ -839,20 +839,24 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt) *(here->VDMOSSPspPtr) += (here->VDMOSsourceConductance + here->VDMOSgds + here->VDMOSgbs + xnrm*(here->VDMOSgm + here->VDMOSgmbs) + gcgs); + *(here->VDMOSGPgpPtr) += + (here->VDMOSgateConductance) + (gcgd + gcgs + gcgb); + *(here->VDMOSGgpPtr) += (-here->VDMOSgateConductance); *(here->VDMOSDdpPtr) += (-here->VDMOSdrainConductance); - *(here->VDMOSGbPtr) -= gcgb; - *(here->VDMOSGdpPtr) -= gcgd; - *(here->VDMOSGspPtr) -= gcgs; + *(here->VDMOSGPgPtr) += (-here->VDMOSgateConductance); + *(here->VDMOSGPbPtr) -= gcgb; + *(here->VDMOSGPdpPtr) -= gcgd; + *(here->VDMOSGPspPtr) -= gcgs; *(here->VDMOSSspPtr) += (-here->VDMOSsourceConductance); - *(here->VDMOSBgPtr) -= gcgb; + *(here->VDMOSBgpPtr) -= gcgb; *(here->VDMOSBdpPtr) -= here->VDMOSgbd; *(here->VDMOSBspPtr) -= here->VDMOSgbs; *(here->VDMOSDPdPtr) += (-here->VDMOSdrainConductance); - *(here->VDMOSDPgPtr) += ((xnrm - xrev)*here->VDMOSgm - gcgd); + *(here->VDMOSDPgpPtr) += ((xnrm - xrev)*here->VDMOSgm - gcgd); *(here->VDMOSDPbPtr) += (-here->VDMOSgbd + (xnrm - xrev)*here->VDMOSgmbs); *(here->VDMOSDPspPtr) += (-here->VDMOSgds - xnrm* (here->VDMOSgm + here->VDMOSgmbs)); - *(here->VDMOSSPgPtr) += (-(xnrm - xrev)*here->VDMOSgm - gcgs); + *(here->VDMOSSPgpPtr) += (-(xnrm - xrev)*here->VDMOSgm - gcgs); *(here->VDMOSSPsPtr) += (-here->VDMOSsourceConductance); *(here->VDMOSSPbPtr) += (-here->VDMOSgbs - (xnrm - xrev)*here->VDMOSgmbs); *(here->VDMOSSPdpPtr) += (-here->VDMOSgds - xrev* diff --git a/src/spicelib/devices/vdmos/vdmosset.c b/src/spicelib/devices/vdmos/vdmosset.c index 034f79982..a60b92796 100644 --- a/src/spicelib/devices/vdmos/vdmosset.c +++ b/src/spicelib/devices/vdmos/vdmosset.c @@ -188,11 +188,36 @@ VDMOSsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, here->VDMOSsNodePrime = here->VDMOSsNode; } + if (model->VDMOSgateResistance != 0 ) { + if (here->VDMOSgNodePrime == 0) { + error = CKTmkVolt(ckt, &tmp, here->VDMOSname, "gate"); + if (error) return(error); + here->VDMOSgNodePrime = tmp->number; + + if (ckt->CKTcopyNodesets) { + CKTnode *tmpNode; + IFuid tmpName; + + if (CKTinst2Node(ckt, here, 3, &tmpNode, &tmpName) == OK) { + if (tmpNode->nsGiven) { + tmp->nodeset = tmpNode->nodeset; + tmp->nsGiven = tmpNode->nsGiven; + } + } + } + } + } + else { + here->VDMOSgNodePrime = here->VDMOSgNode; + } + + /* macro to make elements with built in test for out of memory */ #define TSTALLOC(ptr,first,second) \ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ return(E_NOMEM);\ } } while(0) +/* TSTALLOC(VDMOSDdPtr, VDMOSdNode, VDMOSdNode); TSTALLOC(VDMOSGgPtr, VDMOSgNode, VDMOSgNode); TSTALLOC(VDMOSSsPtr, VDMOSsNode, VDMOSsNode); @@ -215,6 +240,34 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ TSTALLOC(VDMOSDPbPtr, VDMOSdNodePrime, VDMOSbNode); TSTALLOC(VDMOSSPbPtr, VDMOSsNodePrime, VDMOSbNode); TSTALLOC(VDMOSSPdpPtr, VDMOSsNodePrime, VDMOSdNodePrime); +*/ + + TSTALLOC(VDMOSDdPtr, VDMOSdNode, VDMOSdNode); + TSTALLOC(VDMOSGgPtr, VDMOSgNode, VDMOSgNode); + TSTALLOC(VDMOSSsPtr, VDMOSsNode, VDMOSsNode); + TSTALLOC(VDMOSBbPtr, VDMOSbNode, VDMOSbNode); + TSTALLOC(VDMOSDPdpPtr, VDMOSdNodePrime, VDMOSdNodePrime); + TSTALLOC(VDMOSSPspPtr, VDMOSsNodePrime, VDMOSsNodePrime); + TSTALLOC(VDMOSGPgpPtr, VDMOSgNodePrime, VDMOSgNodePrime); + TSTALLOC(VDMOSDdpPtr, VDMOSdNode, VDMOSdNodePrime); + TSTALLOC(VDMOSGPbPtr, VDMOSgNodePrime, VDMOSbNode); + TSTALLOC(VDMOSGPdpPtr, VDMOSgNodePrime, VDMOSdNodePrime); + TSTALLOC(VDMOSGPspPtr, VDMOSgNodePrime, VDMOSsNodePrime); + TSTALLOC(VDMOSSspPtr, VDMOSsNode, VDMOSsNodePrime); + TSTALLOC(VDMOSBdpPtr, VDMOSbNode, VDMOSdNodePrime); + TSTALLOC(VDMOSBspPtr, VDMOSbNode, VDMOSsNodePrime); + TSTALLOC(VDMOSDPspPtr, VDMOSdNodePrime, VDMOSsNodePrime); + TSTALLOC(VDMOSDPdPtr, VDMOSdNodePrime, VDMOSdNode); + TSTALLOC(VDMOSBgpPtr, VDMOSbNode, VDMOSgNodePrime); + TSTALLOC(VDMOSDPgpPtr, VDMOSdNodePrime, VDMOSgNodePrime); + TSTALLOC(VDMOSSPgpPtr, VDMOSsNodePrime, VDMOSgNodePrime); + TSTALLOC(VDMOSSPsPtr, VDMOSsNodePrime, VDMOSsNode); + TSTALLOC(VDMOSDPbPtr, VDMOSdNodePrime, VDMOSbNode); + TSTALLOC(VDMOSSPbPtr, VDMOSsNodePrime, VDMOSbNode); + TSTALLOC(VDMOSSPdpPtr, VDMOSsNodePrime, VDMOSdNodePrime); + + TSTALLOC(VDMOSGgpPtr, VDMOSgNode, VDMOSgNodePrime); + TSTALLOC(VDMOSGPgPtr, VDMOSgNodePrime, VDMOSgNode); } } @@ -242,6 +295,11 @@ VDMOSunsetup(GENmodel *inModel, CKTcircuit *ckt) && here->VDMOSdNodePrime != here->VDMOSdNode) CKTdltNNum(ckt, here->VDMOSdNodePrime); here->VDMOSdNodePrime = 0; + + if (here->VDMOSgNodePrime > 0 + && here->VDMOSgNodePrime != here->VDMOSgNode) + CKTdltNNum(ckt, here->VDMOSgNodePrime); + here->VDMOSgNodePrime = 0; } } return OK;