⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mos1dset.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: 1988 Jaijeet S Roychowdhury**********/#include "spice.h"#include <stdio.h>#include "cktdefs.h"#include "devdefs.h"#include "mos1defs.h"#include "util.h"#include "distodef.h"#include "const.h"#include "sperror.h"#include "suffix.h"intMOS1dSetup(inModel,ckt)    GENmodel *inModel;    register CKTcircuit *ckt;        /* actually load the current value into the          * sparse matrix previously provided          */{    register MOS1model *model = (MOS1model *) inModel;    register MOS1instance *here;    double Beta;    double DrainSatCur;    double EffectiveLength;    double GateBulkOverlapCap;    double GateDrainOverlapCap;    double GateSourceOverlapCap;    double OxideCap;    double SourceSatCur;    double gm;    double gds;    double gb;    double ebd;    double vgst;    double evbs;    double sargsw;    double vbd;    double vbs;    double vds;    double arg;    double sarg;    double vdsat;    double vgd;    double vgs;    double von;    double vt;    double lgbs;    double lgbs2;    double lgbs3;    double lgbd;    double lgbd2;    double lgbd3;    double gm2;    double gds2;    double gb2;    double gmds;    double gmb;    double gbds;    double gm3;    double gds3;    double gb3;    double gm2ds;    double gmds2;    double gm2b;    double gmb2;    double gb2ds;    double gbds2;    double lcapgb2;    double lcapgb3;    double lcapgs2;    double lcapgs3;    double lcapgd2;    double lcapgd3;    double lcapbs2;    double lcapbs3;    double lcapbd2;    double lcapbd3;    double gmbds;#ifndef NOBYPASS#endif /*NOBYPASS*/    /*  loop through all the MOS1 device models */    for( ; model != NULL; model = model->MOS1nextModel ) {        /* loop through all the instances of the model */        for (here = model->MOS1instances; here != NULL ;                here=here->MOS1nextInstance) {	    if (here->MOS1owner != ARCHme) continue;            vt = CONSTKoverQ * here->MOS1temp;            EffectiveLength=here->MOS1l - 2*model->MOS1latDiff;            if( (here->MOS1tSatCurDens == 0) ||                     (here->MOS1drainArea == 0) ||                    (here->MOS1sourceArea == 0)) {                DrainSatCur = here->MOS1tSatCur;                SourceSatCur = here->MOS1tSatCur;            } else {                DrainSatCur = here->MOS1tSatCurDens *                         here->MOS1drainArea;                SourceSatCur = here->MOS1tSatCurDens *                         here->MOS1sourceArea;            }            GateSourceOverlapCap = model->MOS1gateSourceOverlapCapFactor *                     here->MOS1w;            GateDrainOverlapCap = model->MOS1gateDrainOverlapCapFactor *                     here->MOS1w;            GateBulkOverlapCap = model->MOS1gateBulkOverlapCapFactor *                     EffectiveLength;            Beta = here->MOS1tTransconductance * here->MOS1w/EffectiveLength;            OxideCap = model->MOS1oxideCapFactor * EffectiveLength *                     here->MOS1w;                    vbs = model->MOS1type * (                         *(ckt->CKTrhsOld+here->MOS1bNode) -                        *(ckt->CKTrhsOld+here->MOS1sNodePrime));                    vgs = model->MOS1type * (                         *(ckt->CKTrhsOld+here->MOS1gNode) -                        *(ckt->CKTrhsOld+here->MOS1sNodePrime));                    vds = model->MOS1type * (                         *(ckt->CKTrhsOld+here->MOS1dNodePrime) -                        *(ckt->CKTrhsOld+here->MOS1sNodePrime));                /* now some common crunching for some more useful quantities */                vbd=vbs-vds;                vgd=vgs-vds;            /*             * bulk-source and bulk-drain diodes             *   here we just evaluate the ideal diode current and the             *   corresponding derivative (conductance).             */next1:      if(vbs <= 0) {                lgbs = SourceSatCur/vt;                lgbs += ckt->CKTgmin;		lgbs2 = lgbs3 = 0;            } else {                evbs = exp(MIN(MAX_EXP_ARG,vbs/vt));                lgbs = SourceSatCur*evbs/vt + ckt->CKTgmin;		lgbs2 = model->MOS1type *0.5 * (lgbs - ckt->CKTgmin)/vt;		lgbs3 = model->MOS1type *lgbs2/(vt*3);            }            if(vbd <= 0) {                lgbd = DrainSatCur/vt;                lgbd += ckt->CKTgmin;		lgbd2 = lgbd3 = 0;            } else {                ebd = exp(MIN(MAX_EXP_ARG,vbd/vt));                lgbd = DrainSatCur*ebd/vt +ckt->CKTgmin;		lgbd2 = model->MOS1type *0.5 * (lgbd - ckt->CKTgmin)/vt;		lgbd3 = model->MOS1type *lgbd2/(vt*3);            }            /* now to determine whether the user was able to correctly             * identify the source and drain of his device             */            if(vds >= 0) {                /* normal mode */                here->MOS1mode = 1;            } else {                /* inverse mode */                here->MOS1mode = -1;            }            /*             *     this block of code evaluates the drain current and its              *     derivatives using the shichman-hodges model and the              *     charges associated with the gate, channel and bulk for              *     mosfets             *             */            /* the following variables are local to this code block until              * it is obvious that they can be made global              */	     {            double betap;	    double dvondvbs;	    double d2vondvbs2;	    double d3vondvbs3;                if ((here->MOS1mode==1?vbs:vbd) <= 0 ) {                    sarg=sqrt(here->MOS1tPhi-(here->MOS1mode==1?vbs:vbd));		    if (-model->MOS1gamma != 0.0) {		    dvondvbs = -model->MOS1gamma*0.5/sarg;		    d2vondvbs2 = - dvondvbs*0.5/(sarg*sarg);		    d3vondvbs3 = 1.5*d2vondvbs2/(sarg*sarg);		    }		    else {		    dvondvbs = d2vondvbs2 = d3vondvbs3 = 0.0;		    }                } else {                    sarg=sqrt(here->MOS1tPhi);		    if (model->MOS1gamma != 0.0) {		    dvondvbs = -model->MOS1gamma/(sarg+sarg);		    }		    else {		    dvondvbs = 0.0;		    }		    d2vondvbs2 = d3vondvbs3 = 0;                    sarg=sarg-(here->MOS1mode==1?vbs:vbd)/(sarg+sarg);                    sarg=MAX(0,sarg);		    dvondvbs = (sarg<=0?0:dvondvbs);                }                von=(here->MOS1tVbi*model->MOS1type)+model->MOS1gamma*sarg;                vgst=(here->MOS1mode==1?vgs:vgd)-von;                vdsat=MAX(vgst,0);/*                if (sarg <= 0) {                    arg=0;                } else {                    arg=model->MOS1gamma/(sarg+sarg);                } */                if (vgst <= 0) {                    /*                     *     cutoff region                     */		    /* cdrain = 0 */                    gm=0;                    gds=0;                    gb=0;		    gm2=gb2=gds2=0;		    gmds=gbds=gmb=0;		    gm3=gb3=gds3=0;		    gm2ds=gmds2=gm2b=gmb2=gb2ds=gbds2=0;                } else{                    /*                     *     saturation region                     */                    betap=Beta*(1+model->MOS1lambda*(vds*here->MOS1mode));			/* cdrain = betap * vgst * vgst * 0.5; */                    if (vgst <= (vds*here->MOS1mode)){                        gm=betap*vgst;                        gds=model->MOS1lambda*Beta*vgst*vgst*.5;                   /*     gb=here->MOS1gm*arg; */			gb= -gm*dvondvbs;			gm2 = betap;			gds2 = 0;			gb2 = -(gm*d2vondvbs2 - betap*dvondvbs*dvondvbs);			gmds = vgst*model->MOS1lambda*Beta;			gbds = - gmds*dvondvbs;			gmb = -betap*dvondvbs;			gm3 = 0;			gb3 = -(gmb*d2vondvbs2 + gm*d3vondvbs3 -				betap*2*dvondvbs*d2vondvbs2);			gds3 = 0;			gm2ds = Beta * model->MOS1lambda;			gm2b = 0;			gmb2 = -betap*d2vondvbs2;			gb2ds = -(gmds*d2vondvbs2 - dvondvbs*dvondvbs*				Beta * model->MOS1lambda);			gmds2 = 0;			gbds2 = 0;			gmbds = -Beta * model->MOS1lambda*dvondvbs;                    } else {                    /*                     *     linear region                     */			/* cdrain = betap * vds * (vgst - vds/2); */                        gm=betap*(vds*here->MOS1mode);                        gds= Beta * model->MOS1lambda*(vgst*				vds*here->MOS1mode - vds*vds*0.5) +				betap*(vgst - vds*here->MOS1mode);                        /* gb=gm*arg; */			gb = - gm*dvondvbs;			gm2 = 0;			gb2 = -(gm*d2vondvbs2);			gds2 = 2*Beta * model->MOS1lambda*(vgst - 				vds*here->MOS1mode) - betap;			gmds = Beta * model->MOS1lambda* vds *				here->MOS1mode + betap;			gbds = - gmds*dvondvbs;			gmb=0;			gm3=0;			gb3 = -gm*d3vondvbs3;			gds3 = -Beta*model->MOS1lambda*3.;			gm2ds=gm2b=gmb2=0;			gmds2 = 2*model->MOS1lambda*Beta;			gb2ds = -(gmds*d2vondvbs2);			gbds2 = -gmds2*dvondvbs;			gmbds = 0;                    }                }                /*                 *     finished                 */            } /* code block */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -