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

📄 b1eval.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: 1985 Hong J. Park, Thomas L. Quarles**********/#include "spice.h"#include <stdio.h>#include "util.h"#include "cktdefs.h"#include "bsim1def.h"#include "trandefs.h"#include "const.h"#include "suffix.h"/* This routine evaluates the drain current, its derivatives and the * charges associated with the gate,bulk and drain terminal * using the B1 (Berkeley Short-Channel IGFET Model) Equations. */voidB1evaluate(vds,vbs,vgs,here,model,gmPointer,gdsPointer,gmbsPointer,        qgPointer,qbPointer,qdPointer,cggbPointer,cgdbPointer,cgsbPointer,        cbgbPointer,cbdbPointer,cbsbPointer,cdgbPointer,cddbPointer,        cdsbPointer,cdrainPointer,vonPointer,vdsatPointer,ckt)    register CKTcircuit  *ckt;    register B1model   *model;    register B1instance *here;    double vds;    double vbs;    double vgs;    double *gmPointer;    double *gdsPointer;    double *gmbsPointer;    double *qgPointer;    double *qbPointer;    double *qdPointer;    double *cggbPointer;    double *cgdbPointer;    double *cgsbPointer;    double *cbgbPointer;    double *cbdbPointer;    double *cbsbPointer;    double *cdgbPointer;    double *cddbPointer;    double *cdsbPointer;    double *cdrainPointer;    double *vonPointer;    double *vdsatPointer; {    double gm;    double gds;    double gmbs;    double qg;    double qb;    double qd;    double cggb;    double cgdb;    double cgsb;    double cbgb;    double cbdb;    double cbsb;    double cdgb;    double cddb;    double cdsb;    double Vfb;    double Phi;    double K1;    double K2;    double Vdd;    double Ugs;    double Uds;    double dUgsdVbs;    double Leff;    double dUdsdVbs;    double dUdsdVds;    double Eta;    double dEtadVds;    double dEtadVbs;    double Vpb;    double SqrtVpb;    double Von;    double Vth;    double dVthdVbs;    double dVthdVds;    double Vgs_Vth;    double DrainCurrent;    double G;    double A;    double Arg;    double dGdVbs;    double dAdVbs;    double Beta;    double Beta_Vds_0;    double BetaVdd;    double dBetaVdd_dVds;    double Beta0;    double dBeta0dVds;    double dBeta0dVbs;    double VddSquare;    double C1;    double C2;    double dBetaVdd_dVbs;    double dBeta_Vds_0_dVbs;    double dC1dVbs;    double dC2dVbs;    double dBetadVgs;    double dBetadVds;    double dBetadVbs;    double VdsSat;    double Argl1;    double Argl2;    double Vc;    double Term1;    double K;    double Args1;    double dVcdVgs;    double dVcdVds;    double dVcdVbs;    double dKdVc;    double dKdVgs;    double dKdVds;    double dKdVbs;    double Args2;    double Args3;    double Warg1;    double Vcut;    double N;    double N0;    double NB;    double ND;    double Warg2;    double Wds;    double Wgs;    double Ilimit;    double Iexp;    double Temp1;    double Vth0;    double Arg1;    double Arg2;    double Arg3;    double Arg5;    double Ent;    double Vcom;    double Vgb;    double Vgb_Vfb;    double VdsPinchoff;    double EntSquare;    double Vgs_VthSquare;    double Argl3;    double Argl4;    double Argl5;    double Argl6;    double Argl7;    double Argl8;    double Argl9;    double dEntdVds;    double dEntdVbs;    double cgbb;    double cdbb;    double cbbb;    double WLCox;    double Vtsquare;    double Temp3;    int ChargeComputationNeeded;    double co4v15;    if (ckt->CKTmode & (MODEAC | MODETRAN)) {        ChargeComputationNeeded  =  1;    } else if (ckt->CKTmode & MODEINITSMSIG) {        ChargeComputationNeeded  =  1;    } else if ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) {        ChargeComputationNeeded  =  1;    } else {        ChargeComputationNeeded  =  0;    }    Vfb  =  here->B1vfb;    Phi  =  here->B1phi;    K1   =  here->B1K1;    K2   =  here->B1K2;    Vdd  =  model->B1vdd;    if((Ugs  =  here->B1ugs + here->B1ugsB * vbs) <= 0 ) {        Ugs = 0;        dUgsdVbs = 0.0;    } else {        dUgsdVbs  =  here->B1ugsB;    }    if((Uds  =  here->B1uds + here->B1udsB * vbs +             here->B1udsD*(vds-Vdd)) <= 0 ) {            Uds = 0.0;        dUdsdVbs = dUdsdVds = 0.0;    } else {        Leff  =  here->B1l * 1.e6 - model->B1deltaL; /* Leff in um */        Uds  =  Uds / Leff;        dUdsdVbs  =  here->B1udsB / Leff;        dUdsdVds  =  here->B1udsD / Leff;    }    Eta  =  here->B1eta + here->B1etaB * vbs + here->B1etaD *         (vds - Vdd);    if( Eta <= 0 ) {           Eta  = 0;         dEtadVds = dEtadVbs = 0.0 ;    } else if ( Eta > 1 ) {        Eta = 1;        dEtadVds = dEtadVbs = 0;    } else {         dEtadVds  =  here->B1etaD;        dEtadVbs  =  here->B1etaB;    }    if( vbs < 0 ) {        Vpb  =  Phi - vbs;    } else {        Vpb  =  Phi;    }    SqrtVpb  =  sqrt( Vpb );    Von  = Vfb + Phi + K1 * SqrtVpb - K2 * Vpb - Eta * vds;    Vth = Von;    dVthdVds  =  - Eta - dEtadVds * vds;    dVthdVbs  =  K2 - 0.5 * K1 / SqrtVpb - dEtadVbs * vds;    Vgs_Vth  =  vgs - Vth;    G  =  1. - 1./(1.744+0.8364 * Vpb);    A  =  1. + 0.5*G*K1/SqrtVpb;    A = MAX( A, 1.0);   /* Modified */    Arg  = MAX(( 1 + Ugs * Vgs_Vth), 1.0);    dGdVbs  =  -0.8364 * (1-G) * (1-G);    dAdVbs  =  0.25 * K1 / SqrtVpb *(2*dGdVbs + G/Vpb);    if( Vgs_Vth < 0 ) {        /* cutoff */        DrainCurrent  = 0;        gm = 0;        gds = 0;        gmbs = 0;        goto SubthresholdComputation;    }    /* Quadratic Interpolation for Beta0 (Beta at vgs  =  0, vds=Vds) */    Beta_Vds_0  =  (here->B1betaZero + here->B1betaZeroB * vbs);    BetaVdd  =  (here->B1betaVdd + here->B1betaVddB * vbs);    dBetaVdd_dVds  =  MAX( here->B1betaVddD, 0.0); /* Modified */    if( vds > Vdd ) {        Beta0  =  BetaVdd + dBetaVdd_dVds * (vds - Vdd);        dBeta0dVds  =  dBetaVdd_dVds;        dBeta0dVbs  =  here->B1betaVddB;    } else {        VddSquare  =  Vdd * Vdd;        C1  =  ( -BetaVdd + Beta_Vds_0 + dBetaVdd_dVds * Vdd) / VddSquare;        C2  =  2 * (BetaVdd - Beta_Vds_0) / Vdd - dBetaVdd_dVds;        dBeta_Vds_0_dVbs  =  here->B1betaZeroB;        dBetaVdd_dVbs  =  here->B1betaVddB;        dC1dVbs  =  (dBeta_Vds_0_dVbs - dBetaVdd_dVbs) / VddSquare;        dC2dVbs  =  dC1dVbs * (-2) * Vdd;        Beta0  =  (C1 * vds + C2) * vds + Beta_Vds_0;        dBeta0dVds  =  2*C1*vds + C2;        dBeta0dVbs  =  dC1dVbs * vds * vds + dC2dVbs * vds + dBeta_Vds_0_dVbs;    }    /*Beta  =  Beta0 / ( 1 + Ugs * Vgs_Vth );*/    Beta = Beta0 / Arg ;    dBetadVgs  =  - Beta * Ugs / Arg;    dBetadVds  =  dBeta0dVds / Arg - dBetadVgs * dVthdVds ;    dBetadVbs  =  dBeta0dVbs / Arg + Beta * Ugs * dVthdVbs / Arg -         Beta * Vgs_Vth * dUgsdVbs / Arg;    /*VdsSat  = MAX( Vgs_Vth / ( A + Uds * Vgs_Vth ),  0.0);*/    if((Vc  =  Uds * Vgs_Vth / A) < 0.0 ) Vc=0.0;    Term1  =  sqrt( 1 + 2 * Vc );    K  =  0.5 * ( 1 + Vc + Term1 );    VdsSat = MAX( Vgs_Vth / ( A * sqrt(K) ) , 0.0 );    if( vds < VdsSat ) {        /* Triode Region */        /*Argl1  =  1 + Uds * vds;*/        Argl1 = MAX( (1 + Uds * vds), 1.);        Argl2  =  Vgs_Vth - 0.5 * A * vds;        DrainCurrent  =  Beta * Argl2 * vds / Argl1;        gm  =  (dBetadVgs * Argl2 * vds + Beta * vds) / Argl1;        gds  =  (dBetadVds * Argl2 * vds + Beta *             (Vgs_Vth - vds * dVthdVds - A * vds) -             DrainCurrent * (vds * dUdsdVds + Uds )) /  Argl1;        gmbs = (dBetadVbs * Argl2 * vds + Beta * vds *             (- dVthdVbs - 0.5 * vds * dAdVbs ) -             DrainCurrent * vds * dUdsdVbs ) / Argl1;    } else {          /* Pinchoff (Saturation) Region */        Args1  =  1. + 1. / Term1;        dVcdVgs  =  Uds / A;        dVcdVds  =  Vgs_Vth * dUdsdVds / A - dVcdVgs * dVthdVds;        dVcdVbs  =  ( Vgs_Vth * dUdsdVbs - Uds *             (dVthdVbs + Vgs_Vth * dAdVbs / A ))/ A;        dKdVc  =  0.5* Args1;        dKdVgs  =  dKdVc * dVcdVgs;        dKdVds  =  dKdVc * dVcdVds;        dKdVbs  =  dKdVc * dVcdVbs;        Args2  =  Vgs_Vth / A / K;        Args3  =  Args2 * Vgs_Vth;        DrainCurrent  =  0.5 * Beta * Args3;        gm  =  0.5 * Args3 * dBetadVgs + Beta * Args2 -             DrainCurrent * dKdVgs / K;        gds  =  0.5 * Args3 * dBetadVds - Beta * Args2 * dVthdVds -             DrainCurrent * dKdVds / K;        gmbs  =  0.5 * dBetadVbs * Args3 - Beta * Args2 *dVthdVbs -             DrainCurrent * (dAdVbs / A + dKdVbs / K );    }SubthresholdComputation:    N0  =  here->B1subthSlope;

⌨️ 快捷键说明

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