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

📄 mos2dset.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 4 页
字号:
                    ro = log(ro)/3.0;                    ro = exp(ro);                    /* the above is eqvt. to                    			ro = (s2/4.0 + p0)^1/6; */		    TimesDeriv(&d_ro,&d_s2,0.25);		    PlusDeriv(&d_ro,&d_ro,&d_p0);		    PowDeriv(&d_ro,&d_ro,1.0/6.0);                    fi = atan(-2.0*p2/s);		    DivDeriv(&d_fi,&d_p2,&d_s);		    TimesDeriv(&d_fi,&d_fi,-2.0);		    AtanDeriv(&d_fi,&d_fi);                    y3 = 2.0*ro*cos(fi/3.0)-a/3.0;		    TimesDeriv(&d_dummy,&d_fi,1.0/3.0);		    CosDeriv(&d_dummy,&d_dummy);		    MultDeriv(&d_y3,&d_ro,&d_dummy);		    TimesDeriv(&d_y3,&d_y3,2.0);		    /* mistake! fixed Dec 8 '89		    TimesDeriv(&d_dummy,&d_a,-3.0);		    */		    TimesDeriv(&d_dummy,&d_a,-1/3.0);		    PlusDeriv(&d_y3,&d_y3,&d_dummy);                } else {                    p3 = (-s/2.0+p2);		    TimesDeriv(&d_p3,&d_s,-0.5);		    PlusDeriv(&d_p3,&d_p3,&d_p2);                    p3 = exp(log(FABS(p3))/3.0);		    /* eqvt. to (FABS(p3)) ^ 1/3 */		    if (p3 < 0.0)			TimesDeriv(&d_p3,&d_p3,-1.0);		    PowDeriv(&d_p3,&d_p3,1.0/3.0);                    p4 = (-s/2.0-p2);		    TimesDeriv(&d_p4,&d_s,0.5);		    PlusDeriv(&d_p4,&d_p4,&d_p2);		    if (p4 < 0.0)		    TimesDeriv(&d_p4,&d_p4,-1.0); /* this is FABS(p4) */                    p4 = exp(log(FABS(p4))/3.0);		    PowDeriv(&d_p4,&d_p4,1.0/3.0);                    y3 = p3+p4-a/3.0;		    TimesDeriv(&d_y3,&d_a,-1.0/3.0);		    PlusDeriv(&d_y3,&d_y3,&d_p4);		    PlusDeriv(&d_y3,&d_y3,&d_p3);                }                iknt = 0;                a3 = sqrt(a1*a1/4.0-b1+y3);		MultDeriv(&d_a3,&d_a1,&d_a1);		TimesDeriv(&d_a3,&d_a3,0.25);		PlusDeriv(&d_a3,&d_a3,&d_y3);		TimesDeriv(&d_dummy,&d_b1,-1.0);		PlusDeriv(&d_a3,&d_a3,&d_dummy);		SqrtDeriv(&d_a3,&d_a3);                b3 = sqrt(y3*y3/4.0-d1);		MultDeriv(&d_b3,&d_y3,&d_y3);		TimesDeriv(&d_b3,&d_b3,0.25);		TimesDeriv(&d_dummy,&d_d1,-1.0);		PlusDeriv(&d_b3,&d_b3,&d_dummy);		SqrtDeriv(&d_b3,&d_b3);                for(i = 1;i<=4;i++) {                    a4[i-1] = a1/2.0+sig1[i-1]*a3;		    TimesDeriv(&d_a4[i-1],&d_a1,0.5);		    TimesDeriv(&d_dummy,&d_a3,sig1[i-1]);		    PlusDeriv(&d_a4[i-1],&d_a4[i-1],&d_dummy);                    b4[i-1] = y3/2.0+sig2[i-1]*b3;		    TimesDeriv(&d_b4[i-1],&d_y3,0.5);		    TimesDeriv(&d_dummy,&d_b3,sig2[i-1]);		    PlusDeriv(&d_b4[i-1],&d_b4[i-1],&d_dummy);                    delta4 = a4[i-1]*a4[i-1]/4.0-b4[i-1];		    MultDeriv(&d_delta4,&d_a4[i-1],&d_a4[i-1]);		    TimesDeriv(&d_delta4,&d_delta4,0.25);		    TimesDeriv(&d_dummy,&d_b4[i-1],-1.0);		    PlusDeriv(&d_delta4,&d_delta4,&d_dummy);                    if (delta4 < 0) continue;                    iknt = iknt+1;                    tmp = sqrt(delta4);		    SqrtDeriv(&d_tmp,&d_delta4);                    x4[iknt-1] = -a4[i-1]/2.0+tmp;		    TimesDeriv(&d_x4[iknt-1],&d_a4[i-1],-0.5);		    PlusDeriv(&d_x4[iknt-1],&d_x4[iknt-1],&d_tmp);                    iknt = iknt+1;                    x4[iknt-1] = -a4[i-1]/2.0-tmp;		    TimesDeriv(&d_x4[iknt-1],&d_a4[i-1],-0.5);		    PlusDeriv(&d_x4[iknt-1],&d_x4[iknt-1],&d_tmp);                }                jknt = 0;                for(j = 1;j<=iknt;j++) {                    if (x4[j-1] <= 0) continue;                    /* XXX implement this sanely */                    poly4[j-1] = x4[j-1]*x4[j-1]*x4[j-1]*x4[j-1]+a1*x4[j-1]*                        x4[j-1]*x4[j-1];		    CubeDeriv(&d_dummy,&d_x4[j-1]);		    PlusDeriv(&d_poly4[j-1],&d_x4[j-1],&d_a1);		    MultDeriv(&d_poly4[j-1],&d_poly4[j-1],&d_dummy);                    poly4[j-1] = poly4[j-1]+b1*x4[j-1]*x4[j-1]+c1*x4[j-1]+d1;		    PlusDeriv(&d_poly4[j-1],&d_poly4[j-1],&d_d1);		    MultDeriv(&d_dummy,&d_b1,&d_x4[j-1]);		    PlusDeriv(&d_dummy,&d_dummy,&d_c1);		    MultDeriv(&d_dummy,&d_dummy,&d_x4[j-1]);		    PlusDeriv(&d_poly4[j-1],&d_poly4[j-1],&d_dummy);                    if (FABS(poly4[j-1]) > 1.0e-6) continue;                    jknt = jknt+1;                    if (jknt <= 1) {                        xvalid = x4[j-1];			EqualDeriv(&d_xvalid,&d_x4[j-1]);                    }                    if (x4[j-1] > xvalid) continue;                    xvalid = x4[j-1];		    EqualDeriv(&d_xvalid,&d_x4[j-1]);                }                if (jknt > 0) {                    vdsat = xvalid*xvalid-phiMinVbs;		    MultDeriv(&d_vdsat,&d_xvalid,&d_xvalid);		    TimesDeriv(&d_dummy,&d_phiMinVbs,-1.0);		    PlusDeriv(&d_vdsat,&d_vdsat,&d_dummy);                }            }            /*             *  evaluate effective channel length and its derivatives             */            if (lvds != 0.0) {                gammad = gamasd;		EqualDeriv(&d_gammad,&d_gamasd);                if ((lvbs-vdsat) <= 0) {                    bsarg = sqrt(vdsat+phiMinVbs);		    PlusDeriv(&d_bsarg,&d_vdsat,&d_phiMinVbs);		    SqrtDeriv(&d_bsarg,&d_bsarg);                } else {                    bsarg = sphi/(1.0+0.5*(lvbs-vdsat)/here->MOS2tPhi);		    TimesDeriv(&d_bsarg,&d_vdsat,-1.0);		    d_bsarg.value += lvbs; d_bsarg.d1_r += 1.0;		    TimesDeriv(&d_bsarg,&d_bsarg,0.5/here->MOS2tPhi);		    d_bsarg.value += 1.0;		    InvDeriv(&d_bsarg,&d_bsarg);		    TimesDeriv(&d_bsarg,&d_bsarg,sphi);                }                bodys = bsarg*bsarg*bsarg-sarg3;		CubeDeriv(&d_bodys,&d_bsarg);		TimesDeriv(&d_dummy,&d_sarg3,-1.0);		PlusDeriv(&d_bodys,&d_bodys,&d_dummy);                if (model->MOS2maxDriftVel <= 0) {                    if (model->MOS2substrateDoping == 0.0) goto line610;                    if (xlamda > 0.0) goto line610;                    argv = (lvds-vdsat)/4.0;		    TimesDeriv(&d_argv,&d_vdsat,-1.0);		    d_argv.value += lvds; d_argv.d1_r += 1.0;		    TimesDeriv(&d_argv,&d_argv,0.25);                    sargv = sqrt(1.0+argv*argv);		    MultDeriv(&d_sargv,&d_argv,&d_argv);		    d_sargv.value += 1.0;		    SqrtDeriv(&d_sargv,&d_sargv);                    arg = sqrt(argv+sargv);		    PlusDeriv(&d_arg,&d_sargv,&d_argv);		    SqrtDeriv(&d_arg,&d_arg);                    xlfact = model->MOS2xd/(EffectiveLength*lvds);		    EqualDeriv(&d_xlfact,&d_r); d_xlfact.value = lvds;		    InvDeriv(&d_xlfact,&d_xlfact);		    TimesDeriv(&d_xlfact,&d_xlfact,model->MOS2xd/EffectiveLength);                    xlamda = xlfact*arg;		    MultDeriv(&d_xlamda,&d_xlfact,&d_arg);                } else {                    argv = (vgsx-vbin)/eta-vdsat;		    TimesDeriv(&d_argv,&d_vbin,-1.0);		    PlusDeriv(&d_argv,&d_argv,&d_vgsx);		    TimesDeriv(&d_argv,&d_argv,1/eta);		    TimesDeriv(&d_dummy,&d_vdsat,-1.0);		    PlusDeriv(&d_argv,&d_argv,&d_dummy);                    xdv = model->MOS2xd/sqrt(model->MOS2channelCharge); /*const*/                    xlv = model->MOS2maxDriftVel*xdv/(2.0*ueff);		    InvDeriv(&d_xlv,&d_ueff);		    TimesDeriv(&d_xlv,&d_xlv,model->MOS2maxDriftVel*xdv*0.5);		    /* retained for historical interest                    vqchan = argv-gammad*bsarg;		    MultDeriv(&d_vqchan,&d_gammad,&d_bsarg);		    TimesDeriv(&d_vqchan,&d_vqchan,-1);		    PlusDeriv(&d_vqchan,&d_vqchan,&d_argv);		    */                    /* gammad = gamasd                     vl = model->MOS2maxDriftVel*EffectiveLength;const*/                    if (model->MOS2substrateDoping == 0.0) goto line610;                    if (xlamda > 0.0) goto line610;                    argv = lvds-vdsat;		    TimesDeriv(&d_argv,&d_vdsat,-1.0);		    d_argv.value += lvds;		    d_argv.d1_r += 1.0;		    if (argv < 0.0)			EqualDeriv(&d_argv,&d_zero);                    argv = MAX(argv,0.0);                    xls = sqrt(xlv*xlv+argv);		    MultDeriv(&d_xls,&d_xlv,&d_xlv);		    PlusDeriv(&d_xls,&d_xls,&d_argv);		    SqrtDeriv(&d_xls,&d_xls);                    /* dummy9 = xlv*xlv + argv */                    xlfact = xdv/(EffectiveLength*lvds);		    EqualDeriv(&d_xlfact,&d_r);		    d_xlfact.value += lvds;		    InvDeriv(&d_xlfact,&d_xlfact);		    TimesDeriv(&d_xlfact,&d_xlfact,xdv/EffectiveLength);                    xlamda = xlfact*(xls-xlv);		    TimesDeriv(&d_xlamda,&d_xlv,-1.0);		    PlusDeriv(&d_xlamda,&d_xlamda,&d_xls);		    MultDeriv(&d_xlamda,&d_xlamda,&d_xlfact);                }            }line610:                        /*             *     limit channel shortening at punch-through             */            xwb = model->MOS2xd*sbiarg; /*const*/            xld = EffectiveLength-xwb; /*const*/            clfact = 1.0-xlamda*lvds;	    EqualDeriv(&d_clfact,&d_r); d_clfact.value = lvds;	    d_clfact.d1_r = -1;	    MultDeriv(&d_clfact,&d_clfact,&d_xlamda);	    d_clfact.value += 1.0;            xleff = EffectiveLength*clfact;	    TimesDeriv(&d_xleff,&d_clfact,EffectiveLength);            deltal = xlamda*lvds*EffectiveLength;	    EqualDeriv(&d_delta1,&d_r); 	    d_delta1.value = EffectiveLength*lvds;	    d_delta1.d1_r = EffectiveLength;	    MultDeriv(&d_delta1,&d_delta1,&d_xlamda);            if (model->MOS2substrateDoping == 0.0) xwb = 0.25e-6;            if (xleff < xwb) {                xleff = xwb/(1.0+(deltal-xld)/xwb);		EqualDeriv(&d_xleff,&d_delta1);d_xleff.value -= xld;		TimesDeriv(&d_xleff,&d_xleff,1/xwb);d_xleff.value += 1.0;		InvDeriv(&d_xleff,&d_xleff);		TimesDeriv(&d_xleff,&d_xleff,xwb);                clfact = xleff/EffectiveLength;		TimesDeriv(&d_clfact,&d_xleff,1/EffectiveLength); /*               dfact = xleff*xleff/(xwb*xwb); */            }            /*             *  evaluate effective beta (effective kp)             */            beta1 = Beta*ufact/clfact;	    DivDeriv(&d_beta1,&d_ufact,&d_clfact);	    TimesDeriv(&d_beta1,&d_beta1,Beta);            /*             *  test for mode of operation and branch appropriately             */            gammad = gamasd;	    EqualDeriv(&d_gammad,&d_gamasd);            if (lvds <= 1.0e-10) {                if (lvgs <= von) {                    if ((model->MOS2fastSurfaceStateDensity == 0.0) ||                            (OxideCap == 0.0)) {                        here->MOS2gds = 0.0;                    d_cdrain.d1_q = 0.0;                    d_cdrain.d2_q2 = 0.0;                    d_cdrain.d3_q3 = 0.0;                        goto line1050;                    }                    here->MOS2gds = beta1*(von-vbin-gammad*sarg)*exp(argg*                        (lvgs-von));		    MultDeriv(&d_dummy,&d_gammad,&d_sarg);		    PlusDeriv(&d_dummy,&d_dummy,&d_vbin);		    TimesDeriv(&d_dummy,&d_dummy,-1.0);		    PlusDeriv(&d_dummy,&d_dummy,&d_von);		    MultDeriv(&d_mos2gds,&d_beta1,&d_dummy);		    TimesDeriv(&d_dummy,&d_von,-1.0);		    PlusDeriv(&d_dummy,&d_dummy,&d_p);		    d_dummy.value += lvgs;		    MultDeriv(&d_dummy,&d_dummy,&d_argg);		    ExpDeriv(&d_dummy,&d_dummy);		    MultDeriv(&d_mos2gds,&d_mos2gds,&d_dummy);		    d_cdrain.d1_r = d_mos2gds.value;		    d_cdrain.d2_r2 = d_mos2gds.d1_r;		    d_cdrain.d3_r3 = d_mos2gds.d2_r2;                        /* dummy1 = von - vbin - gamasd*sarg */                    goto line1050;                }                here->MOS2gds = beta1*(lvgs-vbin-gammad*sarg);		MultDeriv(&d_mos2gds,&d_gammad,&d_sarg);		PlusDeriv(&d_mos2gds,&d_mos2gds,&d_vbin);		TimesDeriv(&d_mos2gds,&d_mos2gds,-1.0);		MultDeriv(&d_mos2gds,&d_mos2gds,&d_beta1);		    d_cdrain.d1_r = d_mos2gds.value;		    d_cdrain.d2_r2 = d_mos2gds.d1_r;		    d_cdrain.d3_r3 = d_mos2gds.d2_r2;                goto line1050;            }            if (lvgs > von) goto line900;            /*             *  subthreshold region             */            if (vdsat <= 0) {                here->MOS2gds = 0.0;		    d_cdrain.d1_r = 0.0;		    d_cdrain.d2_r2 = 0.0;		    d_cdrain.d3_r3 = 0.0;                /* if (lvgs > vth) goto doneval; */                goto line1050;            }             vdson = MIN(vdsat,lvds);	    if (vdsat <= lvds) {		EqualDeriv(&d_vdson,&d_vdsat);		} else {		EqualDeriv(&d_vdson,&d_r);		d_vdson.value = lvds;		}            if (lvds > vdsat) {                barg = bsarg;		EqualDeriv(&d_barg,&d_bsarg);                body = bodys;		EqualDeriv(&d_body,&d_bodys);            }            cdson = beta1*((von-vbin-eta*vdson*0.5)*vdson-gammad*body/1.5);	    MultDeriv(&d_dummy,&d_gammad,&d_body);	    TimesDeriv(&d_cdson,&d_dummy,-1/1.5);	    TimesDeriv(&d_dummy,&d_vdson,0.5*eta);	    PlusDeriv(&d_dummy,&d_dummy,&d_vbin);	    TimesDeriv(&d_dummy,&d_dummy,-1.0);	    PlusDeriv(&d_dummy,&d_dummy,&d_von);	    MultDeriv(&d_dummy,&d_dummy,&d_vdson);	    PlusDeriv(&d_dummy,&d_dummy,&d_cdson);	    MultDeriv(&d_cdson,&d_dummy,&d_beta1);            expg = exp(argg*(lvgs-von));	    TimesDeriv(&d_expg,&d_von,-1.0);	    d_expg.value += lvgs;	    d_expg.d1_p += 1.0;	    MultDeriv(&d_expg,&d_expg,&d_argg);	    ExpDeriv(&d_expg,&d_expg);            cdrain = cdson*expg;	    MultDeriv(&d_cdrain,&d_cdson,&d_expg);	    /*            gmw = cdrain*argg;            here->MOS2gm = gmw;            tmp = gmw*(lvgs-von)/xn;	    */            goto doneval;line900:            if (lvds <= vdsat) {                /*                 *  linear region                 */                cdrain = beta1*((lvgs-vbin-eta*lvds/2.0)*lvds-gammad*body/1.5);		MultDeriv(&d_dummy,&d_gammad,&d_body);		TimesDeriv(&d_dummy,&d_dummy,-1/1.5);		EqualDeriv(&d_cdrain,&d_r);		d_cdrain.value = eta*lvds*0.5;		d_cdrain.d1_r = 0.5*eta;

⌨️ 快捷键说明

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