22 qgPointer,qbPointer,qdPointer,cggbPointer,cgdbPointer,cgsbPointer,
23 cbgbPointer,cbdbPointer,cbsbPointer,cdgbPointer,cddbPointer,
24 cdsbPointer,cdrainPointer,vonPointer,vdsatPointer,ckt)
47 double *cdrainPointer;
104 double dBetaVdd_dVbs;
105 double dBeta_Vds_0_dVbs;
150 double Vgs_VthSquare;
166 int ChargeComputationNeeded;
170 ChargeComputationNeeded = 1;
172 ChargeComputationNeeded = 1;
174 ChargeComputationNeeded = 1;
176 ChargeComputationNeeded = 0;
184 if((Ugs = here->B1ugs + here->B1ugsB * vbs) <= 0 ) {
188 dUgsdVbs = here->B1ugsB;
190 if((Uds = here->B1uds + here->B1udsB * vbs +
191 here->B1udsD*(vds-Vdd)) <= 0 ) {
193 dUdsdVbs = dUdsdVds = 0.0;
195 Leff = here->B1l * 1.e6 - model->B1deltaL;
197 dUdsdVbs = here->B1udsB / Leff;
198 dUdsdVds = here->B1udsD / Leff;
200 Eta = here->B1eta + here->B1etaB * vbs + here->B1etaD *
204 dEtadVds = dEtadVbs = 0.0 ;
205 }
else if ( Eta > 1 ) {
207 dEtadVds = dEtadVbs = 0;
209 dEtadVds = here->B1etaD;
210 dEtadVbs = here->B1etaB;
217 SqrtVpb = sqrt( Vpb );
218 Von = Vfb + Phi + K1 * SqrtVpb - K2 * Vpb - Eta * vds;
220 dVthdVds = - Eta - dEtadVds * vds;
221 dVthdVbs = K2 - 0.5 * K1 / SqrtVpb - dEtadVbs * vds;
224 G = 1. - 1./(1.744+0.8364 * Vpb);
225 A = 1. + 0.5*G*K1/SqrtVpb;
227 Arg =
MAX(( 1 + Ugs * Vgs_Vth), 1.0);
228 dGdVbs = -0.8364 * (1-
G) * (1-G);
229 dAdVbs = 0.25 * K1 / SqrtVpb *(2*dGdVbs + G/Vpb);
237 goto SubthresholdComputation;
242 Beta_Vds_0 = (here->B1betaZero + here->B1betaZeroB * vbs);
243 BetaVdd = (here->B1betaVdd + here->B1betaVddB * vbs);
244 dBetaVdd_dVds =
MAX( here->B1betaVddD, 0.0);
246 Beta0 = BetaVdd + dBetaVdd_dVds * (vds - Vdd);
247 dBeta0dVds = dBetaVdd_dVds;
248 dBeta0dVbs = here->B1betaVddB;
250 VddSquare = Vdd * Vdd;
251 C1 = ( -BetaVdd + Beta_Vds_0 + dBetaVdd_dVds * Vdd) / VddSquare;
252 C2 = 2 * (BetaVdd - Beta_Vds_0) / Vdd - dBetaVdd_dVds;
253 dBeta_Vds_0_dVbs = here->B1betaZeroB;
254 dBetaVdd_dVbs = here->B1betaVddB;
255 dC1dVbs = (dBeta_Vds_0_dVbs - dBetaVdd_dVbs) / VddSquare;
256 dC2dVbs = dC1dVbs * (-2) * Vdd;
257 Beta0 = (C1 * vds + C2) * vds + Beta_Vds_0;
258 dBeta0dVds = 2*C1*vds + C2;
259 dBeta0dVbs = dC1dVbs * vds * vds + dC2dVbs * vds + dBeta_Vds_0_dVbs;
265 dBetadVgs = - Beta * Ugs / Arg;
266 dBetadVds = dBeta0dVds / Arg - dBetadVgs * dVthdVds ;
267 dBetadVbs = dBeta0dVbs / Arg + Beta * Ugs * dVthdVbs / Arg -
268 Beta * Vgs_Vth * dUgsdVbs / Arg;
272 if((Vc = Uds * Vgs_Vth / A) < 0.0 ) Vc=0.0;
273 Term1 = sqrt( 1 + 2 * Vc );
274 K = 0.5 * ( 1 + Vc + Term1 );
275 VdsSat =
MAX( Vgs_Vth / ( A * sqrt(K) ) , 0.0 );
280 Argl1 =
MAX( (1 + Uds * vds), 1.);
281 Argl2 = Vgs_Vth - 0.5 * A * vds;
282 DrainCurrent = Beta * Argl2 * vds / Argl1;
283 gm = (dBetadVgs * Argl2 * vds + Beta * vds) / Argl1;
284 gds = (dBetadVds * Argl2 * vds + Beta *
285 (Vgs_Vth - vds * dVthdVds - A * vds) -
286 DrainCurrent * (vds * dUdsdVds + Uds )) / Argl1;
287 gmbs = (dBetadVbs * Argl2 * vds + Beta * vds *
288 (- dVthdVbs - 0.5 * vds * dAdVbs ) -
289 DrainCurrent * vds * dUdsdVbs ) / Argl1;
292 Args1 = 1. + 1. / Term1;
294 dVcdVds = Vgs_Vth * dUdsdVds / A - dVcdVgs * dVthdVds;
295 dVcdVbs = ( Vgs_Vth * dUdsdVbs - Uds *
296 (dVthdVbs + Vgs_Vth * dAdVbs / A ))/ A;
298 dKdVgs = dKdVc * dVcdVgs;
299 dKdVds = dKdVc * dVcdVds;
300 dKdVbs = dKdVc * dVcdVbs;
301 Args2 = Vgs_Vth / A / K;
302 Args3 = Args2 * Vgs_Vth;
303 DrainCurrent = 0.5 * Beta * Args3;
304 gm = 0.5 * Args3 * dBetadVgs + Beta * Args2 -
305 DrainCurrent * dKdVgs / K;
306 gds = 0.5 * Args3 * dBetadVds - Beta * Args2 * dVthdVds -
307 DrainCurrent * dKdVds / K;
308 gmbs = 0.5 * dBetadVbs * Args3 - Beta * Args2 *dVthdVbs -
309 DrainCurrent * (dAdVbs / A + dKdVbs / K );
312 SubthresholdComputation:
314 N0 = here->B1subthSlope;
326 goto ChargeComputation;
329 NB = here->B1subthSlopeB;
330 ND = here->B1subthSlopeD;
331 N = N0 + NB * vbs + ND * vds;
332 if( N < 0.5 ) N = 0.5;
333 Warg1 = exp( - vds / CONSTvt0 );
335 Wgs = exp( Vgs_Vth / ( N * CONSTvt0 ));
337 Warg2 = 6.04965 * Vtsquare * here->B1betaZero;
338 Ilimit = 4.5 * Vtsquare * here->B1betaZero;
339 Iexp = Warg2 * Wgs * Wds;
340 DrainCurrent = DrainCurrent + Ilimit * Iexp / ( Ilimit + Iexp );
341 Temp1 = Ilimit / ( Ilimit + Iexp );
342 Temp1 = Temp1 * Temp1;
343 Temp3 = Ilimit / ( Ilimit + Wgs * Warg2 );
344 Temp3=Temp3 * Temp3 * Warg2 * Wgs;
346 gm = gm + Temp1 * Iexp / ( N *
CONSTvt0 );
348 gds = gds + Temp3 * ( -Wds / N / CONSTvt0 * (dVthdVds +
349 Vgs_Vth * ND / N ) + Warg1 / CONSTvt0 );
350 gmbs = gmbs - Temp1 * Iexp * (dVthdVbs + Vgs_Vth * NB / N ) /
356 if(DrainCurrent < 0.0) DrainCurrent = 0.0;
357 if(gm < 0.0) gm = 0.0;
358 if(gds < 0.0) gds = 0.0;
359 if(gmbs < 0.0) gmbs = 0.0;
361 WLCox = model->B1Cox *
362 (here->B1l - model->B1deltaL * 1.e-6) *
363 (here->B1w - model->B1deltaW * 1.e-6) * 1.e4;
365 if( ! ChargeComputationNeeded ) {
380 G = 1. - 1./(1.744+0.8364 * Vpb);
381 A = 1. + 0.5*G*K1/SqrtVpb;
384 dGdVbs = -0.8364 * (1-
G) * (1-G);
385 dAdVbs = 0.25 * K1 / SqrtVpb *(2*dGdVbs + G/Vpb);
386 Phi =
MAX( 0.1, Phi);
388 if( model->B1channelChargePartitionFlag >= 1 ) {
391 Vth0 = Vfb + Phi + K1 * SqrtVpb;
392 Vgs_Vth = vgs - Vth0;
394 Arg2 = Vgs_Vth - 0.5 * Arg1;
397 dVthdVbs = - 0.5 * K1 / SqrtVpb;
398 dAdVbs = 0.5 * K1 * (0.5 * G / Vpb - 0.8364 * (1 -
G) * (1 - G) ) /
400 Ent =
MAX(Arg2,1.0
e-8);
401 dEntdVds = - 0.5 * A;
402 dEntdVbs = - dVthdVbs - 0.5 * vds * dAdVbs;
403 Vcom = Vgs_Vth * Vgs_Vth / 6.0 - 1.25e-1 * Arg1 *
404 Vgs_Vth + 2.5e-2 * Arg5;
405 VdsPinchoff =
MAX( Vgs_Vth / A, 0.0);
411 qg = WLCox * Vgb_Vfb;
424 }
else if ( vgs < Vth0 ){
426 qg = 0.5 * WLCox * K1 * K1 * (-1 +
427 sqrt(1 + 4 * Vgb_Vfb / (K1 * K1)));
430 cggb = WLCox / sqrt(1 + 4 * Vgb_Vfb / (K1 * K1));
433 cbdb = cbsb = cdgb = cddb = cdsb = 0.0;
435 }
else if( vds < VdsPinchoff ){
437 EntSquare = Ent * Ent;
438 Argl1 = 1.2e1 * EntSquare;
449 Argl7 = Argl5 / 1.2e1;
451 Argl9 = 0.125 * Argl5 * Argl5;
452 qg = WLCox * (vgs - Vfb - Phi - 0.5 * vds + vds * Argl7);
453 qb = WLCox * ( - Vth0 + Vfb + Phi + 0.5 * Arg3 - Arg3 * Argl7);
454 qd = - WLCox * (0.5 * Vgs_Vth - 0.75 * Arg1 +
455 0.125 * Arg1 * Argl5);
456 cggb = WLCox * (1.0 - Argl3 / Argl1);
457 cgdb = WLCox * ( - 0.5 + Arg1 / Argl8 - Argl3 * dEntdVds /
459 cgbb = WLCox * (vds * vds * dAdVbs * Ent - Argl3 * dEntdVbs) /
461 cgsb = - (cggb + cgdb + cgbb);
462 cbgb = WLCox * Argl3 * Argl2 / Argl1;
463 cbdb = WLCox * Argl2 * (0.5 - Arg1 / Argl8 + Argl3 * dEntdVds /
465 cbbb = - WLCox * (dVthdVbs + 0.5 * vds * dAdVbs + vds *
466 vds * ((1.0 - 2.0 * A) * dAdVbs * Ent - Argl2 *
467 A * dEntdVbs) / Argl1);
468 cbsb = - (cbgb + cbdb + cbbb);
469 cdgb = - WLCox * (0.5 - Argl9);
470 cddb = WLCox * (0.75 * A - 0.25 * A * Arg1 / Ent +
472 cdbb = WLCox * (0.5 * dVthdVbs + vds * dAdVbs *
473 (0.75 - 0.25 * Argl5 ) + Argl9 * dEntdVbs);
474 cdsb = - (cdgb + cddb + cdbb);
476 }
else if( vds >= VdsPinchoff ) {
477 Args1 = 1.0 / (3.0 * A);
478 qg = WLCox * (vgs - Vfb - Phi - Vgs_Vth * Args1);
479 qb = WLCox * (Vfb + Phi - Vth0 + (1.0 - A) * Vgs_Vth * Args1);
481 cggb = WLCox * (1.0 - Args1);
483 cgbb = WLCox * Args1 * (dVthdVbs + Vgs_Vth * dAdVbs / A);
484 cgsb = - (cggb + cgdb + cgbb);
485 cbgb = WLCox * (Args1 - 1.0 / 3.0);
487 cbbb = - WLCox * ((2.0 / 3.0 + Args1) * dVthdVbs +
488 Vgs_Vth * Args1 * dAdVbs / A);
489 cbsb = - (cbgb + cbdb + cbbb);
503 Vth0 = Vfb+Phi+K1*SqrtVpb;
506 Arg2 = Vgs_Vth-0.5*Arg1;
509 dVthdVbs = -0.5*K1/SqrtVpb;
510 dAdVbs = 0.5*K1*(0.5*G/Vpb-0.8364*(1-
G)*(1-G))/SqrtVpb;
511 Ent =
MAX(Arg2,1.0
e-8);
513 dEntdVbs = -dVthdVbs-0.5*vds*dAdVbs;
514 Vcom = Vgs_Vth*Vgs_Vth/6.0-1.25e-1*Arg1*Vgs_Vth+2.5e-2*Arg5;
515 VdsPinchoff =
MAX( Vgs_Vth/A, 0.0);
520 qg = WLCox * Vgb_Vfb;
533 }
else if ( vgs < Vth0 ) {
534 qg = 0.5 * WLCox * K1 * K1 * (-1+sqrt(1+4*Vgb_Vfb/(K1*K1)));
537 cggb = WLCox/sqrt(1+4*Vgb_Vfb/(K1*K1));
540 cbdb = cbsb = cdgb = cddb = cdsb = 0.0;
542 }
else if ( vds < VdsPinchoff ) {
544 Vgs_VthSquare = Vgs_Vth*Vgs_Vth;
546 Argl1 = 1.2e1*EntSquare;
549 Argl4 = Vcom/Ent/EntSquare;
552 Argl6 = Vcom/EntSquare;
559 qg = WLCox*(vgs-Vfb-Phi-0.5*vds+vds*Argl7);
560 qb = WLCox*(-Vth0+Vfb+Phi+0.5*Arg3-Arg3*Argl7);
561 qd = -WLCox*(0.5*(Vgs_Vth-Arg1)+Arg1*Argl6);
562 cggb = WLCox*(1.0-Argl3/Argl1);
563 cgdb = WLCox*(-0.5+Arg1/Argl8-Argl3*dEntdVds/Argl1);
564 cgbb = WLCox*(vds*vds*dAdVbs*Ent-Argl3*dEntdVbs)/Argl1;
565 cgsb = -(cggb+cgdb+cgbb);
566 cbgb = WLCox*Argl3*Argl2/Argl1;
567 cbdb = WLCox*Argl2*(0.5-Arg1/Argl8+Argl3*dEntdVds/Argl1);
568 cbbb = -WLCox*(dVthdVbs+0.5*vds*dAdVbs+vds*vds*((1.0-2.0*A)
569 *dAdVbs*Ent-Argl2*A*dEntdVbs)/Argl1);
570 cbsb = -(cbgb+cbdb+cbbb);
571 cdgb = -WLCox*(0.5+Arg1*(4.0*Vgs_Vth-1.5*Arg1)/Argl1-
573 cddb = WLCox*(0.5*A+2.0*Arg1*dEntdVds*Argl4-A*(2.0*Vgs_VthSquare
574 -3.0*Arg1*Vgs_Vth+0.9*Arg5)/Argl1);
575 cdbb = WLCox*(0.5*dVthdVbs+0.5*vds*dAdVbs+2.0*Arg1*dEntdVbs
576 *Argl4-vds*(2.0*Vgs_VthSquare*dAdVbs-4.0*A*Vgs_Vth*dVthdVbs-3.0
577 *Arg1*Vgs_Vth*dAdVbs+1.5*A*Arg1*dVthdVbs+0.9*Arg5*dAdVbs)
579 cdsb = -(cdgb+cddb+cdbb);
581 }
else if( vds >= VdsPinchoff ) {
584 qg = WLCox*(vgs-Vfb-Phi-Vgs_Vth*Args1);
585 qb = WLCox*(Vfb+Phi-Vth0+(1.0-A)*Vgs_Vth*Args1);
586 qd = -co4v15*WLCox*Vgs_Vth;
587 cggb = WLCox*(1.0-Args1);
589 cgbb = WLCox*Args1*(dVthdVbs+Vgs_Vth*dAdVbs/A);
590 cgsb = -(cggb+cgdb+cgbb);
591 cbgb = WLCox*(Args1-1.0/3.0);
593 cbbb = -WLCox*((2.0/3.0+Args1)*dVthdVbs+Vgs_Vth*Args1*dAdVbs/A);
594 cbsb = -(cbgb+cbdb+cbbb);
595 cdgb = -co4v15*WLCox;
597 cdbb = co4v15*WLCox*dVthdVbs;
598 cdsb = -(cdgb+cddb+cdbb);
605 *gmPointer =
MAX(gm,0.0);
606 *gdsPointer =
MAX( gds, 0.0);
607 *gmbsPointer =
MAX(gmbs,0.0);
620 *cdrainPointer =
MAX(DrainCurrent,0.0);
622 *vdsatPointer = VdsSat;
void B1evaluate(double vds, double vbs, double vgs, B1instance *here, B1model *model, 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, CKTcircuit *ckt)