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

📄 mos2dset.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: 1988 Jaijeet S Roychowdhury**********/#include <stdio.h>#include "spice.h"#include "util.h"#include "distodef.h"#include "devdefs.h"#include "cktdefs.h"#include "mos2defs.h"#include "trandefs.h"#include "const.h"#include "sperror.h"#include "suffix.h"/* assuming silicon - make definition for epsilon of silicon */#define EPSSIL (11.7 * 8.854214871e-12)static double sig1[4] = {1.0, -1.0, 1.0, -1.0};static double sig2[4] = {1.0,  1.0,-1.0, -1.0};intMOS2dSetup(inModel,ckt)    GENmodel *inModel;    register CKTcircuit *ckt;        /* actually load the current value into the          * sparse matrix previously provided          */{    register MOS2model *model = (MOS2model *)inModel;    register MOS2instance *here;    double Beta;    double DrainSatCur;    double EffectiveLength;    double GateBulkOverlapCap;    double GateDrainOverlapCap;    double GateSourceOverlapCap;    double OxideCap;    double SourceSatCur;    double arg;    double cdrain;    double ebd;    double evbs;    double sarg;    double sargsw;    double vbd;    double vbs;    double vds;    double vdsat;    double vgb;    double vgd;    double vgs;    double von;    double vt;      /* K * T / Q */    double lcapgs2;    double lcapgd2;     double lcapgb2;    double lcapgs3;      double lcapgd3;     double lcapgb3;    double lgbs, lgbs2, lgbs3;    double lgbd, lgbd2, lgbd3;            double vgst;double lcapbs, lcapbs2, lcapbs3;double lcapbd, lcapbd2, lcapbd3;double gm2, gb2, gds2;double gmb, gmds, gbds;double gm3, gb3, gds3;double gm2b, gm2ds, gmb2, gmds2, gbds2, gb2ds;double gmbds;    Dderivs d_cdrain;    /*  loop through all the MOS2 device models */    for( ; model != NULL; model = model->MOS2nextModel ) {        /* loop through all the instances of the model */        for (here = model->MOS2instances; here != NULL ;                here=here->MOS2nextInstance) {	    if (here->MOS2owner != ARCHme) continue;            vt = CONSTKoverQ * here->MOS2temp;            EffectiveLength=here->MOS2l - 2*model->MOS2latDiff;            if( (here->MOS2tSatCurDens == 0) ||                     (here->MOS2drainArea == 0) ||                    (here->MOS2sourceArea == 0)) {                DrainSatCur = here->MOS2tSatCur;                SourceSatCur = here->MOS2tSatCur;            } else {                DrainSatCur = here->MOS2tSatCurDens *                         here->MOS2drainArea;                SourceSatCur = here->MOS2tSatCurDens *                         here->MOS2sourceArea;            }            GateSourceOverlapCap = model->MOS2gateSourceOverlapCapFactor *                     here->MOS2w;            GateDrainOverlapCap = model->MOS2gateDrainOverlapCapFactor *                     here->MOS2w;            GateBulkOverlapCap = model->MOS2gateBulkOverlapCapFactor *                     EffectiveLength;            Beta = here->MOS2tTransconductance * here->MOS2w/EffectiveLength;            OxideCap = model->MOS2oxideCapFactor * EffectiveLength *                     here->MOS2w;                    /* general iteration */                    vbs = model->MOS2type * (                         *(ckt->CKTrhsOld+here->MOS2bNode) -                        *(ckt->CKTrhsOld+here->MOS2sNodePrime));                    vgs = model->MOS2type * (                         *(ckt->CKTrhsOld+here->MOS2gNode) -                        *(ckt->CKTrhsOld+here->MOS2sNodePrime));                    vds = model->MOS2type * (                         *(ckt->CKTrhsOld+here->MOS2dNodePrime) -                        *(ckt->CKTrhsOld+here->MOS2sNodePrime));                /* now some common crunching for some more useful quantities */                    vbd=vbs-vds;                    vgd=vgs-vds;            /* now all the preliminaries are over - we can start doing the             * real work              */            vgb = vgs - vbs;            /* bulk-source and bulk-drain doides             * here we just evaluate the ideal diode current and the             * correspoinding 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->MOS2type *0.5 * (lgbs - ckt->CKTgmin)/vt;		lgbs3 = model->MOS2type *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->MOS2type *0.5 * (lgbd - ckt->CKTgmin)/vt;		lgbd3 = model->MOS2type *lgbd2/(vt*3);            }            if(vds >= 0) {                /* normal mode */                here->MOS2mode = 1;            } else {                /* inverse mode */                here->MOS2mode = -1;            }            {            /* moseq2(vds,vbs,vgs,gm,gds,gmbs,qg,qc,qb,             *        cggb,cgdb,cgsb,cbgb,cbdb,cbsb)             */            /* note:  cgdb, cgsb, cbdb, cbsb never used */            /*             *     this routine evaluates the drain current, its derivatives and             *     the charges associated with the gate, channel and bulk             *     for mosfets             *             */            double arg;            double sarg;            double a4[4],b4[4],x4[8],poly4[8];            double beta1;            double sphi;    /* square root of phi */            double sphi3;   /* square root of phi cubed */            double barg;            double factor;            double eta;            double vbin;            double argd;            double args;            double argss;            double argsd;            double argxs;            double argxd;            double gamasd;            double xwd;            double xws;            double gammad;            double cfs;            double cdonco;            double xn;            double argg;            double sarg3;            double sbiarg;            double body;            double udenom;            double gammd2;            double argv;            double vgsx;            double ufact;            double ueff;            double a1;            double a3;            double a;            double b1;            double b3;            double b;            double c1;            double c;            double d1;            double fi;            double p0;            double p2;            double p3;            double p4;            double p;            double r3;            double r;            double ro;            double s2;            double s;            double v1;            double v2;            double xv;            double y3;            double delta4;            double xvalid;            double bsarg;            double bodys;            double sargv;            double xlfact;            double xdv;            double xlv;            double xls;            double clfact;            double xleff;            double deltal;            double xwb;            double vdson;            double cdson;            double expg;            double xld;	double xlamda = model->MOS2lambda;	Dderivs d_xleff, d_delta1;	Dderivs d_xlfact;	Dderivs d_xlv, d_xls;	Dderivs d_bsarg, d_bodys, d_vdsat, d_sargv;	Dderivs d_delta4, d_a4[3], d_b4[3], d_x4[3], d_poly4[3];	Dderivs d_xvalid;	Dderivs d_ro, d_fi, d_y3, d_p3, d_p4, d_a3, d_b3;	Dderivs d_r3, d_s2, d_pee, d_p0, d_p2;	Dderivs d_b1, d_c1, d_d1, d_a, d_b, d_c, d_arr, d_s;	Dderivs d_xv, d_a1;	Dderivs d_v1, d_v2;	Dderivs d_argv,d_gammd2;	Dderivs d_ufact;	Dderivs d_udenom;	Dderivs d_sarg3, d_body;	Dderivs d_vgst;	Dderivs d_argg;	Dderivs d_cdonco,d_tmp,d_xn;	Dderivs d_dbargs,d_dbargd,d_dgddvb;	Dderivs d_dbxwd,d_dbxws;	Dderivs d_dsrgdb, d_dbrgdb;	Dderivs d_gamasd, d_gammad, d_args, d_argd;	Dderivs d_argxs, d_argxd;	Dderivs d_argss, d_argsd;	Dderivs d_xwd, d_xws;	Dderivs d_zero;	Dderivs d_vbin;	Dderivs d_barg;	Dderivs d_sarg;	Dderivs d_phiMinVbs;    Dderivs d_p, d_q, d_r;    Dderivs d_von, d_dummy, d_vgsx, d_arg, d_dumarg;    Dderivs d_ueff, d_beta1, d_clfact, d_xlamda,d_mos2gds;    Dderivs d_vdson, d_cdson, d_expg;    double dsrgdb, dbrgdb, dbxwd, dbxws, dbargs, dbargd;    double dgddvb;/* from now on, p=vgs, q=vbs, r=vds  *//* * 'local' variables - these switch d & s around appropriately * so that we don't have to worry about vds < 0  */	double lvbs = here->MOS2mode==1?vbs:vbd;	double lvds = here->MOS2mode*vds;	double lvgs = here->MOS2mode==1?vgs:vgd;	double phiMinVbs = here->MOS2tPhi - lvbs;	double tmp; /* a temporary variable, not used for more than */		    /* about 10 lines at a time */	int iknt;	int jknt;	int i;	int j;	/*	 *  compute some useful quantities                      */d_p.value = 0.0;d_p.d1_p = 1.0;d_p.d1_q = 0.0;d_p.d1_r = 0.0;d_p.d2_p2 = 0.0;d_p.d2_q2 = 0.0;d_p.d2_r2 = 0.0;d_p.d2_pq = 0.0;d_p.d2_qr = 0.0;d_p.d2_pr = 0.0;d_p.d3_p3 = 0.0;d_p.d3_q3 = 0.0;d_p.d3_r3 = 0.0;d_p.d3_p2r = 0.0;d_p.d3_p2q = 0.0;d_p.d3_q2r = 0.0;d_p.d3_pq2 = 0.0;d_p.d3_pr2 = 0.0;d_p.d3_qr2 = 0.0;d_p.d3_pqr = 0.0;	EqualDeriv(&d_q,&d_p);	EqualDeriv(&d_r,&d_p);	EqualDeriv(&d_zero,&d_p);    d_q.d1_p = d_r.d1_p = d_zero.d1_p = 0.0;    d_q.d1_q = d_r.d1_r = 1.0;	EqualDeriv(&d_phiMinVbs,&d_q);	d_phiMinVbs.value = phiMinVbs;	d_phiMinVbs.d1_q = -  d_phiMinVbs.d1_q;	if (lvbs <= 0.0) {	    sarg = sqrt(phiMinVbs);	    SqrtDeriv(&d_sarg, &d_phiMinVbs);	    dsrgdb = -0.5/sarg;	    InvDeriv(&d_dsrgdb,&d_sarg);	    TimesDeriv(&d_dsrgdb,&d_dsrgdb,-0.5);	} else {	    sphi = sqrt(here->MOS2tPhi); /*const*/	    sphi3 = here->MOS2tPhi*sphi; /*const*/	    sarg = sphi/(1.0+0.5*lvbs/here->MOS2tPhi);	    EqualDeriv(&d_sarg,&d_q); d_sarg.value = lvbs;	    TimesDeriv(&d_sarg,&d_sarg,0.5/here->MOS2tPhi);	    d_sarg.value += 1.0;	    InvDeriv(&d_sarg,&d_sarg);

⌨️ 快捷键说明

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