@@ -39,6 +39,8 @@ class MosfetElm extends CircuitElm {
3939 double vt ;
4040 // beta = 1/(RdsON*(Vgs-Vt))
4141 double beta ;
42+ // channel-length modulation parameter (1/V), 0 = ideal
43+ double lambda ;
4244 static int globalFlags ;
4345 Diode diodeB1 , diodeB2 ;
4446 double diodeCurrent1 , diodeCurrent2 , bodyCurrent ;
@@ -67,6 +69,7 @@ public MosfetElm(int xa, int ya, int xb, int yb, int f,
6769 try {
6870 vt = new Double (st .nextToken ()).doubleValue ();
6971 beta = new Double (st .nextToken ()).doubleValue ();
72+ lambda = new Double (st .nextToken ()).doubleValue ();
7073 } catch (Exception e ) {}
7174 globalFlags = flags & (FLAGS_GLOBAL );
7275 allocNodes (); // make sure volts[] has the right number of elements when hasBodyTerminal() is true
@@ -105,7 +108,7 @@ void reset() {
105108 volts [bodyTerminal ] = 0 ;
106109 }
107110 String dump () {
108- return super .dump () + " " + vt + " " + beta ;
111+ return super .dump () + " " + vt + " " + beta + " " + lambda ;
109112 }
110113
111114 void dumpXml (Document doc , Element elem ) {
@@ -415,11 +418,14 @@ void calculate(boolean finished) {
415418 Gds = beta *(vgs -vds -vt );
416419 mode = 1 ;
417420 } else {
418- // saturation; Gds = 0
419- gm = beta *(vgs -vt );
421+ // saturation; Gds from channel-length modulation
422+ double vgs_vt = vgs -vt ;
423+ gm = beta *vgs_vt *(1 +lambda *vds );
424+ ids = .5 *beta *vgs_vt *vgs_vt *(1 +lambda *vds );
425+ Gds = .5 *beta *vgs_vt *vgs_vt *lambda ;
420426 // use very small Gds to avoid nonconvergence
421- Gds = 1e-8 ;
422- ids = .5 * beta *( vgs - vt )*( vgs - vt ) + ( vds -( vgs - vt ))* Gds ;
427+ if ( Gds < 1e-8 )
428+ Gds = 1e-8 ;
423429 mode = 2 ;
424430 }
425431
@@ -457,7 +463,9 @@ void calculate(boolean finished) {
457463 void getFetInfo (String arr [], String n ) {
458464 arr [0 ] = Locale .LS (((pnp == -1 ) ? "p-" : "n-" ) + n );
459465 arr [0 ] += " (Vt=" + getVoltageText (pnp *vt );
460- arr [0 ] += ", \u03b2 =" + beta + ")" ;
466+ arr [0 ] += ", \u03b2 =" + beta ;
467+ if (lambda > 0 ) arr [0 ] += ", \u03bb =" + lambda ;
468+ arr [0 ] += ")" ;
461469 arr [1 ] = ((pnp == 1 ) ? "Ids = " : "Isd = " ) + getCurrentText (ids );
462470 arr [2 ] = "Vgs = " + getVoltageText (volts [0 ]-volts [pnp == -1 ? 2 : 1 ]);
463471 arr [3 ] = ((pnp == 1 ) ? "Vds = " : "Vsd = " ) + getVoltageText (volts [2 ]-volts [1 ]);
@@ -485,27 +493,29 @@ public EditInfo getEditInfo(int n) {
485493 return new EditInfo ("Threshold Voltage" , pnp *vt , .01 , 5 );
486494 if (n == 1 )
487495 return new EditInfo (EditInfo .makeLink ("mosfet-beta.html" , "Beta" ), beta , .01 , 5 );
488- if (n == 2 ) {
496+ if (n == 2 )
497+ return new EditInfo ("Channel-Length Modulation (1/V)" , lambda , 0 , 0 ).setDimensionless ();
498+ if (n == 3 ) {
489499 EditInfo ei = new EditInfo ("" , 0 , -1 , -1 );
490500 ei .checkbox = new Checkbox ("Show Bulk" , showBulk ());
491501 return ei ;
492502 }
493- if (n == 3 ) {
503+ if (n == 4 ) {
494504 EditInfo ei = new EditInfo ("" , 0 , -1 , -1 );
495505 ei .checkbox = new Checkbox ("Swap D/S" , (flags & FLAG_FLIP ) != 0 );
496506 return ei ;
497507 }
498- if (n == 4 && !showBulk ()) {
508+ if (n == 5 && !showBulk ()) {
499509 EditInfo ei = new EditInfo ("" , 0 , -1 , -1 );
500510 ei .checkbox = new Checkbox ("Digital Symbol" , drawDigital ());
501511 return ei ;
502512 }
503- if (n == 4 && showBulk ()) {
513+ if (n == 5 && showBulk ()) {
504514 EditInfo ei = new EditInfo ("" , 0 , -1 , -1 );
505515 ei .checkbox = new Checkbox ("Simulate Body Diode" , (flags & FLAG_BODY_DIODE ) != 0 );
506516 return ei ;
507517 }
508- if (n == 5 && doBodyDiode ()) {
518+ if (n == 6 && doBodyDiode ()) {
509519 EditInfo ei = new EditInfo ("" , 0 , -1 , -1 );
510520 ei .checkbox = new Checkbox ("Body Terminal" , (flags & FLAG_BODY_TERMINAL ) != 0 );
511521 return ei ;
@@ -517,28 +527,30 @@ public void setEditValue(int n, EditInfo ei) {
517527 if (n == 0 )
518528 vt = pnp *ei .value ;
519529 if (n == 1 && ei .value > 0 )
520- beta = lastBeta = ei .value ;
521- if (n == 2 ) {
530+ beta = lastBeta = ei .value ;
531+ if (n == 2 && ei .value >= 0 )
532+ lambda = ei .value ;
533+ if (n == 3 ) {
522534 globalFlags = (!ei .checkbox .getState ()) ? (globalFlags |FLAG_HIDE_BULK ) :
523535 (globalFlags & ~(FLAG_HIDE_BULK |FLAG_DIGITAL ));
524536// setPoints();
525537 ei .newDialog = true ;
526538 }
527- if (n == 3 ) {
539+ if (n == 4 ) {
528540 flags = (ei .checkbox .getState ()) ? (flags | FLAG_FLIP ) :
529541 (flags & ~FLAG_FLIP );
530542// setPoints();
531543 }
532- if (n == 4 && !showBulk ()) {
544+ if (n == 5 && !showBulk ()) {
533545 globalFlags = (ei .checkbox .getState ()) ? (globalFlags |FLAG_DIGITAL ) :
534546 (globalFlags & ~FLAG_DIGITAL );
535547// setPoints();
536548 }
537- if (n == 4 && showBulk ()) {
549+ if (n == 5 && showBulk ()) {
538550 flags = ei .changeFlag (flags , FLAG_BODY_DIODE );
539551 ei .newDialog = true ;
540552 }
541- if (n == 5 ) {
553+ if (n == 6 ) {
542554 flags = ei .changeFlag (flags , FLAG_BODY_TERMINAL );
543555 }
544556
0 commit comments